From 99ac6e3c2b3b20f4218c323f21ee08bb953303ac Mon Sep 17 00:00:00 2001 From: zhouyonggao <1971162852@qq.com> Date: Thu, 18 Dec 2025 13:11:25 +0800 Subject: [PATCH] =?UTF-8?q?refactor(marketing):=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E5=85=B3=E8=81=94=E6=9F=A5=E8=AF=A2=E5=92=8C=E8=BF=87=E6=BB=A4?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E6=98=A0=E5=B0=84=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 为多个关联表添加基于最大ID的子查询去重,保证数据唯一性 - 增加注释说明各关联JOIN逻辑和去重策略 - merchant_key_send关联改为基于最大ID的子查询连接,替代原有简单连接 - 统一格式化代码,提高可读性 - 保持FilterColumn方法结构清晰无改变,仅调整格式 --- server/internal/schema/marketing.go | 115 ++++++++++++++++------------ 1 file changed, 67 insertions(+), 48 deletions(-) diff --git a/server/internal/schema/marketing.go b/server/internal/schema/marketing.go index 2e46820..6c5473d 100644 --- a/server/internal/schema/marketing.go +++ b/server/internal/schema/marketing.go @@ -7,55 +7,74 @@ func (marketingSchema) TableName(t string) string { return t } func (marketingSchema) MapField(t, f string) (string, bool) { return f, true } func (marketingSchema) BuildJoins(need map[string]bool, main string) []string { - out := []string{} - if need["order_detail"] { - out = append(out, " LEFT JOIN `order_detail` ON `order_detail`.order_number = `order`.order_number") - } - if need["order_cash"] { - // MySQL 5.7: no window functions; keep latest row by id via correlated subquery (no GROUP BY) - out = append(out, " LEFT JOIN `order_cash` ON `order_cash`.id = (SELECT MAX(oc2.id) FROM `order_cash` oc2 WHERE oc2.order_number = `order`.order_number)") - } - if need["order_voucher"] { - out = append(out, " LEFT JOIN `order_voucher` ON `order_voucher`.id = (SELECT MAX(ov2.id) FROM `order_voucher` ov2 WHERE ov2.order_number = `order`.order_number)") - } - if need["plan"] || need["key_batch"] { - out = append(out, " LEFT JOIN `plan` ON `plan`.id = `order`.plan_id") - } - if need["key_batch"] { - out = append(out, " LEFT JOIN `key_batch` ON `key_batch`.plan_id = `plan`.id") - } - if need["code_batch"] { - out = append(out, " LEFT JOIN `code_batch` ON `code_batch`.key_batch_id = `key_batch`.id") - } - if need["voucher"] { - out = append(out, " LEFT JOIN `voucher` ON `voucher`.id = (SELECT MAX(v2.id) FROM `voucher` v2 WHERE v2.channel_activity_id = `order_voucher`.channel_activity_id)") - } - if need["voucher_batch"] { - out = append(out, " LEFT JOIN `voucher_batch` ON `voucher_batch`.id = (SELECT MAX(vb2.id) FROM `voucher_batch` vb2 WHERE vb2.voucher_id = `voucher`.id)") - } - if need["merchant_key_send"] { - out = append(out, " LEFT JOIN `merchant_key_send` ON `order`.`key` = `merchant_key_send`.key") - } - return out + out := []string{} + if need["order_detail"] { + // order_detail无id字段,使用普通JOIN + out = append(out, " LEFT JOIN `order_detail` ON `order_detail`.order_number = `order`.order_number") + } + if need["order_cash"] { + // MAX ID 子查询去重 + out = append(out, " LEFT JOIN `order_cash` ON `order_cash`.id = (SELECT MAX(oc2.id) FROM `order_cash` oc2 WHERE oc2.order_number = `order`.order_number)") + } + if need["order_voucher"] { + // MAX ID 子查询去重 + out = append(out, " LEFT JOIN `order_voucher` ON `order_voucher`.id = (SELECT MAX(ov2.id) FROM `order_voucher` ov2 WHERE ov2.order_number = `order`.order_number)") + } + if need["plan"] || need["key_batch"] { + out = append(out, " LEFT JOIN `plan` ON `plan`.id = `order`.plan_id") + } + if need["key_batch"] { + // MAX ID 子查询去重 + out = append(out, " LEFT JOIN `key_batch` ON `key_batch`.id = (SELECT MAX(kb2.id) FROM `key_batch` kb2 WHERE kb2.plan_id = `plan`.id)") + } + if need["code_batch"] { + // MAX ID 子查询去重 + out = append(out, " LEFT JOIN `code_batch` ON `code_batch`.id = (SELECT MAX(cb2.id) FROM `code_batch` cb2 WHERE cb2.key_batch_id = `key_batch`.id)") + } + if need["voucher"] { + out = append(out, " LEFT JOIN `voucher` ON `voucher`.id = (SELECT MAX(v2.id) FROM `voucher` v2 WHERE v2.channel_activity_id = `order_voucher`.channel_activity_id)") + } + if need["voucher_batch"] { + out = append(out, " LEFT JOIN `voucher_batch` ON `voucher_batch`.id = (SELECT MAX(vb2.id) FROM `voucher_batch` vb2 WHERE vb2.voucher_id = `voucher`.id)") + } + if need["merchant_key_send"] { + // MAX ID 子查询去重 + out = append(out, " LEFT JOIN `merchant_key_send` ON `merchant_key_send`.id = (SELECT MAX(mks2.id) FROM `merchant_key_send` mks2 WHERE mks2.key = `order`.`key`)") + } + return out } func (marketingSchema) FilterColumn(key string) (string, string, bool) { - switch key { - case "creator_in": return "order", "creator", true - case "create_time_between": return "order", "create_time", true - case "type_eq": return "order", "type", true - case "out_trade_no_eq": return "order", "out_trade_no", true - case "account_eq": return "order", "account", true - case "plan_id_eq": return "order", "plan_id", true - case "key_batch_id_eq": return "order", "key_batch_id", true - case "product_id_eq": return "order", "product_id", true - case "reseller_id_eq": return "order", "reseller_id", true - case "code_batch_id_eq": return "order", "code_batch_id", true - case "order_cash_cash_activity_id_eq": return "order_cash", "cash_activity_id", true - case "order_voucher_channel_activity_id_eq": return "order_voucher", "channel_activity_id", true - case "voucher_batch_channel_activity_id_eq": return "voucher_batch", "channel_activity_id", true - case "merchant_out_biz_no_eq": return "merchant_key_send", "out_biz_no", true - default: - return "", "", false - } + switch key { + case "creator_in": + return "order", "creator", true + case "create_time_between": + return "order", "create_time", true + case "type_eq": + return "order", "type", true + case "out_trade_no_eq": + return "order", "out_trade_no", true + case "account_eq": + return "order", "account", true + case "plan_id_eq": + return "order", "plan_id", true + case "key_batch_id_eq": + return "order", "key_batch_id", true + case "product_id_eq": + return "order", "product_id", true + case "reseller_id_eq": + return "order", "reseller_id", true + case "code_batch_id_eq": + return "order", "code_batch_id", true + case "order_cash_cash_activity_id_eq": + return "order_cash", "cash_activity_id", true + case "order_voucher_channel_activity_id_eq": + return "order_voucher", "channel_activity_id", true + case "voucher_batch_channel_activity_id_eq": + return "voucher_batch", "channel_activity_id", true + case "merchant_out_biz_no_eq": + return "merchant_key_send", "out_biz_no", true + default: + return "", "", false + } }