From a8ca00e5f213b15549c4aebeb488e981a36b5a36 Mon Sep 17 00:00:00 2001 From: break Date: Mon, 27 Jul 2026 18:43:16 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=A9=E6=8D=A2=E8=B4=A7=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E4=B8=8D=E5=8F=97=E6=96=B0=E8=B5=84=E4=BA=A7=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E4=B8=8E=E5=8E=9F=E5=BD=92=E5=B1=9E=E9=98=BB=E7=A2=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新资产仍需通过有效客户绑定和进行中换货占用校验,并返回明确的绑定冲突提示。 Constraint: 运营明确要求移除新资产在库和店铺一致限制 Rejected: 保留在库条件仅放宽店铺归属 | 无法支持已销售资产参与换货 Confidence: high Scope-risk: moderate Directive: 不得移除客户绑定和换货占用校验 Tested: git diff --check Not-tested: 按用户要求未运行自动化测试 --- internal/service/exchange/service.go | 29 +++++++--------------------- 1 file changed, 7 insertions(+), 22 deletions(-) diff --git a/internal/service/exchange/service.go b/internal/service/exchange/service.go index 1a9d5de..cb4becd 100644 --- a/internal/service/exchange/service.go +++ b/internal/service/exchange/service.go @@ -801,14 +801,6 @@ func (s *Service) validateExchangeAssetsWithTx(ctx context.Context, tx *gorm.DB, if !isExchangeableAssetStatus(oldAsset.AssetStatus) { return oldAssetStatusError(oldAsset.AssetStatus) } - if newAsset.AssetStatus != constants.AssetStatusInStock { - return errors.New(errors.CodeExchangeNewAssetNotInStock) - } - // 平台库存资产没有店铺归属,换货完成时会继承旧资产店铺; - // 已归属其他店铺的资产仍必须拒绝,避免跨店铺覆盖资产归属。 - if newAsset.ShopID != nil && !sameShopID(oldAsset.ShopID, newAsset.ShopID) { - return errors.New(errors.CodeForbidden, "新旧资产归属不一致") - } if err := s.ensureNewAssetBindingAvailableWithTx(ctx, tx, oldAsset, newAsset); err != nil { return err } @@ -835,7 +827,7 @@ func (s *Service) ensureNewAssetBindingAvailableWithTx(ctx context.Context, tx * return errors.Wrap(errors.CodeDatabaseError, err, "查询新资产客户绑定失败") } if newBindCount > 0 { - return errors.New(errors.CodeExchangeStatusInvalid, "新资产已存在有效客户绑定") + return errors.New(errors.CodeExchangeStatusInvalid, "新资产存在有效客户绑定,不可用于换货") } return nil } @@ -862,7 +854,7 @@ func (s *Service) syncNewAssetOwnershipWithTx(ctx context.Context, tx *gorm.DB, } result := tx.WithContext(ctx).Model(modelValue). - Where("id = ? AND asset_status = ?", newAsset.AssetID, constants.AssetStatusInStock). + Where("id = ?", newAsset.AssetID). Updates(map[string]any{ "shop_id": oldAsset.ShopID, "status": ownershipStatus, @@ -872,7 +864,7 @@ func (s *Service) syncNewAssetOwnershipWithTx(ctx context.Context, tx *gorm.DB, return errors.Wrap(errors.CodeDatabaseError, result.Error, "同步新资产店铺归属失败") } if result.RowsAffected == 0 { - return errors.New(errors.CodeExchangeNewAssetNotInStock) + return errors.New(errors.CodeAssetNotFound) } shopIDTag := uint(0) @@ -910,13 +902,13 @@ func (s *Service) updateAssetStatusesForCompletion(ctx context.Context, tx *gorm return errors.New(errors.CodeExchangeStatusInvalid, "旧资产状态已被修改,请重试") } result = tx.WithContext(ctx).Model(&model.IotCard{}). - Where("id = ? AND asset_status = ?", newAsset.AssetID, constants.AssetStatusInStock). + Where("id = ?", newAsset.AssetID). Updates(map[string]any{"asset_status": constants.AssetStatusSold, "updated_at": now}) if result.Error != nil { return errors.Wrap(errors.CodeDatabaseError, result.Error, "更新新卡状态失败") } if result.RowsAffected == 0 { - return errors.New(errors.CodeExchangeNewAssetNotInStock) + return errors.New(errors.CodeAssetNotFound) } return nil } @@ -930,13 +922,13 @@ func (s *Service) updateAssetStatusesForCompletion(ctx context.Context, tx *gorm return errors.New(errors.CodeExchangeStatusInvalid, "旧资产状态已被修改,请重试") } result = tx.WithContext(ctx).Model(&model.Device{}). - Where("id = ? AND asset_status = ?", newAsset.AssetID, constants.AssetStatusInStock). + Where("id = ?", newAsset.AssetID). Updates(map[string]any{"asset_status": constants.AssetStatusSold, "updated_at": now}) if result.Error != nil { return errors.Wrap(errors.CodeDatabaseError, result.Error, "更新新设备状态失败") } if result.RowsAffected == 0 { - return errors.New(errors.CodeExchangeNewAssetNotInStock) + return errors.New(errors.CodeAssetNotFound) } return nil } @@ -1007,13 +999,6 @@ func preferredDeviceIdentifier(device *model.Device) string { return device.SN } -func sameShopID(left, right *uint) bool { - if left == nil || right == nil { - return left == nil && right == nil - } - return *left == *right -} - func (s *Service) toExchangeOrderResponse(order *model.ExchangeOrder) *dto.ExchangeOrderResponse { if order == nil { return nil