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

125 lines
3.6 KiB
Go

package camel_oil
import (
"context"
"kami/internal/consts"
"kami/internal/dao"
"kami/utility/config"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/os/glog"
)
// ====================================================================================
// 可用订单容量管理相关方法
// ====================================================================================
// GetAvailableOrderCapacity 获取当前可用订单容量
// 计算所有在线账号的剩余可下单数之和
func (s *sCamelOil) GetAvailableOrderCapacity(ctx context.Context) (capacity int, err error) {
m := dao.V1CamelOilAccount.Ctx(ctx).DB(config.GetDatabaseV1())
// 查询所有在线账号
type CapacityResult struct {
TotalCapacity int `json:"total_capacity"`
}
var result CapacityResult
err = m.Where(dao.V1CamelOilAccount.Columns().Status, consts.CamelOilAccountStatusOnline).
Fields("SUM(10 - " + dao.V1CamelOilAccount.Columns().DailyOrderCount + ") as total_capacity").
Scan(&result)
if err != nil {
return 0, gerror.Wrap(err, "查询可用订单容量失败")
}
return result.TotalCapacity, nil
}
// CheckAndTriggerAccountLogin 检查容量并触发账号登录
// 如果可用订单容量<50,触发账号登录任务
func (s *sCamelOil) CheckAndTriggerAccountLogin(ctx context.Context) (err error) {
// 1. 获取当前可用容量
capacity, err := s.GetAvailableOrderCapacity(ctx)
if err != nil {
glog.Error(ctx, "获取可用订单容量失败", err)
return err
}
glog.Info(ctx, "当前可用订单容量", capacity)
// 2. 如果容量充足,无需登录
if capacity >= 50 {
return nil
}
// 3. 计算需要登录的账号数量
needCount := (50 - capacity + 9) / 10 // 向上取整
glog.Info(ctx, "可用订单容量不足,需要登录账号", needCount)
// 4. 触发账号登录任务
// 这里会在cron任务中调用LoginAccount方法
// 暂时只记录日志,具体登录逻辑在account_login.go中实现
if _, err = s.BatchLoginAccounts(ctx, needCount); err != nil {
glog.Error(ctx, "批量登录失败", err)
}
return nil
}
// GetAccountPoolStatus 获取账号池状态统计
func (s *sCamelOil) GetAccountPoolStatus(ctx context.Context) (status map[string]interface{}, err error) {
m := dao.V1CamelOilAccount.Ctx(ctx).DB(config.GetDatabaseV1())
// 统计各状态账号数量
type StatusCount struct {
Status int `json:"status"`
Count int `json:"count"`
}
var statusCounts []StatusCount
err = m.Fields(dao.V1CamelOilAccount.Columns().Status + ", COUNT(*) as count").
Group(dao.V1CamelOilAccount.Columns().Status).
Scan(&statusCounts)
if err != nil {
return nil, gerror.Wrap(err, "统计账号状态失败")
}
// 构建结果
result := map[string]interface{}{
"pending": 0, // 待登录
"logging_in": 0, // 登录中
"online": 0, // 在线
"paused": 0, // 已暂停
"invalid": 0, // 已失效
"total": 0, // 总数
}
for _, sc := range statusCounts {
switch sc.Status {
case int(consts.CamelOilAccountStatusPending):
result["pending"] = sc.Count
case int(consts.CamelOilAccountStatusSendCode):
result["logging_in"] = sc.Count
case int(consts.CamelOilAccountStatusOnline):
result["online"] = sc.Count
case int(consts.CamelOilAccountStatusPaused):
result["paused"] = sc.Count
case int(consts.CamelOilAccountStatusInvalid):
result["invalid"] = sc.Count
}
result["total"] = result["total"].(int) + sc.Count
}
// 获取可用订单容量
capacity, err := s.GetAvailableOrderCapacity(ctx)
if err != nil {
glog.Error(ctx, "获取可用订单容量失败", err)
} else {
result["available_capacity"] = capacity
}
return result, nil
}