- 实现账号增删改查接口和逻辑 - 支持账号状态更新及状态历史记录功能 - 提供账号列表、历史和统计信息查询API - 实现账号轮询机制,支持按使用时间轮询获取账号 - 增加账号登录流程及批量登录功能,集成接码平台和平台API - 管理账号订单容量,支持容量检查与账号登录触发 - 提供账号池状态统计接口 - 账号历史记录查询支持多种变更类型文本展示 - 密码等敏感信息采用脱敏展示 - 完善日志记录和错误处理机制,保证业务稳定运行
206 lines
8.0 KiB
Go
206 lines
8.0 KiB
Go
package card_apple_order
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
"github.com/duke-git/lancet/v2/slice"
|
||
"github.com/gogf/gf/v2/database/gdb"
|
||
"github.com/gogf/gf/v2/errors/gcode"
|
||
"github.com/gogf/gf/v2/os/glog"
|
||
"github.com/shopspring/decimal"
|
||
"kami/internal/consts"
|
||
"kami/internal/errHandler"
|
||
"kami/internal/model"
|
||
"kami/internal/model/entity"
|
||
"kami/internal/service"
|
||
"kami/utility/cache"
|
||
"kami/utility/config"
|
||
"kami/utility/integration/apple"
|
||
"kami/utility/pool"
|
||
"time"
|
||
)
|
||
|
||
// HandleRedeemResult 处理核销结果,根据不同的状态进行相应的业务操作
|
||
func (h *sAppleOrder) handleRedeemResult(ctx context.Context, orderEntity *entity.V1CardAppleRechargeInfo, accountInfo *entity.V1CardAppleAccountInfo) error {
|
||
// 调用 Apple 服务进行核销(同步等待)
|
||
redeemClient := apple.NewClient()
|
||
// 准备推送请求
|
||
redeemReq := &apple.RedeemReq{
|
||
Account: accountInfo.Account,
|
||
Password: accountInfo.Password,
|
||
OrderId: orderEntity.OrderNo,
|
||
RedemptionCode: orderEntity.CardPass,
|
||
}
|
||
_, _ = redeemClient.Redeem(ctx, redeemReq)
|
||
return nil
|
||
}
|
||
|
||
// handleRedeemSuccess 处理核销成功的情况
|
||
func (h *sAppleOrder) handleRedeemSuccess(ctx context.Context, orderEntity *entity.V1CardAppleRechargeInfo, accountInfo *entity.V1CardAppleAccountInfo, balanceBefore, balanceAfter float64) error {
|
||
// 将返回的金额字符串转换为 float64(假数据处理)
|
||
actualAmount := orderEntity.CardAmount // 使用卡密面额作为默认金额
|
||
|
||
// 判断金额是否一致
|
||
var orderStatus consts.AppleRechargeOrderStatus
|
||
var historyOperation consts.AppleOrderOperation
|
||
var remark string
|
||
|
||
if actualAmount == orderEntity.CardAmount {
|
||
orderStatus = consts.AppleRechargeOrderSuccess
|
||
historyOperation = consts.AppleRechargeOperationItunesSucceed
|
||
} else {
|
||
orderStatus = consts.AppleRechargeOrderAmountDifferent
|
||
historyOperation = consts.AppleRechargeOperationItunesSucceedButWrongAmount
|
||
remark = "金额异议"
|
||
}
|
||
|
||
// 更新订单和账户余额
|
||
err := h.UpdateActualAmountAndHistoryAndWallet(ctx, &model.AppleAccountUpdateAmountAndHistoryRecord{
|
||
OrderInfo: &model.AppleAccountUpdateAmountRecord{
|
||
OrderNo: orderEntity.OrderNo,
|
||
Amount: actualAmount,
|
||
Status: orderStatus,
|
||
Remark: fmt.Sprintf("卡密:%s,面额:%.2f,实际充值:%.2f,充值账户:%s,%s", orderEntity.CardPass, orderEntity.CardAmount, actualAmount, accountInfo.Account, remark),
|
||
},
|
||
AccountId: accountInfo.Id,
|
||
HistoryRemark: remark,
|
||
HistoryOperation: historyOperation,
|
||
BalanceFromItunes: balanceAfter,
|
||
})
|
||
|
||
if err != nil {
|
||
glog.Error(ctx, fmt.Sprintf("更新订单成功记录失败 - 订单号: %s, 错误: %v", orderEntity.OrderNo, err))
|
||
return err
|
||
}
|
||
|
||
// 异步回调上游
|
||
_ = h.CallBackOrderToUpstream(ctx, orderEntity.OrderNo)
|
||
|
||
glog.Info(ctx, fmt.Sprintf("订单核销成功处理完毕 - 订单号: %s", orderEntity.OrderNo))
|
||
return nil
|
||
}
|
||
|
||
// handleRedeemFailed 处理核销失败的情况
|
||
func (h *sAppleOrder) handleRedeemFailed(ctx context.Context, orderEntity *entity.V1CardAppleRechargeInfo, accountInfo *entity.V1CardAppleAccountInfo, errMsg string) error {
|
||
// 订单退回待处理状态
|
||
err := h.ModifyOrderStatus(ctx, orderEntity.OrderNo, consts.AppleRechargeOrderWaiting, fmt.Sprintf("核销失败:%s", errMsg), nil)
|
||
if err != nil {
|
||
glog.Error(ctx, fmt.Sprintf("更新订单失败状态失败 - 订单号: %s, 错误: %v", orderEntity.OrderNo, err))
|
||
return err
|
||
}
|
||
|
||
// 减少分配计数
|
||
_ = h.DecrementDistributionCount(ctx, orderEntity.OrderNo)
|
||
|
||
// 添加历史记录
|
||
_ = h.AddHistory(ctx, &model.AppleCardRechargeHistoryInput{
|
||
AccountID: accountInfo.Id,
|
||
OrderNo: orderEntity.OrderNo,
|
||
RechargeId: int(orderEntity.Id),
|
||
AccountName: accountInfo.Account,
|
||
Operation: consts.AppleRechargeOperationItunesFail,
|
||
Remark: fmt.Sprintf("核销失败:%s", errMsg),
|
||
}, nil)
|
||
|
||
glog.Info(ctx, fmt.Sprintf("订单核销失败,已退回待处理 - 订单号: %s", orderEntity.OrderNo))
|
||
return nil
|
||
}
|
||
|
||
// handleAccountInvalid 处理账号失效的情况
|
||
func (h *sAppleOrder) handleAccountInvalid(ctx context.Context, orderEntity *entity.V1CardAppleRechargeInfo, accountInfo *entity.V1CardAppleAccountInfo, errMsg string) error {
|
||
// 标记当前账号为失效(密码错误或被禁用)
|
||
_ = service.AppleAccount().ModifyStatus(ctx, accountInfo.Id, consts.AppleAccountWrongPassword, nil)
|
||
|
||
// 订单重新设为待调度状态
|
||
err := h.ModifyOrderStatus(ctx, orderEntity.OrderNo, consts.AppleRechargeOrderWaiting, "账号失效,待重新分配", nil)
|
||
if err != nil {
|
||
glog.Error(ctx, fmt.Sprintf("更新订单待处理状态失败 - 订单号: %s, 错误: %v", orderEntity.OrderNo, err))
|
||
return err
|
||
}
|
||
|
||
// 减少分配计数,允许重新分配
|
||
_ = h.DecrementDistributionCount(ctx, orderEntity.OrderNo)
|
||
|
||
// 添加历史记录
|
||
_ = h.AddHistory(ctx, &model.AppleCardRechargeHistoryInput{
|
||
AccountID: accountInfo.Id,
|
||
OrderNo: orderEntity.OrderNo,
|
||
RechargeId: int(orderEntity.Id),
|
||
AccountName: accountInfo.Account,
|
||
Operation: consts.AppleRechargeOperationWrongPassword,
|
||
Remark: fmt.Sprintf("账号失效:%s", errMsg),
|
||
}, nil)
|
||
|
||
glog.Info(ctx, fmt.Sprintf("账号失效,订单已退回待重新分配 - 订单号: %s, 账号: %s", orderEntity.OrderNo, accountInfo.Account))
|
||
return nil
|
||
}
|
||
|
||
// ProcessOrderWithPush 处理订单:根据订单类型判断是立即进行核销处理还是创建定时任务异步处理
|
||
// 参数说明:
|
||
// - orderEntity: 待处理的订单信息
|
||
// - accountInfo: 分配的苹果账号信息
|
||
// - immediate: 是否立即处理(true: 立即核销,false: 异步定时处理)
|
||
func (h *sAppleOrder) ProcessOrderWithPush(ctx context.Context) (err error) {
|
||
orderEntities, _ := h.GetAccordingOrders(ctx)
|
||
if len(orderEntities) == 0 {
|
||
return
|
||
}
|
||
poolClient := pool.New("apple_order_process_push_pool", 1)
|
||
for _, orderInfo := range orderEntities {
|
||
_ = poolClient.Add(ctx, func(ctx context.Context) {
|
||
err = h.processOrderWithAccount(ctx, orderInfo)
|
||
if err != nil {
|
||
glog.Error(ctx, "处理订单失败", err)
|
||
}
|
||
})
|
||
}
|
||
return
|
||
}
|
||
|
||
func (h *sAppleOrder) processOrderWithAccount(ctx context.Context, orderInfo *entity.V1CardAppleRechargeInfo) (err error) {
|
||
keys := cache.NewCache().GetPrefixKey(ctx, cache.PrefixAppleAccount)
|
||
keysStr := slice.Map(slice.Filter(keys, func(index int, item interface{}) bool {
|
||
_, ok := item.(string)
|
||
return ok
|
||
}), func(index int, item interface{}) string {
|
||
return item.(string)
|
||
})
|
||
accountInfo, err := service.AppleAccount().GetAccordingAccount(ctx, decimal.NewFromFloat(orderInfo.Balance), keysStr)
|
||
if err != nil {
|
||
glog.Error(ctx, "获取订单账户失败", err)
|
||
return
|
||
}
|
||
cacheVar, err := cache.NewCache().Get(ctx, cache.PrefixAppleAccount.Key(accountInfo.Id))
|
||
if err == nil && !cacheVar.IsNil() {
|
||
glog.Warning(ctx, "账户正在处理中", accountInfo.Account)
|
||
}
|
||
_ = cache.NewCache().Set(ctx, cache.PrefixAppleAccount.Key(accountInfo.Id), 1, time.Minute*3)
|
||
defer func() {
|
||
_, _ = cache.NewCache().Remove(ctx, cache.PrefixAppleAccount.Key(accountInfo.Id))
|
||
}()
|
||
if err = h.DistributionAccordingAccount(ctx, accountInfo, orderInfo); err != nil {
|
||
err = errHandler.WrapError(ctx, gcode.CodeInternalError, err, "分配订单账户失败")
|
||
return
|
||
}
|
||
err = config.GetDatabaseV1().Transaction(ctx, func(ctx2 context.Context, tx gdb.TX) error {
|
||
err = service.AppleOrder().ModifyOrderStatus(ctx2, orderInfo.OrderNo, consts.AppleRechargeOrderProcessing, "", tx)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
err = service.AppleOrder().AddHistory(ctx2, &model.AppleCardRechargeHistoryInput{
|
||
AccountID: accountInfo.Id,
|
||
OrderNo: orderInfo.OrderNo,
|
||
RechargeId: int(orderInfo.Id),
|
||
AccountName: accountInfo.Account,
|
||
Operation: consts.AppleRechargeOperationStartRechargeByItunes,
|
||
Remark: fmt.Sprintf("分配账户:%s,账户余额:%.2f", accountInfo.Account, accountInfo.BalanceItunes),
|
||
}, tx)
|
||
return err
|
||
})
|
||
if err != nil {
|
||
glog.Error(ctx, "修改订单状态失败", err)
|
||
}
|
||
_ = h.handleRedeemResult(ctx, orderInfo, accountInfo)
|
||
return
|
||
}
|