- 实现账号增删改查接口和逻辑 - 支持账号状态更新及状态历史记录功能 - 提供账号列表、历史和统计信息查询API - 实现账号轮询机制,支持按使用时间轮询获取账号 - 增加账号登录流程及批量登录功能,集成接码平台和平台API - 管理账号订单容量,支持容量检查与账号登录触发 - 提供账号池状态统计接口 - 账号历史记录查询支持多种变更类型文本展示 - 密码等敏感信息采用脱敏展示 - 完善日志记录和错误处理机制,保证业务稳定运行
377 lines
14 KiB
Go
377 lines
14 KiB
Go
package card_apple_order
|
|
|
|
import (
|
|
"context"
|
|
"github.com/gogf/gf/v2/os/gmlock"
|
|
"kami/api/commonApi"
|
|
"kami/internal/consts"
|
|
"kami/internal/dao"
|
|
"kami/internal/errHandler"
|
|
"kami/internal/model"
|
|
"kami/internal/model/do"
|
|
"kami/internal/model/entity"
|
|
"kami/internal/service"
|
|
"kami/utility/config"
|
|
"kami/utility/utils"
|
|
"slices"
|
|
|
|
"github.com/gogf/gf/v2/database/gdb"
|
|
"github.com/gogf/gf/v2/errors/gcode"
|
|
"github.com/gogf/gf/v2/errors/gerror"
|
|
"github.com/gogf/gf/v2/frame/g"
|
|
"github.com/gogf/gf/v2/os/gtime"
|
|
)
|
|
|
|
// List 获取充值列表
|
|
func (h *sAppleOrder) List(ctx context.Context, input model.AppleCardRechargeParamsInput) (total int, data []entity.V1CardAppleRechargeInfo, err error) {
|
|
data = make([]entity.V1CardAppleRechargeInfo, 0)
|
|
m := dao.V1CardAppleRechargeInfo.Ctx(ctx).DB(config.GetDatabaseV1())
|
|
if input.StartDate != nil {
|
|
m = m.WhereGTE(dao.V1CardAppleRechargeInfo.Columns().CreatedAt, input.StartDate)
|
|
}
|
|
if input.EndDate != nil {
|
|
input.EndDate = input.EndDate.AddDate(0, 0, 1)
|
|
m = m.WhereLTE(dao.V1CardAppleRechargeInfo.Columns().CreatedAt, input.EndDate)
|
|
}
|
|
if input.AccountID != "" {
|
|
m = m.WhereLike(dao.V1CardAppleRechargeInfo.Columns().AccountId, utils.OrmLike(input.AccountID))
|
|
}
|
|
if input.OrderNo != "" {
|
|
m = m.WhereLike(dao.V1CardAppleRechargeInfo.Columns().OrderNo, utils.OrmLike(input.OrderNo))
|
|
}
|
|
if input.Attach != "" {
|
|
m = m.WhereLike(dao.V1CardAppleRechargeInfo.Columns().Attach, utils.OrmLike(input.Attach))
|
|
}
|
|
if input.CardNo != "" {
|
|
m = m.WhereLike(dao.V1CardAppleRechargeInfo.Columns().OrderNo, utils.OrmLike(input.CardNo))
|
|
}
|
|
if input.CardPass != "" {
|
|
m = m.WhereLike(dao.V1CardAppleRechargeInfo.Columns().CardPass, utils.OrmLike(input.CardPass))
|
|
}
|
|
if input.UserId != "" {
|
|
m = m.Where(dao.V1CardAppleRechargeInfo.Columns().CreatedUserId, input.UserId)
|
|
}
|
|
if input.MerchantId != "" {
|
|
m = m.Where(dao.V1CardAppleRechargeInfo.Columns().MerchantId, input.MerchantId)
|
|
}
|
|
if input.Account != "" {
|
|
m = m.WhereLike(dao.V1CardAppleRechargeInfo.Columns().AccountName, utils.OrmLike(input.Account))
|
|
}
|
|
err2 := m.Page(input.Current, input.PageSize).
|
|
OrderDesc(dao.V1CardAppleRechargeInfo.Columns().CreatedAt).
|
|
ScanAndCount(&data, &total, false)
|
|
if err2 != nil {
|
|
total = 0
|
|
err = gerror.Wrap(err2, "获取充值订单列表(分页)失败")
|
|
}
|
|
return
|
|
}
|
|
|
|
// ListWithAccount 获取充值列表(包含账号信息)
|
|
func (h *sAppleOrder) ListWithAccount(ctx context.Context, input model.AppleCardRechargeParamsInput) (total int, data []model.AppleCardRechargeListOutput, err error) {
|
|
data = make([]model.AppleCardRechargeListOutput, 0)
|
|
m := dao.V1CardAppleRechargeInfo.Ctx(ctx).DB(config.GetDatabaseV1())
|
|
if input.AccountID != "" {
|
|
accountEntity, _ := service.AppleAccount().GetDetailById(ctx, input.AccountID)
|
|
if accountEntity.Id != "" {
|
|
m = m.Where(dao.V1CardAppleRechargeInfo.Columns().AccountId, accountEntity.Account)
|
|
}
|
|
}
|
|
if input.OrderNo != "" {
|
|
m = m.WhereLike(dao.V1CardAppleRechargeInfo.Columns().OrderNo, utils.OrmLike(input.OrderNo))
|
|
}
|
|
if input.Attach != "" {
|
|
m = m.WhereLike(dao.V1CardAppleRechargeInfo.Columns().Attach, utils.OrmLike(input.Attach))
|
|
}
|
|
if input.CardNo != "" {
|
|
m = m.WhereLike(dao.V1CardAppleRechargeInfo.Columns().OrderNo, utils.OrmLike(input.CardNo))
|
|
}
|
|
if input.CardPass != "" {
|
|
m = m.WhereLike(dao.V1CardAppleRechargeInfo.Columns().CardPass, utils.OrmLike(input.CardPass))
|
|
}
|
|
err2 := m.Page(input.Current, input.PageSize).WithAll().
|
|
OrderDesc(dao.V1CardAppleRechargeInfo.Columns().CreatedAt).
|
|
ScanAndCount(&data, &total, true)
|
|
if err2 != nil {
|
|
total = 0
|
|
err = gerror.Wrap(err2, "获取充值订单列表失败")
|
|
}
|
|
return
|
|
}
|
|
|
|
// AddRechargeOrder 添加一条充值记录
|
|
func (h *sAppleOrder) AddRechargeOrder(ctx context.Context, input *model.AppleCardRechargeInput) (orderNo string, err error) {
|
|
orderNo = utils.GenerateRandomUUID()
|
|
status := consts.AppleRechargeOrderWaiting
|
|
operation := consts.AppleRechargeOperationCreated
|
|
// 处理二次提交的订单
|
|
if targetEntity, _ := h.QueryOneByCardPass(ctx, input.CardPass, nil); targetEntity.Id != 0 &&
|
|
targetEntity.Status == int(consts.AppleRechargeOrderAmountDifferent) {
|
|
status = consts.AppleRechargeOrderCardNoOrCardPassDuplicated
|
|
operation = consts.AppleRechargeOperationDuplicatedOrder
|
|
if targetEntity.ActualAmount != input.Amount {
|
|
err = gerror.NewCode(errHandler.ErrAppleErrCardPass)
|
|
return
|
|
}
|
|
}
|
|
rechargeId, err := dao.V1CardAppleRechargeInfo.Ctx(ctx).DB(config.GetDatabaseV1()).
|
|
InsertAndGetId(do.V1CardAppleRechargeInfo{
|
|
OrderNo: orderNo,
|
|
AccountId: input.AccountID,
|
|
AccountName: input.AccountName,
|
|
CardNo: input.CardNo,
|
|
CardPass: input.CardPass,
|
|
Balance: input.Balance,
|
|
CardAmount: input.FaceValue,
|
|
Status: status,
|
|
CallbackUrl: input.CallbackUrl,
|
|
Attach: input.Attach,
|
|
MerchantId: input.MerchantId,
|
|
})
|
|
if err != nil {
|
|
err = gerror.WrapCode(gcode.CodeDbOperationError, err, "添加充值订单失败")
|
|
return "", err
|
|
}
|
|
err = h.AddHistory(ctx, &model.AppleCardRechargeHistoryInput{
|
|
RechargeId: int(rechargeId),
|
|
OrderNo: orderNo,
|
|
AccountName: input.AccountName,
|
|
Operation: operation,
|
|
}, nil)
|
|
if err != nil {
|
|
err = gerror.WrapCode(gcode.CodeDbOperationError, err, "添加充值订单历史记录失败")
|
|
return "", err
|
|
}
|
|
return orderNo, err
|
|
}
|
|
|
|
// DistributionAccordingAccount 给指定订单分配一个账户
|
|
func (h *sAppleOrder) DistributionAccordingAccount(ctx context.Context, account *entity.V1CardAppleAccountInfo, order *entity.V1CardAppleRechargeInfo) (err error) {
|
|
if account == nil || order == nil {
|
|
err = gerror.NewCode(gcode.CodeNil)
|
|
return
|
|
}
|
|
m := dao.V1CardAppleRechargeInfo.Ctx(ctx).DB(config.GetDatabaseV1()).Where(dao.V1CardAppleRechargeInfo.Columns().OrderNo, order.OrderNo)
|
|
err = m.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
|
|
_, err2 := m.TX(tx).Update(do.V1CardAppleRechargeInfo{
|
|
AccountId: account.Id,
|
|
AccountName: account.Account,
|
|
CreatedUserId: account.CreatedUserId,
|
|
})
|
|
if err2 != nil {
|
|
return err2
|
|
}
|
|
_, err2 = m.TX(tx).Update(g.Map{
|
|
dao.V1CardAppleRechargeInfo.Columns().DistributionCount: gdb.Counter{
|
|
Field: dao.V1CardAppleRechargeInfo.Columns().DistributionCount,
|
|
Value: 1,
|
|
},
|
|
})
|
|
return err2
|
|
})
|
|
return err
|
|
}
|
|
|
|
// DecrementDistributionCount 减少分配次数
|
|
func (h *sAppleOrder) DecrementDistributionCount(ctx context.Context, orderNo string) (err error) {
|
|
_, err = dao.V1CardAppleRechargeInfo.Ctx(ctx).DB(config.GetDatabaseV1()).
|
|
Where(dao.V1CardAppleRechargeInfo.Columns().OrderNo, orderNo).
|
|
Decrement(dao.V1CardAppleRechargeInfo.Columns().DistributionCount, 1)
|
|
return err
|
|
}
|
|
|
|
// UpdateActualAmount 修改订单实际金额
|
|
func (h *sAppleOrder) UpdateActualAmount(ctx context.Context, data *model.AppleAccountUpdateAmountRecord, tx gdb.TX) (err error) {
|
|
m := dao.V1CardAppleRechargeInfo.Ctx(ctx).DB(config.GetDatabaseV1())
|
|
if tx != nil {
|
|
m = m.TX(tx)
|
|
}
|
|
_, err = m.Where(dao.V1CardAppleRechargeInfo.Columns().OrderNo, data.OrderNo).
|
|
Update(do.V1CardAppleRechargeInfo{
|
|
ActualAmount: data.Amount,
|
|
Status: data.Status,
|
|
Remark: data.Remark,
|
|
})
|
|
return err
|
|
}
|
|
|
|
// UpdateActualAmountAndHistory 添加充值记录
|
|
func (h *sAppleOrder) UpdateActualAmountAndHistory(ctx context.Context, record *model.AppleAccountUpdateAmountAndHistoryRecord, tx gdb.TX) (err error) {
|
|
m := dao.V1CardAppleRechargeInfo.Ctx(ctx).DB(config.GetDatabaseV1())
|
|
if tx != nil {
|
|
m = m.TX(tx)
|
|
}
|
|
err = m.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
|
|
orderEntity, err2 := h.GetOneByOrderNo(ctx, record.OrderInfo.OrderNo, tx)
|
|
if err2 != nil {
|
|
return err2
|
|
}
|
|
if orderEntity.Id == 0 {
|
|
return gerror.NewCode(gcode.CodeNil)
|
|
}
|
|
err2 = h.UpdateActualAmount(ctx, record.OrderInfo, tx)
|
|
if err != nil {
|
|
return err2
|
|
}
|
|
err = h.AddHistory(ctx, &model.AppleCardRechargeHistoryInput{
|
|
RechargeId: int(orderEntity.Id),
|
|
OrderNo: orderEntity.OrderNo,
|
|
AccountID: orderEntity.AccountId,
|
|
AccountName: orderEntity.AccountName,
|
|
Operation: record.HistoryOperation,
|
|
Remark: record.HistoryRemark,
|
|
}, tx)
|
|
return err
|
|
})
|
|
return
|
|
}
|
|
|
|
func (h *sAppleOrder) UpdateActualAmountAndHistoryAndWallet(ctx context.Context, m *model.AppleAccountUpdateAmountAndHistoryRecord) (err error) {
|
|
err = config.GetDatabaseV1().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
|
|
if err = h.UpdateActualAmountAndHistory(ctx, m, tx); err != nil {
|
|
return err
|
|
}
|
|
//往钱包里充值
|
|
_, err = service.AppleAccount().AddWalletAmount(ctx, &model.AppleCardWalletInfo{
|
|
CommonStrId: commonApi.CommonStrId{ID: m.AccountId},
|
|
OrderNo: m.OrderInfo.OrderNo,
|
|
Amount: m.OrderInfo.Amount,
|
|
BalanceFromItunes: m.BalanceFromItunes,
|
|
Remark: m.WalletRemark,
|
|
}, tx)
|
|
return err
|
|
})
|
|
//if err != nil {
|
|
// newPool := pool.New(pool.AppleAccountCheckWallet, 10)
|
|
// _ = newPool.Add(ctx, func(ctx context.Context) {
|
|
// orderEntity, err2 := h.GetOneByOrderNo(ctx, m.OrderInfo.OrderNo, nil)
|
|
// if err2 != nil {
|
|
// return
|
|
// }
|
|
// //检查余额是否正常
|
|
// service.AppleAccount().CheckWalletHistoryNormal(ctx, orderEntity.AccountId)
|
|
// })
|
|
//}
|
|
return
|
|
}
|
|
|
|
// GetListByStatus 获取指定状态的订单
|
|
func (h *sAppleOrder) GetListByStatus(ctx context.Context, statusList []consts.AppleRechargeOrderStatus) (data entity.V1CardAppleRechargeInfo, err error) {
|
|
// 切片
|
|
err = dao.V1CardAppleRechargeInfo.Ctx(ctx).DB(config.GetDatabaseV1()).
|
|
WhereIn(dao.V1CardAppleRechargeInfo.Columns().Status, statusList).
|
|
Scan(&data)
|
|
return
|
|
}
|
|
|
|
// GetTodayRechargeAmountByAccountID 获取当前账户今日的充值金额
|
|
func (h *sAppleOrder) GetTodayRechargeAmountByAccountID(ctx context.Context, accountID string) (amount float64, err error) {
|
|
amount, err = dao.V1CardAppleRechargeInfo.Ctx(ctx).DB(config.GetDatabaseV1()).
|
|
Where(dao.V1CardAppleRechargeInfo.Columns().AccountId, accountID).
|
|
Where(dao.V1CardAppleRechargeInfo.Columns().Status, consts.AppleRechargeOrderProcessing).
|
|
Where(dao.V1CardAppleRechargeInfo.Columns().Status, consts.AppleRechargeOrderSuccess).
|
|
Where(dao.V1CardAppleRechargeInfo.Columns().Status, consts.AppleRechargeOrderAmountDifferent).
|
|
WhereBetween(dao.V1CardAppleRechargeInfo.Columns().CreatedAt, gtime.Now().StartOfDay(), gtime.Now()).
|
|
Sum(dao.V1CardAppleRechargeInfo.Columns().ActualAmount)
|
|
return
|
|
}
|
|
|
|
// GetRechargeStatusByOrderNo 通过订单号查询当前订单充值状态
|
|
func (h *sAppleOrder) GetRechargeStatusByOrderNo(ctx context.Context, orderNo string) (status int, err error) {
|
|
m := dao.V1CardAppleRechargeInfo.Ctx(ctx).DB(config.GetDatabaseV1())
|
|
err = m.Where(dao.V1CardAppleRechargeInfo.Columns().OrderNo, orderNo).Scan(&status)
|
|
return
|
|
}
|
|
|
|
// GetOneByOrderNo 通过订单号查询当前订单充值
|
|
func (h *sAppleOrder) GetOneByOrderNo(ctx context.Context, orderNo string, tx gdb.TX, id ...int64) (data entity.V1CardAppleRechargeInfo, err error) {
|
|
m := dao.V1CardAppleRechargeInfo.Ctx(ctx).DB(config.GetDatabaseV1())
|
|
if tx != nil {
|
|
m = m.TX(tx)
|
|
}
|
|
if orderNo != "" {
|
|
m = m.Where(dao.V1CardAppleRechargeInfo.Columns().OrderNo, orderNo)
|
|
}
|
|
if len(id) != 0 && id[0] != 0 {
|
|
m = m.Where(dao.V1CardAppleRechargeInfo.Columns().Id, id[0])
|
|
}
|
|
err = m.Scan(&data)
|
|
return
|
|
}
|
|
|
|
func (h *sAppleOrder) GetOneByMerchantId(ctx context.Context, merchantId string) (data *entity.V1CardAppleRechargeInfo, err error) {
|
|
err = dao.V1CardAppleRechargeInfo.Ctx(ctx).DB(config.GetDatabaseV1()).
|
|
Where(dao.V1CardAppleRechargeInfo.Columns().MerchantId, merchantId).
|
|
Scan(&data)
|
|
return
|
|
}
|
|
|
|
// GetAccordingOrder 找到符合条件的订单
|
|
// 最早提交等待处理的订单
|
|
func (h *sAppleOrder) GetAccordingOrder(ctx context.Context) (data *entity.V1CardAppleRechargeInfo, err error) {
|
|
gmlock.Lock("sAppleOrder_GetAccordingOrder")
|
|
defer gmlock.Unlock("sAppleOrder_GetAccordingOrder")
|
|
m := dao.V1CardAppleRechargeInfo.Ctx(ctx).DB(config.GetDatabaseV1()).
|
|
Where(dao.V1CardAppleRechargeInfo.Columns().Status, consts.AppleRechargeOrderWaiting).
|
|
OrderAsc(dao.V1CardAppleRechargeInfo.Columns().CreatedAt)
|
|
total, err := m.Count()
|
|
for i := 0; i < total; i++ {
|
|
// 这一行可以没必要
|
|
data = &entity.V1CardAppleRechargeInfo{}
|
|
err = m.Scan(data)
|
|
err = utils.HandleNoRowsError(err)
|
|
if data.Id == 0 || data.DistributionCount < consts.AppleOrderMaxDistributionCount {
|
|
break
|
|
}
|
|
err = config.GetDatabaseV1().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
|
|
err = h.ModifyOrderStatus(ctx, data.OrderNo, consts.AppleRechargeOrderFreeze, "订单回调超过最大次数", tx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = h.AddHistory(ctx, &model.AppleCardRechargeHistoryInput{
|
|
RechargeId: int(data.Id),
|
|
OrderNo: data.OrderNo,
|
|
AccountID: data.AccountId,
|
|
AccountName: data.AccountName,
|
|
Operation: consts.AppleRechargeOperationCallBackTimeout,
|
|
Remark: "itunes调用订单超过最大次数",
|
|
}, tx)
|
|
return err
|
|
})
|
|
data = &entity.V1CardAppleRechargeInfo{}
|
|
}
|
|
return
|
|
}
|
|
|
|
// GetAccordingOrders 找到符合条件的订单
|
|
func (h *sAppleOrder) GetAccordingOrders(ctx context.Context) (list []*entity.V1CardAppleRechargeInfo, err error) {
|
|
gmlock.Lock("sAppleOrder_GetAccordingOrders")
|
|
defer gmlock.Unlock("sAppleOrder_GetAccordingOrders")
|
|
_ = dao.V1CardAppleRechargeInfo.Ctx(ctx).DB(config.GetDatabaseV1()).
|
|
Where(dao.V1CardAppleRechargeInfo.Columns().Status, consts.AppleRechargeOrderWaiting).
|
|
OrderAsc(dao.V1CardAppleRechargeInfo.Columns().CreatedAt).Scan(&list)
|
|
|
|
slices.DeleteFunc(list, func(v *entity.V1CardAppleRechargeInfo) bool {
|
|
if v.Id == 0 || v.DistributionCount < consts.AppleOrderMaxDistributionCount {
|
|
return false
|
|
}
|
|
err = config.GetDatabaseV1().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
|
|
err = h.ModifyOrderStatus(ctx, v.OrderNo, consts.AppleRechargeOrderFreeze, "订单回调超过最大次数", tx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = h.AddHistory(ctx, &model.AppleCardRechargeHistoryInput{
|
|
RechargeId: int(v.Id),
|
|
OrderNo: v.OrderNo,
|
|
AccountID: v.AccountId,
|
|
AccountName: v.AccountName,
|
|
Operation: consts.AppleRechargeOperationCallBackTimeout,
|
|
Remark: "itunes调用订单超过最大次数",
|
|
}, tx)
|
|
return err
|
|
})
|
|
return true
|
|
})
|
|
return
|
|
}
|