feat: tenant-scoped routing and portal navigation
This commit is contained in:
@@ -21,14 +21,19 @@ import (
|
||||
// @provider
|
||||
type order struct{}
|
||||
|
||||
func (s *order) ListUserOrders(ctx context.Context, userID int64, status string) ([]user_dto.Order, error) {
|
||||
func (s *order) ListUserOrders(ctx context.Context, tenantID, userID int64, status string) ([]user_dto.Order, error) {
|
||||
if userID == 0 {
|
||||
return nil, errorx.ErrUnauthorized
|
||||
}
|
||||
uid := userID
|
||||
|
||||
tbl, q := models.OrderQuery.QueryContext(ctx)
|
||||
q = q.Where(tbl.UserID.Eq(uid))
|
||||
if tenantID > 0 {
|
||||
q = q.Where(tbl.UserID.Eq(uid), tbl.TenantID.Eq(tenantID)).
|
||||
Or(tbl.UserID.Eq(uid), tbl.Type.Eq(consts.OrderTypeRecharge))
|
||||
} else {
|
||||
q = q.Where(tbl.UserID.Eq(uid))
|
||||
}
|
||||
|
||||
if status != "" && status != "all" {
|
||||
q = q.Where(tbl.Status.Eq(consts.OrderStatus(status)))
|
||||
@@ -46,14 +51,21 @@ func (s *order) ListUserOrders(ctx context.Context, userID int64, status string)
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (s *order) GetUserOrder(ctx context.Context, userID, id int64) (*user_dto.Order, error) {
|
||||
func (s *order) GetUserOrder(ctx context.Context, tenantID, userID, id int64) (*user_dto.Order, error) {
|
||||
if userID == 0 {
|
||||
return nil, errorx.ErrUnauthorized
|
||||
}
|
||||
uid := userID
|
||||
|
||||
tbl, q := models.OrderQuery.QueryContext(ctx)
|
||||
item, err := q.Where(tbl.ID.Eq(id), tbl.UserID.Eq(uid)).First()
|
||||
itemQuery := q
|
||||
if tenantID > 0 {
|
||||
itemQuery = itemQuery.Where(tbl.ID.Eq(id), tbl.UserID.Eq(uid), tbl.TenantID.Eq(tenantID)).
|
||||
Or(tbl.ID.Eq(id), tbl.UserID.Eq(uid), tbl.Type.Eq(consts.OrderTypeRecharge))
|
||||
} else {
|
||||
itemQuery = itemQuery.Where(tbl.ID.Eq(id), tbl.UserID.Eq(uid))
|
||||
}
|
||||
item, err := itemQuery.First()
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, errorx.ErrRecordNotFound
|
||||
@@ -70,6 +82,7 @@ func (s *order) GetUserOrder(ctx context.Context, userID, id int64) (*user_dto.O
|
||||
|
||||
func (s *order) Create(
|
||||
ctx context.Context,
|
||||
tenantID int64,
|
||||
userID int64,
|
||||
form *transaction_dto.OrderCreateForm,
|
||||
) (*transaction_dto.OrderCreateResponse, error) {
|
||||
@@ -86,7 +99,11 @@ func (s *order) Create(
|
||||
}
|
||||
if idempotencyKey != "" {
|
||||
tbl, q := models.OrderQuery.QueryContext(ctx)
|
||||
existing, err := q.Where(tbl.UserID.Eq(uid), tbl.IdempotencyKey.Eq(idempotencyKey)).First()
|
||||
q = q.Where(tbl.UserID.Eq(uid), tbl.IdempotencyKey.Eq(idempotencyKey))
|
||||
if tenantID > 0 {
|
||||
q = q.Where(tbl.TenantID.Eq(tenantID))
|
||||
}
|
||||
existing, err := q.First()
|
||||
if err == nil {
|
||||
return &transaction_dto.OrderCreateResponse{OrderID: existing.ID}, nil
|
||||
}
|
||||
@@ -96,7 +113,11 @@ func (s *order) Create(
|
||||
}
|
||||
|
||||
// 1. Fetch Content & Price
|
||||
content, err := models.ContentQuery.WithContext(ctx).Where(models.ContentQuery.ID.Eq(cid)).First()
|
||||
contentQuery := models.ContentQuery.WithContext(ctx).Where(models.ContentQuery.ID.Eq(cid))
|
||||
if tenantID > 0 {
|
||||
contentQuery = contentQuery.Where(models.ContentQuery.TenantID.Eq(tenantID))
|
||||
}
|
||||
content, err := contentQuery.First()
|
||||
if err != nil {
|
||||
return nil, errorx.ErrRecordNotFound.WithMsg("内容不存在")
|
||||
}
|
||||
@@ -188,6 +209,7 @@ func (s *order) Create(
|
||||
|
||||
func (s *order) Pay(
|
||||
ctx context.Context,
|
||||
tenantID int64,
|
||||
userID int64,
|
||||
id int64,
|
||||
form *transaction_dto.OrderPayForm,
|
||||
@@ -204,6 +226,9 @@ func (s *order) Pay(
|
||||
if err != nil {
|
||||
return nil, errorx.ErrRecordNotFound
|
||||
}
|
||||
if tenantID > 0 && o.TenantID > 0 && o.TenantID != tenantID {
|
||||
return nil, errorx.ErrForbidden.WithMsg("租户不匹配")
|
||||
}
|
||||
if o.Status != consts.OrderStatusCreated {
|
||||
return nil, errorx.ErrStatusConflict.WithMsg("订单状态不可支付")
|
||||
}
|
||||
@@ -219,11 +244,14 @@ func (s *order) Pay(
|
||||
}
|
||||
|
||||
// ProcessExternalPayment handles callback from payment gateway
|
||||
func (s *order) ProcessExternalPayment(ctx context.Context, orderID int64, externalID string) error {
|
||||
func (s *order) ProcessExternalPayment(ctx context.Context, tenantID, orderID int64, externalID string) error {
|
||||
o, err := models.OrderQuery.WithContext(ctx).Where(models.OrderQuery.ID.Eq(orderID)).First()
|
||||
if err != nil {
|
||||
return errorx.ErrRecordNotFound
|
||||
}
|
||||
if tenantID > 0 && o.TenantID > 0 && o.TenantID != tenantID {
|
||||
return errorx.ErrForbidden.WithMsg("租户不匹配")
|
||||
}
|
||||
if o.Status != consts.OrderStatusCreated {
|
||||
return nil // Already processed idempotency
|
||||
}
|
||||
@@ -365,7 +393,7 @@ func (s *order) settleOrder(ctx context.Context, o *models.Order, method, extern
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *order) Status(ctx context.Context, id int64) (*transaction_dto.OrderStatusResponse, error) {
|
||||
func (s *order) Status(ctx context.Context, tenantID, id int64) (*transaction_dto.OrderStatusResponse, error) {
|
||||
o, err := models.OrderQuery.WithContext(ctx).Where(models.OrderQuery.ID.Eq(id)).First()
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
@@ -373,6 +401,9 @@ func (s *order) Status(ctx context.Context, id int64) (*transaction_dto.OrderSta
|
||||
}
|
||||
return nil, errorx.ErrDatabaseError.WithCause(err)
|
||||
}
|
||||
if tenantID > 0 && o.TenantID > 0 && o.TenantID != tenantID {
|
||||
return nil, errorx.ErrForbidden.WithMsg("租户不匹配")
|
||||
}
|
||||
|
||||
return &transaction_dto.OrderStatusResponse{
|
||||
Status: string(o.Status),
|
||||
|
||||
Reference in New Issue
Block a user