关于绑定的问题
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled

This commit is contained in:
2026-06-22 12:08:41 +09:00
parent 5f960daf78
commit ba435dd6a6
13 changed files with 1306 additions and 210 deletions

View File

@@ -13,6 +13,7 @@ import (
"github.com/break/junhong_cmp_fiber/internal/model"
"github.com/break/junhong_cmp_fiber/internal/model/dto"
asset "github.com/break/junhong_cmp_fiber/internal/service/asset"
customerBinding "github.com/break/junhong_cmp_fiber/internal/service/customer_binding"
"github.com/break/junhong_cmp_fiber/internal/service/purchase_validation"
"github.com/break/junhong_cmp_fiber/internal/store/postgres"
"github.com/break/junhong_cmp_fiber/pkg/alipay"
@@ -55,7 +56,7 @@ type Service struct {
rechargeOrderStore *postgres.RechargeOrderStore
paymentStore *postgres.PaymentStore
walletStore *postgres.AssetWalletStore
personalDeviceStore *postgres.PersonalCustomerDeviceStore
customerBinding *customerBinding.Service
openIDStore *postgres.PersonalCustomerOpenIDStore
personalCustomerStore *postgres.PersonalCustomerStore
personalCustomerPhoneStore *postgres.PersonalCustomerPhoneStore
@@ -78,7 +79,7 @@ func New(
rechargeOrderStore *postgres.RechargeOrderStore,
paymentStore *postgres.PaymentStore,
walletStore *postgres.AssetWalletStore,
personalDeviceStore *postgres.PersonalCustomerDeviceStore,
binding *customerBinding.Service,
openIDStore *postgres.PersonalCustomerOpenIDStore,
personalCustomerStore *postgres.PersonalCustomerStore,
personalCustomerPhoneStore *postgres.PersonalCustomerPhoneStore,
@@ -99,7 +100,7 @@ func New(
rechargeOrderStore: rechargeOrderStore,
paymentStore: paymentStore,
walletStore: walletStore,
personalDeviceStore: personalDeviceStore,
customerBinding: binding,
openIDStore: openIDStore,
personalCustomerStore: personalCustomerStore,
personalCustomerPhoneStore: personalCustomerPhoneStore,
@@ -132,8 +133,10 @@ func (s *Service) CreateOrder(ctx context.Context, customerID uint, req *dto.Cli
return nil, err
}
if err := s.checkAssetOwnership(skipCtx, customerID, assetInfo.VirtualNo); err != nil {
return nil, err
if owned, err := s.customerBinding.OwnsAsset(skipCtx, customerID, assetInfo.AssetType, assetInfo.AssetID); err != nil {
return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询资产归属失败")
} else if !owned {
return nil, errors.New(errors.CodeForbidden, "无权限操作该资产或资源不存在")
}
validationResult, err := s.validatePurchase(skipCtx, assetInfo, req.PackageIDs)
@@ -256,29 +259,25 @@ func (s *Service) CreateOrder(ctx context.Context, customerID uint, req *dto.Cli
return s.createPackageOrder(skipCtx, customerID, validationResult, redisKey, &created)
}
func (s *Service) checkAssetOwnership(ctx context.Context, customerID uint, virtualNo string) error {
owned, err := s.personalDeviceStore.ExistsByCustomerAndDevice(ctx, customerID, virtualNo)
if err != nil {
return errors.Wrap(errors.CodeDatabaseError, err, "查询资产归属失败")
// getOrderAssetInfo 从订单中提取资产类型和 ID无需额外 DB 查询
func getOrderAssetInfo(order *model.Order) (string, uint, error) {
if order == nil {
return "", 0, errors.New(errors.CodeNotFound, "订单不存在")
}
if owned {
return nil
}
records, err := s.personalDeviceStore.GetByCustomerID(ctx, customerID)
if err != nil {
return errors.Wrap(errors.CodeDatabaseError, err, "查询资产归属失败")
}
for _, record := range records {
if record == nil {
continue
switch order.OrderType {
case model.OrderTypeSingleCard:
if order.IotCardID == nil || *order.IotCardID == 0 {
return "", 0, errors.New(errors.CodeInvalidParam)
}
if record.Status == constants.StatusEnabled && record.VirtualNo == virtualNo {
return nil
return "iot_card", *order.IotCardID, nil
case model.OrderTypeDevice:
if order.DeviceID == nil || *order.DeviceID == 0 {
return "", 0, errors.New(errors.CodeInvalidParam)
}
return "device", *order.DeviceID, nil
default:
return "", 0, errors.New(errors.CodeInvalidParam)
}
return errors.New(errors.CodeForbidden, "无权限操作该资产或资源不存在")
}
func (s *Service) validatePurchase(ctx context.Context, assetInfo *dto.AssetResolveResponse, packageIDs []uint) (*purchase_validation.PurchaseValidationResult, error) {
@@ -1066,8 +1065,10 @@ func (s *Service) ListOrders(ctx context.Context, customerID uint, req *dto.Clie
return nil, 0, err
}
if err := s.checkAssetOwnership(skipCtx, customerID, assetInfo.VirtualNo); err != nil {
return nil, 0, err
if owned, err := s.customerBinding.OwnsAsset(skipCtx, customerID, assetInfo.AssetType, assetInfo.AssetID); err != nil {
return nil, 0, errors.Wrap(errors.CodeDatabaseError, err, "查询资产归属失败")
} else if !owned {
return nil, 0, errors.New(errors.CodeForbidden, "无权限操作该资产或资源不存在")
}
generation, err := s.getAssetGeneration(skipCtx, assetInfo.AssetType, assetInfo.AssetID)
@@ -1150,13 +1151,14 @@ func (s *Service) GetOrderDetail(ctx context.Context, customerID uint, orderID u
}
skipCtx := context.WithValue(ctx, constants.ContextKeySubordinateShopIDs, []uint{})
virtualNo, err := s.getOrderVirtualNo(skipCtx, order)
orderAssetType, orderAssetID, err := getOrderAssetInfo(order)
if err != nil {
return nil, err
}
if err := s.checkAssetOwnership(skipCtx, customerID, virtualNo); err != nil {
return nil, err
if owned, ownErr := s.customerBinding.OwnsAsset(skipCtx, customerID, orderAssetType, orderAssetID); ownErr != nil {
return nil, errors.Wrap(errors.CodeDatabaseError, ownErr, "查询资产归属失败")
} else if !owned {
return nil, errors.New(errors.CodeForbidden, "无权限操作该资产或资源不存在")
}
packages := make([]dto.ClientOrderPackageItem, 0, len(items))