93 lines
3.1 KiB
Go
93 lines
3.1 KiB
Go
package order
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"time"
|
|
|
|
"github.com/perfect-panel/server/pkg/constant"
|
|
"github.com/perfect-panel/server/pkg/xerr"
|
|
|
|
"github.com/hibiken/asynq"
|
|
"github.com/perfect-panel/server/internal/model/order"
|
|
"github.com/perfect-panel/server/internal/model/user"
|
|
"github.com/perfect-panel/server/internal/svc"
|
|
"github.com/perfect-panel/server/internal/types"
|
|
"github.com/perfect-panel/server/pkg/logger"
|
|
"github.com/perfect-panel/server/pkg/tool"
|
|
queue "github.com/perfect-panel/server/queue/types"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
type RechargeLogic struct {
|
|
logger.Logger
|
|
ctx context.Context
|
|
svcCtx *svc.ServiceContext
|
|
}
|
|
|
|
// NewRechargeLogic Recharge
|
|
func NewRechargeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RechargeLogic {
|
|
return &RechargeLogic{
|
|
Logger: logger.WithContext(ctx),
|
|
ctx: ctx,
|
|
svcCtx: svcCtx,
|
|
}
|
|
}
|
|
|
|
func (l *RechargeLogic) Recharge(req *types.RechargeOrderRequest) (resp *types.RechargeOrderResponse, err error) {
|
|
u, ok := l.ctx.Value(constant.CtxKeyUser).(*user.User)
|
|
if !ok {
|
|
logger.Error("current user is not found in context")
|
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidAccess), "Invalid Access")
|
|
}
|
|
// find payment method
|
|
payment, err := l.svcCtx.PaymentModel.FindOne(l.ctx, req.Payment)
|
|
if err != nil {
|
|
l.Error("[Recharge] Database query error", logger.Field("error", err.Error()), logger.Field("payment", req.Payment))
|
|
return nil, errors.Wrapf(err, "find payment error: %v", err.Error())
|
|
}
|
|
// Calculate the handling fee
|
|
feeAmount := calculateFee(req.Amount, payment)
|
|
// query user is new purchase or renewal
|
|
isNew, err := l.svcCtx.OrderModel.IsUserEligibleForNewOrder(l.ctx, u.Id)
|
|
if err != nil {
|
|
l.Error("[Recharge] Database query error", logger.Field("error", err.Error()), logger.Field("user_id", u.Id))
|
|
return nil, errors.Wrapf(err, "query user error: %v", err.Error())
|
|
}
|
|
orderInfo := order.Order{
|
|
UserId: u.Id,
|
|
OrderNo: tool.GenerateTradeNo(),
|
|
Type: 4,
|
|
Price: req.Amount,
|
|
Amount: req.Amount + feeAmount,
|
|
FeeAmount: feeAmount,
|
|
PaymentId: req.Payment,
|
|
Method: payment.Platform,
|
|
Status: 1,
|
|
IsNew: isNew,
|
|
}
|
|
err = l.svcCtx.OrderModel.Insert(l.ctx, &orderInfo)
|
|
if err != nil {
|
|
l.Error("[Recharge] Database insert error", logger.Field("error", err.Error()), logger.Field("order", orderInfo))
|
|
return nil, errors.Wrapf(err, "insert order error: %v", err.Error())
|
|
}
|
|
// Deferred task
|
|
payload := queue.DeferCloseOrderPayload{
|
|
OrderNo: orderInfo.OrderNo,
|
|
}
|
|
val, err := json.Marshal(payload)
|
|
if err != nil {
|
|
l.Error("[Recharge] Marshal payload error", logger.Field("error", err.Error()), logger.Field("payload", payload))
|
|
}
|
|
task := asynq.NewTask(queue.DeferCloseOrder, val, asynq.MaxRetry(3))
|
|
taskInfo, err := l.svcCtx.Queue.Enqueue(task, asynq.ProcessIn(CloseOrderTimeMinutes*time.Minute))
|
|
if err != nil {
|
|
l.Error("[Recharge] Enqueue task error", logger.Field("error", err.Error()), logger.Field("task", task))
|
|
} else {
|
|
l.Info("[Recharge] Enqueue task success", logger.Field("TaskID", taskInfo.ID))
|
|
}
|
|
return &types.RechargeOrderResponse{
|
|
OrderNo: orderInfo.OrderNo,
|
|
}, nil
|
|
}
|