🐛 修正之前的错误,添加订单什么的

🐛 修正url链接的问题

🐛 修正url链接的问题

🐛 修正url链接的问题
This commit is contained in:
sunxiaolong
2024-05-29 00:37:00 +08:00
parent 96eb5470af
commit 0dbace1e5d
17 changed files with 142 additions and 57 deletions

1
.gitattributes vendored
View File

@@ -1,2 +1 @@
* linguist-language=GO * linguist-language=GO
*.xlsx filter=lfs diff=lfs merge=lfs -text

View File

@@ -3,6 +3,7 @@ package cmd
import ( import (
"context" "context"
"kami/internal/controller/apple_card_info" "kami/internal/controller/apple_card_info"
"kami/utility/cron"
"github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp" "github.com/gogf/gf/v2/net/ghttp"
@@ -45,6 +46,10 @@ var Main = gcmd.Command{
group.Bind(apple_card_info.NewV1()) group.Bind(apple_card_info.NewV1())
}) })
//注册轮询任务
cron.RegisterCron(ctx)
s.Run() s.Run()
return nil return nil
}, },

View File

@@ -48,11 +48,12 @@ const (
type AppleRechargeOperation string type AppleRechargeOperation string
const ( const (
AppleRechargeOperationCreated AppleRechargeOperation = "创建订单" AppleRechargeOperationCreated AppleRechargeOperation = "创建订单"
AppleRechargeOperationWrongPassword AppleRechargeOperation = "密码错误" AppleRechargeOperationWrongPassword AppleRechargeOperation = "代充值账户密码错误,等待重新调度"
AppleRechargeOperationItunesFail AppleRechargeOperation = "iTunes处理失败(卡密错误)" AppleRechargeOperationItunesFail AppleRechargeOperation = "iTunes处理失败(卡密错误)"
AppleRechargeOperationItunesSucceed AppleRechargeOperation = "iTunes处理成功(兑换成功)" AppleRechargeOperationItunesSucceed AppleRechargeOperation = "iTunes处理成功(兑换成功)"
AppleRechargeOperationRepeated AppleRechargeOperation = "重复充值" AppleRechargeOperationItunesSucceedButWrongAmount AppleRechargeOperation = "iTunes处理成功(兑换成功,金额不一致)"
AppleRechargeOperationRepeated AppleRechargeOperation = "重复充值"
AppleRechargeOperationStartRechargeByItunes AppleRechargeOperation = "iTunes开始处理" AppleRechargeOperationStartRechargeByItunes AppleRechargeOperation = "iTunes开始处理"
AppleRechargeOperationHandleSuccessByManual AppleRechargeOperation = "手动处理成功" AppleRechargeOperationHandleSuccessByManual AppleRechargeOperation = "手动处理成功"

View File

@@ -2,17 +2,13 @@ package apple_card_info
import ( import (
"context" "context"
"fmt"
"github.com/gogf/gf/errors/gcode" "github.com/gogf/gf/errors/gcode"
"github.com/gogf/gf/v2/os/glog"
"kami/api/apple_card_info/v1" "kami/api/apple_card_info/v1"
"kami/api/commonapi" "kami/api/commonapi"
"kami/internal/consts" "kami/internal/consts"
"kami/internal/err_handler" "kami/internal/err_handler"
"kami/internal/model" "kami/internal/model"
"kami/internal/service" "kami/internal/service"
"kami/utility/pool"
"time"
) )
func (c *ControllerV1) CallBackOrderManual(ctx context.Context, req *v1.CallBackOrderManualReq) (res *v1.CallBackOrderManualRes, err error) { func (c *ControllerV1) CallBackOrderManual(ctx context.Context, req *v1.CallBackOrderManualReq) (res *v1.CallBackOrderManualRes, err error) {
@@ -41,42 +37,13 @@ func (c *ControllerV1) CallBackOrderManual(ctx context.Context, req *v1.CallBack
AccountID: orderEntity.AccountId, AccountID: orderEntity.AccountId,
Operation: consts.AppleRechargeOperationHandleSuccessByManual, Operation: consts.AppleRechargeOperationHandleSuccessByManual,
}, nil) }, nil)
//重新获取订单
orderEntity, _ = rechargeOrderService.GetRechargeOrderByOrderNo(ctx, req.OrderNo, req.ID) orderEntity, _ = rechargeOrderService.GetRechargeOrderByOrderNo(ctx, req.OrderNo, req.ID)
} }
err = rechargeOrderService.CallBackOrderToUpstream(ctx, orderEntity)
newPool := pool.New(pool.AppleCardCallBack, 20) if err != nil {
_ = newPool.Add(ctx, func(ctx context.Context) { err = err_handler.WrapError(ctx, err_handler.CornError, err, "回调网关失败,请稍后重试")
for i := 1; i < 4; i++ { return
isOk, err2 := rechargeOrderService.CallbackOrder(ctx, orderEntity) }
if err2 != nil {
glog.Error(ctx, "手动回调失败,原因:\n", err2)
_ = rechargeOrderService.AddHistory(ctx, model.AppleCardRechargeHistoryInput{
OrderNo: orderEntity.OrderNo,
RechargeId: orderEntity.Id,
AccountID: orderEntity.AccountId,
Operation: consts.AppleRechargeOperationCallBackFailed,
Remark: fmt.Sprintf("第%d次手动回调失败原因%+v", i, err2),
}, nil)
}
if isOk {
_ = rechargeOrderService.AddHistory(ctx, model.AppleCardRechargeHistoryInput{
OrderNo: orderEntity.OrderNo,
RechargeId: orderEntity.Id,
AccountID: orderEntity.AccountId,
Operation: consts.AppleRechargeOperationCallBackSuccess,
}, nil)
return
} else {
_ = rechargeOrderService.AddHistory(ctx, model.AppleCardRechargeHistoryInput{
OrderNo: orderEntity.OrderNo,
RechargeId: orderEntity.Id,
AccountID: orderEntity.AccountId,
Operation: consts.AppleRechargeOperationCallBackFailed,
Remark: fmt.Sprintf("第%d次手动回调失败原因回调接口返回失败", i),
}, nil)
}
time.Sleep(time.Duration(i*2) * time.Second)
}
})
return return
} }

View File

@@ -30,6 +30,7 @@ func (c *ControllerV1) RechargeHandler(ctx context.Context, req *v1.RechargeHand
err = err_handler.WrapError(ctx, gcode.CodeInternalError, err, "分配账户失败") err = err_handler.WrapError(ctx, gcode.CodeInternalError, err, "分配账户失败")
return return
} }
//这个是获取到该账户已经充值成功的金额
todayAmount, err := rechargeOrderService.GetTodayRechargeAmountByAccountID(ctx, accountInfo.Account) todayAmount, err := rechargeOrderService.GetTodayRechargeAmountByAccountID(ctx, accountInfo.Account)
if err != nil { if err != nil {
err = err_handler.WrapError(ctx, gcode.CodeInternalError, err, "获取今日充值金额失败") err = err_handler.WrapError(ctx, gcode.CodeInternalError, err, "获取今日充值金额失败")

View File

@@ -35,6 +35,7 @@ func (c *ControllerV1) RechargeItunesCallback(ctx context.Context, req *v1.Recha
Remark: req.Remark, Remark: req.Remark,
}, nil) }, nil)
case consts.AppleRechargeItunesStatusSuccess: case consts.AppleRechargeItunesStatusSuccess:
//如果当前订单已经处理成功,则不处理
if orderEntity.Status == int(consts.AppleRechargeOrderSuccess) || orderEntity.Status == int(consts.AppleRechargeOrderAmountDifferent) { if orderEntity.Status == int(consts.AppleRechargeOrderSuccess) || orderEntity.Status == int(consts.AppleRechargeOrderAmountDifferent) {
//添加一条记录 //添加一条记录
_ = rechargeOrderService.AddHistory(ctx, model.AppleCardRechargeHistoryInput{ _ = rechargeOrderService.AddHistory(ctx, model.AppleCardRechargeHistoryInput{
@@ -46,9 +47,14 @@ func (c *ControllerV1) RechargeItunesCallback(ctx context.Context, req *v1.Recha
}, nil) }, nil)
return return
} }
var status consts.AppleRechargeOperation
if orderEntity.CardAmount == req.Amount { if orderEntity.CardAmount == req.Amount {
status = consts.AppleRechargeOperationItunesSucceed
_ = rechargeOrderService.ModifyRechargeOrderStatus(ctx, orderEntity.OrderNo, consts.AppleRechargeOrderSuccess, nil) _ = rechargeOrderService.ModifyRechargeOrderStatus(ctx, orderEntity.OrderNo, consts.AppleRechargeOrderSuccess, nil)
} else { } else {
status = consts.AppleRechargeOperationItunesSucceedButWrongAmount
_ = rechargeOrderService.ModifyRechargeOrderStatus(ctx, orderEntity.OrderNo, consts.AppleRechargeOrderAmountDifferent, nil) _ = rechargeOrderService.ModifyRechargeOrderStatus(ctx, orderEntity.OrderNo, consts.AppleRechargeOrderAmountDifferent, nil)
} }
_ = appleAccountService.AddWalletAmount(ctx, model.AppleCardWalletInfo{ _ = appleAccountService.AddWalletAmount(ctx, model.AppleCardWalletInfo{
@@ -62,9 +68,10 @@ func (c *ControllerV1) RechargeItunesCallback(ctx context.Context, req *v1.Recha
AccountID: orderEntity.AccountId, AccountID: orderEntity.AccountId,
OrderNo: orderEntity.OrderNo, OrderNo: orderEntity.OrderNo,
RechargeId: orderEntity.Id, RechargeId: orderEntity.Id,
Operation: consts.AppleRechargeOperationItunesSucceed, Operation: status,
Remark: req.Remark, Remark: req.Remark,
}, nil) }, nil)
_ = rechargeOrderService.CallBackOrderToUpstream(ctx, orderEntity)
case consts.AppleRechargeItunesStatusFail: case consts.AppleRechargeItunesStatusFail:
_ = rechargeOrderService.ModifyRechargeOrderStatus(ctx, orderEntity.OrderNo, consts.AppleRechargeOrderFail, nil) _ = rechargeOrderService.ModifyRechargeOrderStatus(ctx, orderEntity.OrderNo, consts.AppleRechargeOrderFail, nil)
//添加一条记录 //添加一条记录

View File

@@ -12,4 +12,5 @@ var (
ErrFileBroken = gcode.New(2006, "文件损坏", nil) ErrFileBroken = gcode.New(2006, "文件损坏", nil)
HttpClientGetError = gcode.New(1005, "http请求失败", nil) HttpClientGetError = gcode.New(1005, "http请求失败", nil)
CornError = gcode.New(2001, "处理错误,请稍后重试", nil)
) )

View File

@@ -149,7 +149,7 @@ func (a *sAppleAccount) GetAccordingAccount(ctx context.Context) (data entity.V1
return return
} }
// 获取所有账号 // GetAllAccount 获取所有账号
func (a *sAppleAccount) GetAllAccount(ctx context.Context) (data []entity.V1CardAppleAccountInfo, err error) { func (a *sAppleAccount) GetAllAccount(ctx context.Context) (data []entity.V1CardAppleAccountInfo, err error) {
data = make([]entity.V1CardAppleAccountInfo, 0) data = make([]entity.V1CardAppleAccountInfo, 0)
err = dao.V1CardAppleAccountInfo.Ctx(ctx).DB(config.GetDatabaseV1()). err = dao.V1CardAppleAccountInfo.Ctx(ctx).DB(config.GetDatabaseV1()).
@@ -159,3 +159,33 @@ func (a *sAppleAccount) GetAllAccount(ctx context.Context) (data []entity.V1Card
} }
return return
} }
// GetAllAccountByStatus 获取所有可用的账号
func (a *sAppleAccount) GetAllAccountByStatus(ctx context.Context, status consts.AppleAccountStatus) (data []entity.V1CardAppleAccountInfo, err error) {
data = make([]entity.V1CardAppleAccountInfo, 0)
err = dao.V1CardAppleAccountInfo.Ctx(ctx).DB(config.GetDatabaseV1()).
WhereNot(dao.V1CardAppleAccountInfo.Columns().Status, consts.AppleAccountWrongPassword).
WhereNot(dao.V1CardAppleAccountInfo.Columns().Status, consts.AppleAccountForbidden).
Scan(&data)
if gerror.Equal(err, sql.ErrNoRows) {
err = nil
}
return
}
// ResetAccountStatus 重置账号状态
func (a *sAppleAccount) ResetAccountStatus(ctx context.Context) (err error) {
//所有账户今日交易量和交易订单金额清零
_, err = dao.V1CardAppleAccountInfo.Ctx(ctx).DB(config.GetDatabaseV1()).
Update(do.V1CardAppleAccountInfo{
TodayRechargeAmount: 0,
TodayRechargeCount: 0,
})
//所有交易满额的账户取消限制
_, err = dao.V1CardAppleAccountInfo.Ctx(ctx).DB(config.GetDatabaseV1()).
Where(dao.V1CardAppleAccountInfo.Columns().Status, consts.AppleAccountLimited).
Update(do.V1CardAppleAccountInfo{
Status: consts.AppleAccountNormal,
})
return
}

View File

@@ -16,6 +16,8 @@ import (
"github.com/google/uuid" "github.com/google/uuid"
"io" "io"
"kami/internal/err_handler" "kami/internal/err_handler"
"kami/utility/pool"
"time"
"kami/internal/consts" "kami/internal/consts"
"kami/internal/dao" "kami/internal/dao"
@@ -209,12 +211,14 @@ func (h *sRechargeHistory) GetRechargeDetails(ctx context.Context, orderNo strin
// GetTodayRechargeAmountByAccountID 获取当前账户今日的充值金额 // GetTodayRechargeAmountByAccountID 获取当前账户今日的充值金额
func (h *sRechargeHistory) GetTodayRechargeAmountByAccountID(ctx context.Context, accountID string) (amount float64, err error) { func (h *sRechargeHistory) GetTodayRechargeAmountByAccountID(ctx context.Context, accountID string) (amount float64, err error) {
// 定义进入0点的变量
year, month, day := gtime.Now().Date() year, month, day := gtime.Now().Date()
amount, err = dao.V1CardAppleRechargeInfo.Ctx(ctx).DB(config.GetDatabaseV1()). amount, err = dao.V1CardAppleRechargeInfo.Ctx(ctx).DB(config.GetDatabaseV1()).
WhereNot(dao.V1CardAppleRechargeInfo.Columns().Status, consts.AppleRechargeOrderFail). 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.NewFromStr(fmt.Sprintf("%d-%d-%d 00:00:00", year, month, day)), gtime.Now()). WhereBetween(dao.V1CardAppleRechargeInfo.Columns().CreatedAt, gtime.NewFromStr(fmt.Sprintf("%d-%d-%d 00:00:00", year, month, day)), gtime.Now()).
Sum(dao.V1CardAppleRechargeInfo.Columns().CardAmount) Sum(dao.V1CardAppleRechargeInfo.Columns().ActualAmount)
return return
} }
@@ -342,3 +346,41 @@ func (h *sRechargeHistory) CallbackOrder(ctx context.Context, data entity.V1Card
// 修改订单状态 // 修改订单状态
return true, nil return true, nil
} }
func (h *sRechargeHistory) CallBackOrderToUpstream(ctx context.Context, orderEntity entity.V1CardAppleRechargeInfo) (err error) {
newPool := pool.New(pool.AppleCardCallBack, 20)
err = newPool.Add(ctx, func(ctx context.Context) {
for i := 1; i < 4; i++ {
isOk, err2 := h.CallbackOrder(ctx, orderEntity)
if err2 != nil {
glog.Error(ctx, "手动回调失败,原因:\n", err2)
_ = h.AddHistory(ctx, model.AppleCardRechargeHistoryInput{
OrderNo: orderEntity.OrderNo,
RechargeId: orderEntity.Id,
AccountID: orderEntity.AccountId,
Operation: consts.AppleRechargeOperationCallBackFailed,
Remark: fmt.Sprintf("第%d次手动回调失败原因%+v", i, err2),
}, nil)
}
if isOk {
_ = h.AddHistory(ctx, model.AppleCardRechargeHistoryInput{
OrderNo: orderEntity.OrderNo,
RechargeId: orderEntity.Id,
AccountID: orderEntity.AccountId,
Operation: consts.AppleRechargeOperationCallBackSuccess,
}, nil)
return
} else {
_ = h.AddHistory(ctx, model.AppleCardRechargeHistoryInput{
OrderNo: orderEntity.OrderNo,
RechargeId: orderEntity.Id,
AccountID: orderEntity.AccountId,
Operation: consts.AppleRechargeOperationCallBackFailed,
Remark: fmt.Sprintf("第%d次手动回调失败原因回调接口返回失败", i),
}, nil)
}
time.Sleep(time.Duration(i*2) * time.Second)
}
})
return
}

View File

@@ -57,12 +57,12 @@ func (c *sUserCenter) CheckPassword(ctx context.Context, oldPassword, newPasswor
return false, err return false, err
} }
frontendResult, err := verify.AesCBCDecryptWithBase64(newPassword, []byte(frontendModel.Key), []byte(frontendModel.IV)) frontendResult, err := verify.AesCBCStdDecryptWithBase64(newPassword, []byte(frontendModel.Key), []byte(frontendModel.IV))
if err != nil { if err != nil {
return false, err return false, err
} }
backendResult, err := verify.AesCBCDecryptWithBase64(oldPassword, []byte(backendModel.Key), []byte(backendModel.IV)) backendResult, err := verify.AesCBCStdDecryptWithBase64(oldPassword, []byte(backendModel.Key), []byte(backendModel.IV))
if err != nil { if err != nil {
return false, err return false, err
} }
@@ -93,7 +93,7 @@ func (c *sUserCenter) ReGeneratePassword(ctx context.Context, password string) (
return "", err return "", err
} }
frontendResult, err := verify.AesCBCDecryptWithBase64(password, []byte(frontendModel.Key), []byte(frontendModel.IV)) frontendResult, err := verify.AesCBCStdDecryptWithBase64(password, []byte(frontendModel.Key), []byte(frontendModel.IV))
if err != nil { if err != nil {
return "", err return "", err
} }

View File

@@ -100,7 +100,7 @@ func IFrameAuth(r *ghttp.Request) {
}) })
return return
} }
tokenByte, err := verify.AesCBCDecryptWithBase64(tokenStr, []byte(frontendModel.Key), []byte(frontendModel.IV)) tokenByte, err := verify.AesCBCURLDecryptWithBase64(tokenStr, []byte(frontendModel.Key), []byte(frontendModel.IV))
if err != nil { if err != nil {
glog.Error(ctx, "解析Token错误", tokenStr, err) glog.Error(ctx, "解析Token错误", tokenStr, err)
r.Response.WriteJson(token.AuthFailed{ r.Response.WriteJson(token.AuthFailed{

View File

@@ -32,8 +32,12 @@ type (
GetDetailByAccount(ctx context.Context, account string) (data entity.V1CardAppleAccountInfo, err error) GetDetailByAccount(ctx context.Context, account string) (data entity.V1CardAppleAccountInfo, err error)
// GetAccordingAccount 轮播,获取符合条件的第一个账户 // GetAccordingAccount 轮播,获取符合条件的第一个账户
GetAccordingAccount(ctx context.Context) (data entity.V1CardAppleAccountInfo, err error) GetAccordingAccount(ctx context.Context) (data entity.V1CardAppleAccountInfo, err error)
// 获取所有账号 // GetAllAccount 获取所有账号
GetAllAccount(ctx context.Context) (data []entity.V1CardAppleAccountInfo, err error) GetAllAccount(ctx context.Context) (data []entity.V1CardAppleAccountInfo, err error)
// GetAllAccountByStatus 获取所有可用的账号
GetAllAccountByStatus(ctx context.Context, status consts.AppleAccountStatus) (data []entity.V1CardAppleAccountInfo, err error)
// ResetAccountStatus 重置账号状态
ResetAccountStatus(ctx context.Context) (err error)
} }
) )

View File

@@ -51,6 +51,7 @@ type (
QueryFaceValueByZHL(ctx context.Context, cardNo string) (bool, error) QueryFaceValueByZHL(ctx context.Context, cardNo string) (bool, error)
// CallbackOrder 回调订单给第三方 // CallbackOrder 回调订单给第三方
CallbackOrder(ctx context.Context, data entity.V1CardAppleRechargeInfo) (bool, error) CallbackOrder(ctx context.Context, data entity.V1CardAppleRechargeInfo) (bool, error)
CallBackOrderToUpstream(ctx context.Context, orderEntity entity.V1CardAppleRechargeInfo) (err error)
} }
) )

View File

@@ -1,5 +1,5 @@
server: server:
address: ":12401" address: ":8000"
NameToUriType: 3 NameToUriType: 3
maxHeaderBytes: "20KB" maxHeaderBytes: "20KB"
clientMaxBodySize: "50MB" clientMaxBodySize: "50MB"

View File

@@ -21,6 +21,7 @@ RUN echo "https://mirrors.aliyun.com/alpine/v3.18/main/" > /etc/apk/repositories
echo "Asia/Shanghai" > /etc/timezone echo "Asia/Shanghai" > /etc/timezone
COPY --from=builder /build/main /app/ COPY --from=builder /build/main /app/
COPY --from=builder /build/resource/public/ /app/resource/public/
# 启动服务 # 启动服务
CMD ["./main"] CMD ["./main"]

18
utility/cron/cron.go Normal file
View File

@@ -0,0 +1,18 @@
package cron
import (
"github.com/gogf/gf/v2/os/gcron"
"github.com/gogf/gf/v2/os/glog"
"golang.org/x/net/context"
"kami/internal/service"
)
// RegisterCron 注册定时任务
func RegisterCron(ctx context.Context) {
//每日0时执行
_, _ = gcron.Add(ctx, "0 0 0 * * ?", func(ctx context.Context) {
glog.Info(ctx, "每日0时执行重置苹果账户状态")
accountService := service.AppleAccount()
_ = accountService.ResetAccountStatus(ctx)
})
}

View File

@@ -56,7 +56,7 @@ func aesCBCDecrypt(ciphertext []byte, key []byte, iv []byte) ([]byte, error) {
return result, nil return result, nil
} }
func AesCBCDecryptWithBase64(ciphertext string, key []byte, iv []byte) ([]byte, error) { func AesCBCStdDecryptWithBase64(ciphertext string, key []byte, iv []byte) ([]byte, error) {
text, err := base64.StdEncoding.DecodeString(ciphertext) text, err := base64.StdEncoding.DecodeString(ciphertext)
if err != nil { if err != nil {
return text, err return text, err
@@ -64,6 +64,14 @@ func AesCBCDecryptWithBase64(ciphertext string, key []byte, iv []byte) ([]byte,
return aesCBCDecrypt(text, key, iv) return aesCBCDecrypt(text, key, iv)
} }
func AesCBCURLDecryptWithBase64(ciphertext string, key []byte, iv []byte) ([]byte, error) {
text, err := base64.URLEncoding.DecodeString(ciphertext)
if err != nil {
return text, err
}
return aesCBCDecrypt(text, key, iv)
}
// PKCS7 填充 // PKCS7 填充
func paddingPKCS7(plaintext []byte, blockSize int) []byte { func paddingPKCS7(plaintext []byte, blockSize int) []byte {
paddingSize := blockSize - len(plaintext)%blockSize paddingSize := blockSize - len(plaintext)%blockSize