feat(export): 增强SQL构建逻辑以支持YMT数据源的ID过滤

- 在BuildSQL函数中添加对reseller_id_eq和merchant_id_eq的处理逻辑,确保在YMT数据源下有效过滤无效ID
- 更新去重逻辑以支持YMT数据源的特定需求,提升SQL构建的灵活性
- 优化聚合查询时的字段别名处理,确保主表字段正确引用
- 增强代码可读性,确保逻辑清晰明了
This commit is contained in:
zhouyonggao 2025-12-17 17:39:35 +08:00
parent ec5322f602
commit d1b30deb4a
1 changed files with 68 additions and 10 deletions

View File

@ -245,6 +245,19 @@ func BuildSQL(req BuildRequest, whitelist map[string]bool) (string, []interface{
delete(req.Filters, "merchant_id_eq") delete(req.Filters, "merchant_id_eq")
} }
} }
// normalize reseller_id_eq (YMT 直连 merchant_id)
if req.Datasource == "ymt" && (req.MainTable == "order" || req.MainTable == "order_info") {
if v, ok := req.Filters["reseller_id_eq"]; ok {
if isZeroID(v) {
delete(req.Filters, "reseller_id_eq")
} else {
if _, has := req.Filters["merchant_id_in"]; !has {
req.Filters["merchant_id_in"] = []interface{}{v}
}
delete(req.Filters, "reseller_id_eq")
}
}
}
// helper: treat "0"/0/空 as未提供的 ID // helper: treat "0"/0/空 as未提供的 ID
isZeroID := func(v interface{}) bool { isZeroID := func(v interface{}) bool {
@ -520,7 +533,13 @@ func BuildSQL(req BuildRequest, whitelist map[string]bool) (string, []interface{
sb.WriteString(" WHERE ") sb.WriteString(" WHERE ")
sb.WriteString(strings.Join(where, " AND ")) sb.WriteString(strings.Join(where, " AND "))
} }
needDedupe := req.Datasource == "marketing" && req.MainTable == "order" && (need["order_voucher"] || need["voucher"] || need["voucher_batch"] || need["key_batch"] || need["code_batch"]) needDedupe := false
if req.Datasource == "marketing" && req.MainTable == "order" && (need["order_voucher"] || need["voucher"] || need["voucher_batch"] || need["key_batch"] || need["code_batch"]) {
needDedupe = true
}
if req.Datasource == "ymt" && (req.MainTable == "order" || req.MainTable == "order_info") && (need["order_digit"] || need["order_voucher"] || need["voucher"] || need["voucher_batch"]) {
needDedupe = true
}
if needDedupe { if needDedupe {
// Extract alias names in order // Extract alias names in order
aliases := make([]string, 0, len(cols)) aliases := make([]string, 0, len(cols))
@ -545,8 +564,8 @@ func BuildSQL(req BuildRequest, whitelist map[string]bool) (string, []interface{
} }
sources = append(sources, src) sources = append(sources, src)
} }
mt := sch.TableName(req.MainTable) // 聚合时按别名分组:主表字段别名始终是 req.MainTable.order_number
pkCol, _ := sch.MapField(req.MainTable, "order_number") pkAlias := req.MainTable + ".order_number"
var out strings.Builder var out strings.Builder
out.WriteString("SELECT ") out.WriteString("SELECT ")
for i := range aliases { for i := range aliases {
@ -563,7 +582,7 @@ func BuildSQL(req BuildRequest, whitelist map[string]bool) (string, []interface{
} }
out.WriteString(" FROM (") out.WriteString(" FROM (")
out.WriteString(sb.String()) out.WriteString(sb.String())
out.WriteString(") AS sub GROUP BY sub.`" + mt + "." + pkCol + "`") out.WriteString(") AS sub GROUP BY sub.`" + pkAlias + "`")
return out.String(), args, nil return out.String(), args, nil
} }
return sb.String(), args, nil return sb.String(), args, nil
@ -596,20 +615,51 @@ func BuildCountSQL(req BuildRequest, whitelist map[string]bool) (string, []inter
need[tbl] = true need[tbl] = true
} }
} }
// normalize merchant_id_eq / reseller_id_eq for YMT: skip 0/空, 非零转为 merchant_id_in 以便与 creator_in 做 OR
if v, ok := req.Filters["merchant_id_eq"]; ok {
if isZeroID(v) {
delete(req.Filters, "merchant_id_eq")
} else {
if _, has := req.Filters["merchant_id_in"]; !has {
req.Filters["merchant_id_in"] = []interface{}{v}
}
delete(req.Filters, "merchant_id_eq")
}
}
if req.Datasource == "ymt" && (req.MainTable == "order" || req.MainTable == "order_info") {
if v, ok := req.Filters["reseller_id_eq"]; ok {
if isZeroID(v) {
delete(req.Filters, "reseller_id_eq")
} else {
if _, has := req.Filters["merchant_id_in"]; !has {
req.Filters["merchant_id_in"] = []interface{}{v}
}
delete(req.Filters, "reseller_id_eq")
}
}
}
// Handle creator_in and merchant_id_in with OR logic if both exist // Handle creator_in and merchant_id_in with OR logic if both exist
var creatorArgs []interface{} var creatorArgs []interface{}
hasCreator := false hasCreator := false
if v, ok := req.Filters["creator_in"]; ok { if v, ok := req.Filters["creator_in"]; ok {
switch t := v.(type) { switch t := v.(type) {
case []interface{}: case []interface{}:
creatorArgs = t for _, x := range t {
if !isZeroID(x) {
creatorArgs = append(creatorArgs, x)
}
}
case []int: case []int:
for _, x := range t { for _, x := range t {
creatorArgs = append(creatorArgs, x) if !isZeroID(x) {
creatorArgs = append(creatorArgs, x)
}
} }
case []string: case []string:
for _, x := range t { for _, x := range t {
creatorArgs = append(creatorArgs, x) if !isZeroID(x) {
creatorArgs = append(creatorArgs, x)
}
} }
} }
if len(creatorArgs) > 0 { if len(creatorArgs) > 0 {
@ -622,14 +672,22 @@ func BuildCountSQL(req BuildRequest, whitelist map[string]bool) (string, []inter
if v, ok := req.Filters["merchant_id_in"]; ok { if v, ok := req.Filters["merchant_id_in"]; ok {
switch t := v.(type) { switch t := v.(type) {
case []interface{}: case []interface{}:
merchantArgs = t for _, x := range t {
if !isZeroID(x) {
merchantArgs = append(merchantArgs, x)
}
}
case []int: case []int:
for _, x := range t { for _, x := range t {
merchantArgs = append(merchantArgs, x) if !isZeroID(x) {
merchantArgs = append(merchantArgs, x)
}
} }
case []string: case []string:
for _, x := range t { for _, x := range t {
merchantArgs = append(merchantArgs, x) if !isZeroID(x) {
merchantArgs = append(merchantArgs, x)
}
} }
} }
if len(merchantArgs) > 0 { if len(merchantArgs) > 0 {