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

🐛 修正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
*.xlsx filter=lfs diff=lfs merge=lfs -text

View File

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

View File

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

View File

@@ -2,17 +2,13 @@ package apple_card_info
import (
"context"
"fmt"
"github.com/gogf/gf/errors/gcode"
"github.com/gogf/gf/v2/os/glog"
"kami/api/apple_card_info/v1"
"kami/api/commonapi"
"kami/internal/consts"
"kami/internal/err_handler"
"kami/internal/model"
"kami/internal/service"
"kami/utility/pool"
"time"
)
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,
Operation: consts.AppleRechargeOperationHandleSuccessByManual,
}, nil)
//重新获取订单
orderEntity, _ = rechargeOrderService.GetRechargeOrderByOrderNo(ctx, req.OrderNo, req.ID)
}
newPool := pool.New(pool.AppleCardCallBack, 20)
_ = newPool.Add(ctx, func(ctx context.Context) {
for i := 1; i < 4; i++ {
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)
err = rechargeOrderService.CallBackOrderToUpstream(ctx, orderEntity)
if err != nil {
err = err_handler.WrapError(ctx, err_handler.CornError, err, "回调网关失败,请稍后重试")
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
}

View File

@@ -30,6 +30,7 @@ func (c *ControllerV1) RechargeHandler(ctx context.Context, req *v1.RechargeHand
err = err_handler.WrapError(ctx, gcode.CodeInternalError, err, "分配账户失败")
return
}
//这个是获取到该账户已经充值成功的金额
todayAmount, err := rechargeOrderService.GetTodayRechargeAmountByAccountID(ctx, accountInfo.Account)
if err != nil {
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,
}, nil)
case consts.AppleRechargeItunesStatusSuccess:
//如果当前订单已经处理成功,则不处理
if orderEntity.Status == int(consts.AppleRechargeOrderSuccess) || orderEntity.Status == int(consts.AppleRechargeOrderAmountDifferent) {
//添加一条记录
_ = rechargeOrderService.AddHistory(ctx, model.AppleCardRechargeHistoryInput{
@@ -46,9 +47,14 @@ func (c *ControllerV1) RechargeItunesCallback(ctx context.Context, req *v1.Recha
}, nil)
return
}
var status consts.AppleRechargeOperation
if orderEntity.CardAmount == req.Amount {
status = consts.AppleRechargeOperationItunesSucceed
_ = rechargeOrderService.ModifyRechargeOrderStatus(ctx, orderEntity.OrderNo, consts.AppleRechargeOrderSuccess, nil)
} else {
status = consts.AppleRechargeOperationItunesSucceedButWrongAmount
_ = rechargeOrderService.ModifyRechargeOrderStatus(ctx, orderEntity.OrderNo, consts.AppleRechargeOrderAmountDifferent, nil)
}
_ = appleAccountService.AddWalletAmount(ctx, model.AppleCardWalletInfo{
@@ -62,9 +68,10 @@ func (c *ControllerV1) RechargeItunesCallback(ctx context.Context, req *v1.Recha
AccountID: orderEntity.AccountId,
OrderNo: orderEntity.OrderNo,
RechargeId: orderEntity.Id,
Operation: consts.AppleRechargeOperationItunesSucceed,
Operation: status,
Remark: req.Remark,
}, nil)
_ = rechargeOrderService.CallBackOrderToUpstream(ctx, orderEntity)
case consts.AppleRechargeItunesStatusFail:
_ = rechargeOrderService.ModifyRechargeOrderStatus(ctx, orderEntity.OrderNo, consts.AppleRechargeOrderFail, nil)
//添加一条记录

View File

@@ -12,4 +12,5 @@ var (
ErrFileBroken = gcode.New(2006, "文件损坏", 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
}
// 获取所有账号
// GetAllAccount 获取所有账号
func (a *sAppleAccount) GetAllAccount(ctx context.Context) (data []entity.V1CardAppleAccountInfo, err error) {
data = make([]entity.V1CardAppleAccountInfo, 0)
err = dao.V1CardAppleAccountInfo.Ctx(ctx).DB(config.GetDatabaseV1()).
@@ -159,3 +159,33 @@ func (a *sAppleAccount) GetAllAccount(ctx context.Context) (data []entity.V1Card
}
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"
"io"
"kami/internal/err_handler"
"kami/utility/pool"
"time"
"kami/internal/consts"
"kami/internal/dao"
@@ -209,12 +211,14 @@ func (h *sRechargeHistory) GetRechargeDetails(ctx context.Context, orderNo strin
// GetTodayRechargeAmountByAccountID 获取当前账户今日的充值金额
func (h *sRechargeHistory) GetTodayRechargeAmountByAccountID(ctx context.Context, accountID string) (amount float64, err error) {
// 定义进入0点的变量
year, month, day := gtime.Now().Date()
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()).
Sum(dao.V1CardAppleRechargeInfo.Columns().CardAmount)
Sum(dao.V1CardAppleRechargeInfo.Columns().ActualAmount)
return
}
@@ -342,3 +346,41 @@ func (h *sRechargeHistory) CallbackOrder(ctx context.Context, data entity.V1Card
// 修改订单状态
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
}
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 {
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 {
return false, err
}
@@ -93,7 +93,7 @@ func (c *sUserCenter) ReGeneratePassword(ctx context.Context, password string) (
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 {
return "", err
}

View File

@@ -100,7 +100,7 @@ func IFrameAuth(r *ghttp.Request) {
})
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 {
glog.Error(ctx, "解析Token错误", tokenStr, err)
r.Response.WriteJson(token.AuthFailed{

View File

@@ -32,8 +32,12 @@ type (
GetDetailByAccount(ctx context.Context, account string) (data entity.V1CardAppleAccountInfo, err error)
// GetAccordingAccount 轮播,获取符合条件的第一个账户
GetAccordingAccount(ctx context.Context) (data entity.V1CardAppleAccountInfo, err error)
// 获取所有账号
// GetAllAccount 获取所有账号
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)
// CallbackOrder 回调订单给第三方
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:
address: ":12401"
address: ":8000"
NameToUriType: 3
maxHeaderBytes: "20KB"
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
COPY --from=builder /build/main /app/
COPY --from=builder /build/resource/public/ /app/resource/public/
# 启动服务
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
}
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)
if err != nil {
return text, err
@@ -64,6 +64,14 @@ func AesCBCDecryptWithBase64(ciphertext string, key []byte, iv []byte) ([]byte,
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 填充
func paddingPKCS7(plaintext []byte, blockSize int) []byte {
paddingSize := blockSize - len(plaintext)%blockSize