feat(exporter): 支持从order_info表导出数据并适配不同表结构
修改SQL构建逻辑以同时支持从order和order_info表导出数据 根据主表类型自动适配不同的字段名和关联条件
This commit is contained in:
parent
7e7fdbc4cc
commit
741722b6b1
|
|
@ -14,9 +14,9 @@ type BuildRequest struct {
|
|||
}
|
||||
|
||||
func BuildSQL(req BuildRequest, whitelist map[string]bool) (string, []interface{}, error) {
|
||||
if req.MainTable != "order" {
|
||||
return "", nil, errors.New("unsupported main table")
|
||||
}
|
||||
if req.MainTable != "order" && req.MainTable != "order_info" {
|
||||
return "", nil, errors.New("unsupported main table")
|
||||
}
|
||||
cols := []string{}
|
||||
need := map[string]bool{}
|
||||
for _, tf := range req.Fields {
|
||||
|
|
@ -71,44 +71,49 @@ func BuildSQL(req BuildRequest, whitelist map[string]bool) (string, []interface{
|
|||
sb := strings.Builder{}
|
||||
sb.WriteString("SELECT ")
|
||||
sb.WriteString(strings.Join(cols, ","))
|
||||
sb.WriteString(" FROM `order`")
|
||||
sb.WriteString(" FROM `" + req.MainTable + "`")
|
||||
// JOINs based on need
|
||||
// order_detail
|
||||
if need["order_detail"] {
|
||||
sb.WriteString(" LEFT JOIN `order_detail` ON `order_detail`.order_number = `order`.order_number")
|
||||
}
|
||||
// order_cash
|
||||
if need["order_cash"] {
|
||||
sb.WriteString(" LEFT JOIN `order_cash` ON `order_cash`.order_number = `order`.order_number")
|
||||
}
|
||||
// order_voucher
|
||||
if need["order_voucher"] {
|
||||
sb.WriteString(" LEFT JOIN `order_voucher` ON `order_voucher`.order_number = `order`.order_number")
|
||||
}
|
||||
if need["order_detail"] && req.MainTable == "order" {
|
||||
sb.WriteString(" LEFT JOIN `order_detail` ON `order_detail`.order_number = `order`.order_number")
|
||||
}
|
||||
// order_cash
|
||||
if need["order_cash"] {
|
||||
if req.MainTable == "order_info" {
|
||||
sb.WriteString(" LEFT JOIN `order_cash` ON `order_cash`.order_no = `order_info`.order_no")
|
||||
} else {
|
||||
sb.WriteString(" LEFT JOIN `order_cash` ON `order_cash`.order_number = `order`.order_number")
|
||||
}
|
||||
}
|
||||
// order_voucher
|
||||
if need["order_voucher"] {
|
||||
if req.MainTable == "order_info" {
|
||||
sb.WriteString(" LEFT JOIN `order_voucher` ON `order_voucher`.order_no = `order_info`.order_no")
|
||||
} else {
|
||||
sb.WriteString(" LEFT JOIN `order_voucher` ON `order_voucher`.order_number = `order`.order_number")
|
||||
}
|
||||
}
|
||||
// plan
|
||||
if need["plan"] || need["key_batch"] {
|
||||
sb.WriteString(" LEFT JOIN `plan` ON `plan`.id = `order`.plan_id")
|
||||
}
|
||||
// key_batch depends on plan
|
||||
if need["key_batch"] {
|
||||
sb.WriteString(" LEFT JOIN `key_batch` ON `key_batch`.plan_id = `plan`.id")
|
||||
}
|
||||
// code_batch depends on key_batch
|
||||
if need["code_batch"] {
|
||||
sb.WriteString(" LEFT JOIN `code_batch` ON `code_batch`.key_batch_id = `key_batch`.id")
|
||||
}
|
||||
// voucher depends on order_voucher
|
||||
if need["voucher"] {
|
||||
sb.WriteString(" LEFT JOIN `voucher` ON `voucher`.channel_activity_id = `order_voucher`.channel_activity_id")
|
||||
}
|
||||
// voucher_batch depends on voucher
|
||||
if need["voucher_batch"] {
|
||||
sb.WriteString(" LEFT JOIN `voucher_batch` ON `voucher_batch`.voucher_id = `voucher`.id")
|
||||
}
|
||||
// merchant_key_send depends on order.key
|
||||
if need["merchant_key_send"] {
|
||||
sb.WriteString(" LEFT JOIN `merchant_key_send` ON `order`." + escape("key") + " = `merchant_key_send`.key")
|
||||
}
|
||||
if req.MainTable == "order" {
|
||||
if need["plan"] || need["key_batch"] {
|
||||
sb.WriteString(" LEFT JOIN `plan` ON `plan`.id = `order`.plan_id")
|
||||
}
|
||||
if need["key_batch"] {
|
||||
sb.WriteString(" LEFT JOIN `key_batch` ON `key_batch`.plan_id = `plan`.id")
|
||||
}
|
||||
if need["code_batch"] {
|
||||
sb.WriteString(" LEFT JOIN `code_batch` ON `code_batch`.key_batch_id = `key_batch`.id")
|
||||
}
|
||||
if need["voucher"] {
|
||||
sb.WriteString(" LEFT JOIN `voucher` ON `voucher`.channel_activity_id = `order_voucher`.channel_activity_id")
|
||||
}
|
||||
if need["voucher_batch"] {
|
||||
sb.WriteString(" LEFT JOIN `voucher_batch` ON `voucher_batch`.voucher_id = `voucher`.id")
|
||||
}
|
||||
if need["merchant_key_send"] {
|
||||
sb.WriteString(" LEFT JOIN `merchant_key_send` ON `order`." + escape("key") + " = `merchant_key_send`.key")
|
||||
}
|
||||
}
|
||||
|
||||
args := []interface{}{}
|
||||
where := []string{}
|
||||
|
|
@ -127,8 +132,8 @@ func BuildSQL(req BuildRequest, whitelist map[string]bool) (string, []interface{
|
|||
if _, ok := req.Filters["merchant_out_biz_no_eq"]; ok {
|
||||
need["merchant_key_send"] = true
|
||||
}
|
||||
if v, ok := req.Filters["creator_in"]; ok {
|
||||
ids := []interface{}{}
|
||||
if v, ok := req.Filters["creator_in"]; ok {
|
||||
ids := []interface{}{}
|
||||
switch t := v.(type) {
|
||||
case []interface{}:
|
||||
ids = t
|
||||
|
|
@ -146,20 +151,28 @@ func BuildSQL(req BuildRequest, whitelist map[string]bool) (string, []interface{
|
|||
}
|
||||
ph := strings.Repeat("?,", len(ids))
|
||||
ph = strings.TrimSuffix(ph, ",")
|
||||
where = append(where, "`order`.creator IN ("+ph+")")
|
||||
args = append(args, ids...)
|
||||
}
|
||||
if v, ok := req.Filters["create_time_between"]; ok {
|
||||
if req.MainTable == "order_info" {
|
||||
where = append(where, "`order_info`.user_id IN ("+ph+")")
|
||||
} else {
|
||||
where = append(where, "`order`.creator IN ("+ph+")")
|
||||
}
|
||||
args = append(args, ids...)
|
||||
}
|
||||
if v, ok := req.Filters["create_time_between"]; ok {
|
||||
var arr []interface{}
|
||||
b, _ := json.Marshal(v)
|
||||
json.Unmarshal(b, &arr)
|
||||
if len(arr) != 2 {
|
||||
return "", nil, errors.New("create_time_between requires 2 values")
|
||||
}
|
||||
where = append(where, "`order`.create_time BETWEEN ? AND ?")
|
||||
args = append(args, arr[0], arr[1])
|
||||
}
|
||||
if v, ok := req.Filters["type_eq"]; ok {
|
||||
if req.MainTable == "order_info" {
|
||||
where = append(where, "`order_info`.create_time BETWEEN ? AND ?")
|
||||
} else {
|
||||
where = append(where, "`order`.create_time BETWEEN ? AND ?")
|
||||
}
|
||||
args = append(args, arr[0], arr[1])
|
||||
}
|
||||
if v, ok := req.Filters["type_eq"]; ok {
|
||||
var tv int
|
||||
switch t := v.(type) {
|
||||
case float64:
|
||||
|
|
@ -176,88 +189,132 @@ func BuildSQL(req BuildRequest, whitelist map[string]bool) (string, []interface{
|
|||
tv = tv*10 + int(c-'0')
|
||||
}
|
||||
}
|
||||
if tv == 1 || tv == 2 || tv == 3 {
|
||||
where = append(where, "`order`.type = ?")
|
||||
args = append(args, tv)
|
||||
}
|
||||
}
|
||||
if v, ok := req.Filters["out_trade_no_eq"]; ok {
|
||||
s := toString(v)
|
||||
if s != "" {
|
||||
where = append(where, "`order`.out_trade_no = ?")
|
||||
args = append(args, s)
|
||||
}
|
||||
}
|
||||
if v, ok := req.Filters["account_eq"]; ok {
|
||||
s := toString(v)
|
||||
if s != "" {
|
||||
where = append(where, "`order`.account = ?")
|
||||
args = append(args, s)
|
||||
}
|
||||
}
|
||||
if v, ok := req.Filters["plan_id_eq"]; ok {
|
||||
s := toString(v)
|
||||
if s != "" {
|
||||
where = append(where, "`order`.plan_id = ?")
|
||||
args = append(args, s)
|
||||
}
|
||||
}
|
||||
if v, ok := req.Filters["key_batch_id_eq"]; ok {
|
||||
s := toString(v)
|
||||
if s != "" {
|
||||
where = append(where, "`order`.key_batch_id = ?")
|
||||
args = append(args, s)
|
||||
}
|
||||
}
|
||||
if v, ok := req.Filters["product_id_eq"]; ok {
|
||||
s := toString(v)
|
||||
if s != "" {
|
||||
where = append(where, "`order`.product_id = ?")
|
||||
args = append(args, s)
|
||||
}
|
||||
}
|
||||
if v, ok := req.Filters["reseller_id_eq"]; ok {
|
||||
s := toString(v)
|
||||
if s != "" {
|
||||
where = append(where, "`order`.reseller_id = ?")
|
||||
args = append(args, s)
|
||||
}
|
||||
}
|
||||
if v, ok := req.Filters["code_batch_id_eq"]; ok {
|
||||
s := toString(v)
|
||||
if s != "" {
|
||||
where = append(where, "`order`.code_batch_id = ?")
|
||||
args = append(args, s)
|
||||
}
|
||||
}
|
||||
if v, ok := req.Filters["order_cash_cash_activity_id_eq"]; ok {
|
||||
s := toString(v)
|
||||
if s != "" {
|
||||
where = append(where, "`order_cash`.cash_activity_id = ?")
|
||||
args = append(args, s)
|
||||
}
|
||||
}
|
||||
if v, ok := req.Filters["order_voucher_channel_activity_id_eq"]; ok {
|
||||
s := toString(v)
|
||||
if s != "" {
|
||||
where = append(where, "`order_voucher`.channel_activity_id = ?")
|
||||
args = append(args, s)
|
||||
}
|
||||
}
|
||||
if v, ok := req.Filters["voucher_batch_channel_activity_id_eq"]; ok {
|
||||
s := toString(v)
|
||||
if s != "" {
|
||||
where = append(where, "`voucher_batch`.channel_activity_id = ?")
|
||||
args = append(args, s)
|
||||
}
|
||||
}
|
||||
if v, ok := req.Filters["merchant_out_biz_no_eq"]; ok {
|
||||
s := toString(v)
|
||||
if s != "" {
|
||||
where = append(where, "`merchant_key_send`.out_biz_no = ?")
|
||||
args = append(args, s)
|
||||
}
|
||||
}
|
||||
if tv == 1 || tv == 2 || tv == 3 {
|
||||
if req.MainTable == "order_info" {
|
||||
where = append(where, "`order_info`.type = ?")
|
||||
} else {
|
||||
where = append(where, "`order`.type = ?")
|
||||
}
|
||||
args = append(args, tv)
|
||||
}
|
||||
}
|
||||
if v, ok := req.Filters["out_trade_no_eq"]; ok {
|
||||
s := toString(v)
|
||||
if s != "" {
|
||||
if req.MainTable == "order_info" {
|
||||
where = append(where, "`order_info`.out_order_no = ?")
|
||||
} else {
|
||||
where = append(where, "`order`.out_trade_no = ?")
|
||||
}
|
||||
args = append(args, s)
|
||||
}
|
||||
}
|
||||
if v, ok := req.Filters["account_eq"]; ok {
|
||||
s := toString(v)
|
||||
if s != "" {
|
||||
if req.MainTable == "order_info" {
|
||||
where = append(where, "`order_info`.account = ?")
|
||||
} else {
|
||||
where = append(where, "`order`.account = ?")
|
||||
}
|
||||
args = append(args, s)
|
||||
}
|
||||
}
|
||||
if v, ok := req.Filters["plan_id_eq"]; ok {
|
||||
s := toString(v)
|
||||
if s != "" {
|
||||
if req.MainTable == "order_info" {
|
||||
where = append(where, "`order_info`.activity_id = ?")
|
||||
} else {
|
||||
where = append(where, "`order`.plan_id = ?")
|
||||
}
|
||||
args = append(args, s)
|
||||
}
|
||||
}
|
||||
if v, ok := req.Filters["key_batch_id_eq"]; ok {
|
||||
s := toString(v)
|
||||
if s != "" {
|
||||
if req.MainTable == "order_info" {
|
||||
where = append(where, "`order_info`.key_batch_name = ?")
|
||||
} else {
|
||||
where = append(where, "`order`.key_batch_id = ?")
|
||||
}
|
||||
args = append(args, s)
|
||||
}
|
||||
}
|
||||
if v, ok := req.Filters["product_id_eq"]; ok {
|
||||
s := toString(v)
|
||||
if s != "" {
|
||||
if req.MainTable == "order_info" {
|
||||
where = append(where, "`order_info`.goods_id = ?")
|
||||
} else {
|
||||
where = append(where, "`order`.product_id = ?")
|
||||
}
|
||||
args = append(args, s)
|
||||
}
|
||||
}
|
||||
if v, ok := req.Filters["reseller_id_eq"]; ok {
|
||||
s := toString(v)
|
||||
if s != "" {
|
||||
if req.MainTable == "order_info" {
|
||||
where = append(where, "`order_info`.merchant_id = ?")
|
||||
} else {
|
||||
where = append(where, "`order`.reseller_id = ?")
|
||||
}
|
||||
args = append(args, s)
|
||||
}
|
||||
}
|
||||
if v, ok := req.Filters["code_batch_id_eq"]; ok {
|
||||
s := toString(v)
|
||||
if s != "" {
|
||||
if req.MainTable == "order_info" {
|
||||
where = append(where, "`order_info`.supplier_product_id = ?")
|
||||
} else {
|
||||
where = append(where, "`order`.code_batch_id = ?")
|
||||
}
|
||||
args = append(args, s)
|
||||
}
|
||||
}
|
||||
if v, ok := req.Filters["order_cash_cash_activity_id_eq"]; ok {
|
||||
s := toString(v)
|
||||
if s != "" {
|
||||
if req.MainTable == "order_info" {
|
||||
where = append(where, "`order_cash`.activity_id = ?")
|
||||
} else {
|
||||
where = append(where, "`order_cash`.cash_activity_id = ?")
|
||||
}
|
||||
args = append(args, s)
|
||||
}
|
||||
}
|
||||
if v, ok := req.Filters["order_voucher_channel_activity_id_eq"]; ok {
|
||||
s := toString(v)
|
||||
if s != "" {
|
||||
if req.MainTable == "order_info" {
|
||||
where = append(where, "`order_voucher`.channel_batch_no = ?")
|
||||
} else {
|
||||
where = append(where, "`order_voucher`.channel_activity_id = ?")
|
||||
}
|
||||
args = append(args, s)
|
||||
}
|
||||
}
|
||||
if v, ok := req.Filters["voucher_batch_channel_activity_id_eq"]; ok {
|
||||
s := toString(v)
|
||||
if s != "" {
|
||||
if req.MainTable == "order" { // only marketing schema has voucher_batch
|
||||
where = append(where, "`voucher_batch`.channel_activity_id = ?")
|
||||
args = append(args, s)
|
||||
}
|
||||
}
|
||||
}
|
||||
if v, ok := req.Filters["merchant_out_biz_no_eq"]; ok {
|
||||
s := toString(v)
|
||||
if s != "" {
|
||||
if req.MainTable == "order" { // marketing only
|
||||
where = append(where, "`merchant_key_send`.out_biz_no = ?")
|
||||
}
|
||||
args = append(args, s)
|
||||
}
|
||||
}
|
||||
if len(where) > 0 {
|
||||
sb.WriteString(" WHERE ")
|
||||
sb.WriteString(strings.Join(where, " AND "))
|
||||
|
|
|
|||
|
|
@ -374,3 +374,8 @@ job_id=47 sql=UPDATE export_jobs SET status=?, started_at=? WHERE id= ? args=[ru
|
|||
{"bytes":77,"duration_ms":16,"kind":"access","level":"INFO","method":"","path":"","query":"","remote":"","status":200,"trace_id":"","ts":"2025-11-26T17:54:11+08:00"}
|
||||
{"bytes":1614,"duration_ms":16,"kind":"access","level":"INFO","method":"","path":"","query":"","remote":"","status":200,"trace_id":"","ts":"2025-11-26T17:54:11+08:00"}
|
||||
{"bytes":1040,"duration_ms":51,"kind":"access","level":"INFO","method":"","path":"","query":"","remote":"","status":200,"trace_id":"","ts":"2025-11-26T17:54:16+08:00"}
|
||||
{"bytes":1040,"duration_ms":55,"kind":"access","level":"INFO","method":"","path":"","query":"","remote":"","status":200,"trace_id":"","ts":"2025-11-26T18:12:45+08:00"}
|
||||
{"bytes":914,"duration_ms":108,"kind":"access","level":"INFO","method":"","path":"","query":"","remote":"","status":200,"trace_id":"","ts":"2025-11-26T18:12:48+08:00"}
|
||||
{"bytes":1614,"duration_ms":10,"kind":"access","level":"INFO","method":"","path":"","query":"","remote":"","status":200,"trace_id":"","ts":"2025-11-26T18:12:48+08:00"}
|
||||
{"bytes":914,"duration_ms":107,"kind":"access","level":"INFO","method":"","path":"","query":"","remote":"","status":200,"trace_id":"","ts":"2025-11-26T18:12:51+08:00"}
|
||||
{"bytes":1040,"duration_ms":51,"kind":"access","level":"INFO","method":"","path":"","query":"","remote":"","status":200,"trace_id":"","ts":"2025-11-26T18:15:41+08:00"}
|
||||
|
|
|
|||
Loading…
Reference in New Issue