Compare commits

..

2 Commits

Author SHA1 Message Date
7f18765911 fix: IoT 卡列表查询补充 virtual_no 字段
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m58s
standaloneListColumns 是为性能优化而手写的列选择列表,
virtual_no 字段新增时只加了 model 和 DTO,遗漏了这里,
导致四条列表查询路径均未 SELECT virtual_no,字段始终为空。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 16:48:45 +08:00
876c92095c fix: 平台账号后台创建钱包订单时,绕过代理套餐分配检查
后台钱包支付下单时,原逻辑根据卡/设备所属代理店铺触发
套餐分配上架校验,导致平台账号无法为属于代理的卡购买
未被该代理分配的套餐(如 0 元赠送套餐)。

修复:在 CreateAdminOrder wallet 分支中,按买家类型区分:
- 代理账号:保留原有校验,确保卡所属代理已分配该套餐
- 平台/超管账号:跳过代理分配检查,仅验证套餐全局状态

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 15:51:01 +08:00
2 changed files with 15 additions and 3 deletions

View File

@@ -346,12 +346,24 @@ func (s *Service) CreateAdminOrder(ctx context.Context, req *dto.CreateAdminOrde
if req.IotCardID == nil {
return nil, errors.New(errors.CodeInvalidParam, "单卡购买必须指定IoT卡ID")
}
validationResult, err = s.purchaseValidationService.ValidateCardPurchase(ctx, *req.IotCardID, req.PackageIDs)
// 平台账号代表平台直接下单,不受卡所属代理的套餐分配限制;
// 代理账号下单时,卡所属代理必须已将套餐上架分配
if buyerType == model.BuyerTypeAgent {
validationResult, err = s.purchaseValidationService.ValidateCardPurchase(ctx, *req.IotCardID, req.PackageIDs)
} else {
validationResult, err = s.purchaseValidationService.ValidateAdminOfflineCardPurchase(ctx, *req.IotCardID, req.PackageIDs)
}
} else if req.OrderType == model.OrderTypeDevice {
if req.DeviceID == nil {
return nil, errors.New(errors.CodeInvalidParam, "设备购买必须指定设备ID")
}
validationResult, err = s.purchaseValidationService.ValidateDevicePurchase(ctx, *req.DeviceID, req.PackageIDs)
// 平台账号代表平台直接下单,不受设备所属代理的套餐分配限制;
// 代理账号下单时,设备所属代理必须已将套餐上架分配
if buyerType == model.BuyerTypeAgent {
validationResult, err = s.purchaseValidationService.ValidateDevicePurchase(ctx, *req.DeviceID, req.PackageIDs)
} else {
validationResult, err = s.purchaseValidationService.ValidateAdminOfflineDevicePurchase(ctx, *req.DeviceID, req.PackageIDs)
}
} else {
return nil, errors.New(errors.CodeInvalidParam, "无效的订单类型")
}

View File

@@ -210,7 +210,7 @@ func (s *IotCardStore) List(ctx context.Context, opts *store.QueryOptions, filte
// standaloneListColumns 列表查询只选取响应需要的列,避免 SELECT * 的宽行 I/O
var standaloneListColumns = []string{
"id", "iccid", "card_category", "carrier_id", "carrier_type", "carrier_name",
"id", "iccid", "virtual_no", "card_category", "carrier_id", "carrier_type", "carrier_name",
"imsi", "msisdn", "batch_no", "supplier", "status", "shop_id", "activated_at",
"activation_status", "real_name_status", "network_status", "data_usage_mb",
"current_month_usage_mb", "current_month_start_date", "last_month_total_mb",