This commit is contained in:
@@ -20,13 +20,17 @@ import (
|
||||
"github.com/perfect-panel/server/pkg/logger"
|
||||
"github.com/perfect-panel/server/pkg/tool"
|
||||
"github.com/perfect-panel/server/pkg/uuidx"
|
||||
"github.com/perfect-panel/server/pkg/xerr"
|
||||
pkgerrors "github.com/pkg/errors"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
const genericRecoveryError = "order recovery information is invalid"
|
||||
const (
|
||||
recoverySuccessMessage = "恢复完成,请使用该邮箱验证码登录查看订阅。"
|
||||
recoveryAlreadyDoneMessage = "该订单已恢复,请使用恢复时绑定的邮箱登录查看订阅。"
|
||||
recoveryInvalidOrderMessage = "订单信息无效,请确认订单号是否正确。"
|
||||
recoveryInvalidCodeMessage = "邮箱验证码错误或已过期,请重新获取验证码。"
|
||||
recoverySystemErrorMessage = "恢复暂时失败,请稍后再试或联系客服处理。"
|
||||
)
|
||||
|
||||
type RecoverOrderLogic struct {
|
||||
logger.Logger
|
||||
@@ -48,45 +52,51 @@ func (l *RecoverOrderLogic) RecoverOrder(req *types.RecoverOrderRequest) (*types
|
||||
code := strings.TrimSpace(req.Code)
|
||||
|
||||
if orderNo == "" || email == "" || code == "" {
|
||||
return nil, pkgerrors.Wrapf(xerr.NewErrCode(xerr.InvalidParams), genericRecoveryError)
|
||||
return recoveryFailed(recoveryInvalidOrderMessage), nil
|
||||
}
|
||||
|
||||
if err := l.verifyEmailCode(email, code); err != nil {
|
||||
return nil, err
|
||||
return recoveryFailed(recoveryInvalidCodeMessage), nil
|
||||
}
|
||||
|
||||
item, ok, err := recoveryconfig.FindOrder(orderNo)
|
||||
if err != nil {
|
||||
l.Errorw("[RecoverOrder] load recovery config failed", logger.Field("error", err.Error()))
|
||||
return nil, pkgerrors.Wrapf(xerr.NewErrCode(xerr.ERROR), genericRecoveryError)
|
||||
return recoveryFailed(recoverySystemErrorMessage), nil
|
||||
}
|
||||
if !ok {
|
||||
return nil, pkgerrors.Wrapf(xerr.NewErrCode(xerr.InvalidParams), genericRecoveryError)
|
||||
return recoveryFailed(recoveryInvalidOrderMessage), nil
|
||||
}
|
||||
|
||||
if item.OrderStatus != "" && item.OrderStatus != "success" {
|
||||
return nil, pkgerrors.Wrapf(xerr.NewErrCode(xerr.InvalidParams), genericRecoveryError)
|
||||
return recoveryFailed(recoveryInvalidOrderMessage), nil
|
||||
}
|
||||
if item.Quantity <= 0 || item.OrderMoneyCents <= 0 {
|
||||
return nil, pkgerrors.Wrapf(xerr.NewErrCode(xerr.InvalidParams), genericRecoveryError)
|
||||
return recoveryFailed(recoveryInvalidOrderMessage), nil
|
||||
}
|
||||
claimOrderNo := item.OutOrderNo
|
||||
if claimOrderNo == "" {
|
||||
claimOrderNo = item.OrderNo
|
||||
}
|
||||
|
||||
sub, err := l.svcCtx.SubscribeModel.FindOne(l.ctx, item.SubscribeId)
|
||||
if err != nil {
|
||||
l.Errorw("[RecoverOrder] subscribe not found", logger.Field("subscribe_id", item.SubscribeId), logger.Field("error", err.Error()))
|
||||
return nil, pkgerrors.Wrapf(xerr.NewErrCode(xerr.InvalidParams), genericRecoveryError)
|
||||
return recoveryFailed(recoverySystemErrorMessage), nil
|
||||
}
|
||||
|
||||
var (
|
||||
claim recoverymodel.OrderRecoveryClaim
|
||||
order ordermodel.Order
|
||||
userSub usermodel.Subscribe
|
||||
claim recoverymodel.OrderRecoveryClaim
|
||||
order ordermodel.Order
|
||||
userSub usermodel.Subscribe
|
||||
alreadyRecovered bool
|
||||
)
|
||||
err = l.svcCtx.DB.WithContext(l.ctx).Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Clauses(clause.Locking{Strength: "UPDATE"}).
|
||||
Model(&recoverymodel.OrderRecoveryClaim{}).
|
||||
Where("order_no = ?", orderNo).
|
||||
Where("order_no = ?", claimOrderNo).
|
||||
First(&claim).Error; err == nil {
|
||||
alreadyRecovered = true
|
||||
return nil
|
||||
} else if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return err
|
||||
@@ -98,7 +108,7 @@ func (l *RecoverOrderLogic) RecoverOrder(req *types.RecoverOrderRequest) (*types
|
||||
}
|
||||
|
||||
claim = recoverymodel.OrderRecoveryClaim{
|
||||
OrderNo: orderNo,
|
||||
OrderNo: claimOrderNo,
|
||||
Email: email,
|
||||
UserId: u.Id,
|
||||
SubscribeId: item.SubscribeId,
|
||||
@@ -128,7 +138,14 @@ func (l *RecoverOrderLogic) RecoverOrder(req *types.RecoverOrderRequest) (*types
|
||||
})
|
||||
if err != nil {
|
||||
l.Errorw("[RecoverOrder] recover failed", logger.Field("order_no", orderNo), logger.Field("error", err.Error()))
|
||||
return nil, pkgerrors.Wrapf(xerr.NewErrCode(xerr.DatabaseInsertError), genericRecoveryError)
|
||||
return recoveryFailed(recoverySystemErrorMessage), nil
|
||||
}
|
||||
|
||||
if alreadyRecovered {
|
||||
return &types.RecoverOrderResponse{
|
||||
Success: true,
|
||||
Message: recoveryAlreadyDoneMessage,
|
||||
}, nil
|
||||
}
|
||||
|
||||
l.clearCaches(&userSub, item.SubscribeId, email)
|
||||
@@ -137,10 +154,17 @@ func (l *RecoverOrderLogic) RecoverOrder(req *types.RecoverOrderRequest) (*types
|
||||
|
||||
return &types.RecoverOrderResponse{
|
||||
Success: true,
|
||||
Message: "recovery completed, please login with your email verification code",
|
||||
Message: recoverySuccessMessage,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func recoveryFailed(message string) *types.RecoverOrderResponse {
|
||||
return &types.RecoverOrderResponse{
|
||||
Success: false,
|
||||
Message: message,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *RecoverOrderLogic) createRecoveredOrder(tx *gorm.DB, userId int64, item recoveryconfig.Order, sub *subscribemodel.Subscribe) (ordermodel.Order, error) {
|
||||
var existing ordermodel.Order
|
||||
orderNo := item.OutOrderNo
|
||||
@@ -219,10 +243,6 @@ func (l *RecoverOrderLogic) createOrExtendSubscribe(tx *gorm.DB, userId int64, o
|
||||
existing.ExpireTime = base.Add(time.Duration(item.Quantity) * 24 * time.Hour)
|
||||
existing.Status = 1
|
||||
existing.FinishedAt = nil
|
||||
existing.NodeGroupId = sub.NodeGroupId
|
||||
existing.Traffic = sub.Traffic
|
||||
existing.Download = 0
|
||||
existing.Upload = 0
|
||||
if strings.TrimSpace(item.Note) != "" {
|
||||
existing.Note = strings.TrimSpace(item.Note)
|
||||
}
|
||||
@@ -275,7 +295,7 @@ func (l *RecoverOrderLogic) verifyEmailCode(email string, code string) error {
|
||||
return err
|
||||
}
|
||||
if resp == nil || !resp.Status {
|
||||
return pkgerrors.Wrapf(xerr.NewErrCode(xerr.InvalidParams), genericRecoveryError)
|
||||
return errors.New("invalid verification code")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -99,6 +99,12 @@ func loadOrders() (map[string]Order, error) {
|
||||
return nil, fmt.Errorf("duplicate recovery out_order_no %s", item.OutOrderNo)
|
||||
}
|
||||
result[item.OutOrderNo] = item
|
||||
if item.OrderNo != "" && item.OrderNo != item.OutOrderNo {
|
||||
if _, exists := result[item.OrderNo]; exists {
|
||||
return nil, fmt.Errorf("duplicate recovery order_no %s", item.OrderNo)
|
||||
}
|
||||
result[item.OrderNo] = item
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user