联级,多选
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m52s

This commit is contained in:
2026-05-09 15:06:27 +08:00
parent 6a6672d0e4
commit 09cf0be86e
8 changed files with 124 additions and 24 deletions

View File

@@ -109,7 +109,13 @@ func (s *DeviceStore) List(ctx context.Context, opts *store.QueryOptions, filter
if status, ok := filters["status"].(int); ok && status > 0 {
query = query.Where("status = ?", status)
}
if shopID, ok := filters["shop_id"].(*uint); ok {
if shopIDs, ok := filters["shop_ids"].([]uint); ok {
if len(shopIDs) == 0 {
query = query.Where("1 = 0")
} else {
query = query.Where("shop_id IN ?", shopIDs)
}
} else if shopID, ok := filters["shop_id"].(*uint); ok {
if shopID == nil {
query = query.Where("shop_id IS NULL")
} else {

View File

@@ -677,7 +677,7 @@ func (s *IotCardStore) listStandaloneParallelTwoPhase(ctx context.Context, opts
defer wg.Done()
q := s.db.WithContext(ctx).Model(&model.IotCard{}).
Where("is_standalone = true AND deleted_at IS NULL AND shop_id = ?", sid)
Where("deleted_at IS NULL AND shop_id = ?", sid)
q = s.applyStandaloneFilters(ctx, q, filters)
var ids []cardIDWithTime
@@ -692,7 +692,7 @@ func (s *IotCardStore) listStandaloneParallelTwoPhase(ctx context.Context, opts
var count int64
if !hasCachedTotal {
countQ := s.db.WithContext(ctx).Model(&model.IotCard{}).
Where("is_standalone = true AND deleted_at IS NULL AND shop_id = ?", sid)
Where("deleted_at IS NULL AND shop_id = ?", sid)
countQ = s.applyStandaloneFilters(ctx, countQ, filters)
if err := countQ.Count(&count).Error; err != nil {
results[idx] = shopResult{err: err}
@@ -781,8 +781,8 @@ func (s *IotCardStore) listStandaloneParallelTwoPhase(ctx context.Context, opts
}
// applyStandaloneFilters 应用独立卡列表的通用过滤条件
// 注意:不包含 shop_id、deleted_at 条件(由调用方控制)
// 也不包含 subordinate_shop_ids仅用于路由选择,不作为查询条件
// 注意:不包含 deleted_at 条件(由调用方控制)
// subordinate_shop_ids 仅用于路由选择,不作为查询条件
// is_standalone 仅在 filters["is_standalone"] 非 nil 时拼接(不传则不过滤)
func (s *IotCardStore) applyStandaloneFilters(ctx context.Context, query *gorm.DB, filters map[string]any) *gorm.DB {
// is_standalone 为可选过滤条件,仅在明确传入时应用
@@ -797,8 +797,14 @@ func (s *IotCardStore) applyStandaloneFilters(ctx context.Context, query *gorm.D
if carrierID, ok := filters["carrier_id"].(uint); ok && carrierID > 0 {
query = query.Where("carrier_id = ?", carrierID)
}
// 并行路径下 shop_id 已由调用方设置,此处仅处理显式的 shop_id 过滤
if shopID, ok := filters["shop_id"].(uint); ok && shopID > 0 {
// 并行路径下 shop_id 已由调用方设置,此处仅处理显式店铺筛选。
if shopIDs, ok := filters["shop_ids"].([]uint); ok {
if len(shopIDs) == 0 {
query = query.Where("1 = 0")
} else {
query = query.Where("shop_id IN ?", shopIDs)
}
} else if shopID, ok := filters["shop_id"].(uint); ok && shopID > 0 {
query = query.Where("shop_id = ?", shopID)
}
if iccid, ok := filters["iccid"].(string); ok && iccid != "" {

View File

@@ -236,6 +236,14 @@ func (s *ShopStore) ListForCascade(ctx context.Context, shopName string, parentI
if parentID != nil {
query = query.Where("parent_id = ?", *parentID)
} else if middleware.GetUserTypeFromContext(ctx) == constants.UserTypeAgent {
shopID := middleware.GetShopIDFromContext(ctx)
if shopID == 0 {
query = query.Where("1 = 0")
} else {
// 代理账号的级联根节点是自己的店铺,避免默认根查询落到平台顶级店铺。
query = query.Where("id = ?", shopID)
}
} else {
query = query.Where("parent_id IS NULL")
}