package api import ( "database/sql" "net/http" "sort" ) func MetadataHandler(meta, marketing, ymt *sql.DB) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { ds := r.URL.Query().Get("datasource") ot := r.URL.Query().Get("order_type") db := marketing if ds == "ymt" { db = ymt } // 从代码中获取隐藏字段列表 hiddenFields := getHiddenFieldsFromCode(ds) tables := []string{} if ds == "ymt" { tables = []string{"order_info", "order_cash", "order_voucher", "order_digit", "goods_voucher_batch", "goods_voucher_subject_config", "merchant", "activity"} } else { tables = []string{"order", "order_detail", "order_cash", "order_voucher", "plan", "key_batch", "code_batch", "voucher", "voucher_batch", "merchant_key_send"} } out := []map[string]interface{}{} for _, tbl := range tables { cols := getColumns(db, tbl) fields := []map[string]string{} for _, c := range cols { tCanonical, fCanonical := canonicalField(ds, tbl, c.Name) if tCanonical == "" || fCanonical == "" { continue } // 检查字段是否在隐藏列表中 if isFieldHidden(hiddenFields, tCanonical, fCanonical) { continue } lab := c.Comment if lab == "" { lab = fCanonical } fields = append(fields, map[string]string{"key": tCanonical + "." + fCanonical, "field": fCanonical, "label": lab}) } tDisplay := displayTable(ds, tbl) out = append(out, map[string]interface{}{"table": tDisplay, "label": tableLabel(tDisplay), "fields": fields}) } sort.Slice(out, func(i, j int) bool { return out[i]["table"].(string) < out[j]["table"].(string) }) rec := recommendedDefaults(ds, ot) ok(w, r, map[string]interface{}{"datasource": ds, "tables": out, "recommended": rec}) }) } // getHiddenFieldsFromCode 从代码中获取指定数据源的隐藏字段映射 // 返回 map[table]map[field]bool,标记哪些字段需要隐藏 // // 所有表的字段列表(基于 schema/fields.go): // // Marketing 数据源表字段: // - order: order_number, key, creator, out_trade_no, type, status, account, product_id, reseller_id, plan_id, // key_batch_id, code_batch_id, pay_type, pay_status, use_coupon, deliver_status, expire_time, // recharge_time, contract_price, num, total, pay_amount, create_time, update_time, card_code, // official_price, merchant_name, activity_name, goods_name, pay_time, coupon_id, discount_amount, // supplier_product_name, is_inner, icon, cost_price, success_num, is_reset, is_retry, channel, // is_store, trace_id, out_order_no, next_retry_time, recharge_suc_time, supplier_id, // supplier_product_id, merchant_id, goods_id, activity_id, key_batch_name // 隐藏字段: id, order_id, key, creator_id, plan_id, product_id, reseller_id, supplier_id, // supplier_product_id, key_batch_id, is_internal_supplier_order // - order_detail: plan_title, order_number, reseller_name, product_name, show_url, official_price, // cost_price, create_time, update_time // - order_cash: order_no, trade_no, wechat_detail_id, channel, denomination, account, receive_name, // app_id, cash_activity_id, receive_status, receive_time, success_time, cash_packet_id, // channel_order_id, pay_fund_order_id, cash_id, amount, activity_id, goods_id, merchant_id, // supplier_id, user_id, status, expire_time, create_time, update_time, version, is_confirm // - order_voucher: channel, channel_activity_id, channel_voucher_id, status, receive_mode, grant_time, // usage_time, refund_time, status_modify_time, overdue_time, refund_amount, official_price, // out_biz_no, account_no // - plan: id, title, status, begin_time, end_time // - key_batch: id, batch_name, bind_object, quantity, stock, begin_time, end_time // - code_batch: id, title, status, begin_time, end_time, quantity, usage, stock // - voucher: channel, channel_activity_id, price, balance, used_amount, denomination // - voucher_batch: channel_activity_id, temp_no, provider, weight // - merchant_key_send: merchant_id, out_biz_no, key, status, usage_time, create_time // // YMT 数据源表字段: // - order (order_info): order_number, key, creator, out_trade_no, type, status, account, product_id, // reseller_id, plan_id, key_batch_id, code_batch_id, pay_type, pay_status, // use_coupon, deliver_status, expire_time, recharge_time, contract_price, num, // pay_amount, create_time, update_time, card_code, official_price, merchant_name, // activity_name, goods_name, pay_time, coupon_id, discount_amount, // supplier_product_name, is_inner, icon, cost_price, success_num, is_reset, // is_retry, channel, is_store, trace_id, out_order_no, next_retry_time, // recharge_suc_time, supplier_id, supplier_product_id, merchant_id, goods_id, // activity_id, key_batch_name // 隐藏字段: id, order_id, key, creator_id, plan_id, product_id, reseller_id, supplier_id, // supplier_product_id, key_batch_id, is_internal_supplier_order // - order_cash: order_no, trade_no, wechat_detail_id, channel, denomination, account, receive_name, // app_id, cash_activity_id, receive_status, receive_time, success_time, cash_packet_id, // channel_order_id, pay_fund_order_id, cash_id, amount, activity_id, goods_id, merchant_id, // supplier_id, user_id, status, expire_time, create_time, update_time, version, is_confirm // - order_voucher: channel, channel_activity_id, channel_voucher_id, status, receive_mode, grant_time, // usage_time, refund_time, status_modify_time, overdue_time, refund_amount, official_price, // out_biz_no, account_no // - order_digit: order_no, card_no, account, goods_id, merchant_id, supplier_id, activity_id, user_id, // success_time, supplier_product_no, order_type, end_time, create_time, update_time, code, // sms_channel // - goods_voucher_batch: channel_batch_no, voucher_subject_id, id, goods_voucher_id, supplier_id, // temp_no, index, create_time, update_time // - goods_voucher_subject_config: id, name, type, create_time // - merchant: id, name, user_id, merchant_no, subject, third_party, status, balance, total_consumption, // contact_name, contact_phone, contact_email, create_time, update_time // - activity: id, name, user_id, merchant_id, user_name, activity_no, status, key_total_num, // key_generate_num, key_usable_num, domain_url, theme_login_id, theme_list_id, // theme_verify_id, settlement_type, key_expire_type, key_valid_day, key_begin_time, // key_end_time, key_style, begin_time, end_time, is_retry, create_time, update_time, // discard_time, delete_time, auto_charge, stock, approval_trade_no, amount, channels, // key_begin, key_end, key_unit, key_pay_button_text, goods_pay_button_text, // is_open_db_transaction func getHiddenFieldsFromCode(ds string) map[string]map[string]bool { result := make(map[string]map[string]bool) if ds == "ymt" { // YMT 数据源的隐藏字段配置 - 所有字段默认隐藏(true) // order 表所有字段 result["order"] = map[string]bool{ "order_number": true, "key": true, "creator": false, "out_trade_no": true, "type": true, "status": true, "account": true, "product_id": false, "reseller_id": false, "plan_id": false, "key_batch_id": false, "code_batch_id": false, "pay_type": true, "pay_status": true, "use_coupon": true, "deliver_status": true, "expire_time": true, "recharge_time": true, "contract_price": true, "num": true, "pay_amount": true, "create_time": true, "update_time": true, "card_code": true, "official_price": true, "merchant_name": true, "activity_name": true, "goods_name": true, "pay_time": true, "coupon_id": true, "discount_amount": true, "supplier_product_name": true, "is_inner": false, "icon": true, "cost_price": true, "success_num": true, "is_reset": false, "is_retry": false, "channel": true, "is_store": false, "trace_id": false, "out_order_no": true, "next_retry_time": true, "recharge_suc_time": true, "supplier_id": false, "supplier_product_id": false, "merchant_id": false, "goods_id": false, "activity_id": false, "key_batch_name": true, "id": false, "order_id": false, "creator_id": false, "is_internal_supplier_order": false, } // order_cash 表所有字段 result["order_cash"] = map[string]bool{ "order_no": true, "trade_no": true, "wechat_detail_id": false, "channel": true, "denomination": true, "account": true, "receive_name": true, "app_id": true, "cash_activity_id": true, "receive_status": true, "receive_time": true, "success_time": true, "cash_packet_id": false, "channel_order_id": false, "pay_fund_order_id": false, "cash_id": true, "amount": true, "activity_id": false, "goods_id": false, "merchant_id": false, "supplier_id": false, "user_id": false, "status": true, "expire_time": true, "create_time": true, "update_time": false, "version": false, "is_confirm": true, } // order_voucher 表所有字段 result["order_voucher"] = map[string]bool{ "channel": true, "channel_activity_id": true, "channel_voucher_id": true, "status": true, "receive_mode": true, "grant_time": true, "usage_time": true, "refund_time": true, "status_modify_time": true, "overdue_time": true, "refund_amount": true, "official_price": true, "out_biz_no": true, "account_no": true, } // order_digit 表所有字段 result["order_digit"] = map[string]bool{ "order_no": true, "card_no": true, "account": true, "goods_id": false, "merchant_id": false, "supplier_id": false, "activity_id": false, "user_id": false, "success_time": true, "supplier_product_no": true, "order_type": true, "end_time": true, "create_time": true, "update_time": true, "code": false, "sms_channel": false, } // goods_voucher_batch 表所有字段 result["goods_voucher_batch"] = map[string]bool{ "channel_batch_no": true, "voucher_subject_id": true, "id": false, "goods_voucher_id": false, "supplier_id": false, "temp_no": true, "index": true, "create_time": false, "update_time": false, } // goods_voucher_subject_config 表所有字段 result["goods_voucher_subject_config"] = map[string]bool{ "id": true, "name": true, "type": true, "create_time": true, } // merchant 表所有字段 result["merchant"] = map[string]bool{ "id": false, "name": true, "user_id": false, "merchant_no": true, "subject": true, "third_party": false, "status": false, "balance": false, "total_consumption": false, "contact_name": true, "contact_phone": false, "contact_email": false, "create_time": false, "update_time": false, } // activity 表所有字段 result["activity"] = map[string]bool{ "id": false, "name": true, "user_id": false, "merchant_id": false, "user_name": true, "activity_no": true, "status": true, "key_total_num": true, "key_generate_num": true, "key_usable_num": true, "domain_url": false, "theme_login_id": false, "theme_list_id": false, "theme_verify_id": false, "settlement_type": true, "key_expire_type": true, "key_valid_day": true, "key_begin_time": true, "key_end_time": true, "key_style": true, "begin_time": true, "end_time": true, "is_retry": false, "create_time": false, "update_time": false, "discard_time": false, "delete_time": false, "auto_charge": true, "stock": true, "approval_trade_no": false, "amount": true, "channels": true, "key_begin": true, "key_end": true, "key_unit": false, "key_pay_button_text": false, "goods_pay_button_text": false, "is_open_db_transaction": false, } } else { // Marketing 数据源的隐藏字段配置 - 所有字段默认隐藏(true) // order 表所有字段 result["order"] = map[string]bool{ "order_number": true, "key": true, "creator": true, "out_trade_no": true, "type": true, "status": true, "account": true, "product_id": false, "reseller_id": false, "plan_id": false, "key_batch_id": false, "code_batch_id": false, "pay_type": true, "pay_status": true, "use_coupon": true, "deliver_status": true, "expire_time": true, "recharge_time": true, "contract_price": true, "num": true, "total": true, "pay_amount": true, "create_time": true, "update_time": true, "card_code": true, "official_price": true, "merchant_name": true, "activity_name": true, "goods_name": true, "pay_time": true, "coupon_id": false, "discount_amount": true, "supplier_product_name": true, "is_inner": false, "icon": false, "cost_price": true, "success_num": true, "is_reset": false, "is_retry": false, "channel": true, "is_store": false, "trace_id": false, "out_order_no": true, "next_retry_time": true, "recharge_suc_time": true, "supplier_id": true, "supplier_product_id": false, "merchant_id": false, "goods_id": false, "activity_id": false, "key_batch_name": true, "id": false, "order_id": false, "creator_id": false, "is_internal_supplier_order": false, } // order_detail 表所有字段 result["order_detail"] = map[string]bool{ "plan_title": true, "order_number": true, "reseller_name": true, "product_name": true, "show_url": false, "official_price": true, "cost_price": true, "create_time": false, "update_time": false, } // order_cash 表所有字段 result["order_cash"] = map[string]bool{ "order_no": true, "trade_no": true, "wechat_detail_id": false, "channel": true, "denomination": true, "account": true, "receive_name": true, "app_id": true, "cash_activity_id": false, "receive_status": true, "receive_time": true, "success_time": true, "cash_packet_id": true, "channel_order_id": false, "pay_fund_order_id": false, "cash_id": false, "amount": true, "activity_id": false, "goods_id": false, "merchant_id": false, "supplier_id": false, "user_id": false, "status": true, "expire_time": true, "create_time": true, "update_time": true, "version": false, "is_confirm": true, } // order_voucher 表所有字段 result["order_voucher"] = map[string]bool{ "channel": true, "channel_activity_id": false, "channel_voucher_id": false, "status": true, "receive_mode": true, "grant_time": true, "usage_time": true, "refund_time": true, "status_modify_time": true, "overdue_time": true, "refund_amount": true, "official_price": true, "out_biz_no": true, "account_no": true, } // plan 表所有字段 result["plan"] = map[string]bool{ "id": false, "title": true, "status": true, "begin_time": true, "end_time": true, } // key_batch 表所有字段 result["key_batch"] = map[string]bool{ "id": false, "batch_name": true, "bind_object": true, "quantity": true, "stock": true, "begin_time": true, "end_time": true, } // code_batch 表所有字段 result["code_batch"] = map[string]bool{ "id": false, "title": true, "status": true, "begin_time": true, "end_time": true, "quantity": true, "usage": true, "stock": true, } // voucher 表所有字段 result["voucher"] = map[string]bool{ "channel": true, "channel_activity_id": false, "price": true, "balance": true, "used_amount": true, "denomination": true, } // voucher_batch 表所有字段 result["voucher_batch"] = map[string]bool{ "channel_activity_id": true, "temp_no": true, "provider": true, "weight": true, } // merchant_key_send 表所有字段 result["merchant_key_send"] = map[string]bool{ "merchant_id": true, "out_biz_no": true, "key": true, "status": true, "usage_time": true, "create_time": true, } } return result } // isFieldHidden 检查字段是否在隐藏列表中 func isFieldHidden(hiddenFields map[string]map[string]bool, table, field string) bool { tableFields, ok := hiddenFields[table] if !ok { return false } return tableFields[field] } func tableLabel(t string) string { switch t { case "order": return "订单主表" case "order_detail": return "订单详情" case "order_cash": return "红包订单" case "order_voucher": return "立减金订单" case "order_digit": return "直充卡密订单" case "plan": return "活动" case "key_batch": return "key批次" case "code_batch": return "兑换码批次" case "voucher": return "立减金" case "voucher_batch": return "立减金批次" case "merchant_key_send": return "key码API发放记录" case "goods_voucher_batch": return "立减金批次表" case "goods_voucher_subject_config": return "立减金主体" case "merchant": return "客户" case "activity": return "活动" default: return t } } func displayTable(ds, tbl string) string { if ds == "ymt" && tbl == "order_info" { return "order" } return tbl } func canonicalField(ds, tbl, col string) (string, string) { if ds == "ymt" && tbl == "order_info" { switch col { case "order_no": return "order", "order_number" case "key_code": return "order", "key" case "user_id": return "order", "creator" case "out_order_no": return "order", "out_trade_no" case "activity_id": return "order", "plan_id" case "merchant_id": return "order", "reseller_id" case "goods_id": return "order", "product_id" case "pay_price": return "order", "pay_amount" case "key_batch_name": return "order", "key_batch_id" default: return "order", col } } // other tables: canonical equals actual return tbl, col } type columnMeta struct { Name string Comment string } func getColumns(db *sql.DB, tbl string) []columnMeta { rows, err := db.Query("SELECT COLUMN_NAME, COLUMN_COMMENT FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = ? ORDER BY ORDINAL_POSITION", tbl) if err != nil { return []columnMeta{} } defer rows.Close() cols := []columnMeta{} for rows.Next() { var name, comment string if err := rows.Scan(&name, &comment); err == nil { cols = append(cols, columnMeta{Name: name, Comment: comment}) } } return cols } func recommendedDefaults(ds, orderType string) []string { base := []string{"order.order_number", "order.creator", "order.out_trade_no", "order.type", "order.status", "order.contract_price", "order.num", "order.pay_amount", "order.create_time"} if ds != "ymt" { base = []string{"order.order_number", "order.creator", "order.out_trade_no", "order.type", "order.status", "order.contract_price", "order.num", "order.total", "order.pay_amount", "order.create_time"} } t := orderType if t == "2" { // 直充卡密 if ds == "ymt" { base = append(base, "order_digit.order_no", "order_digit.account", "order_digit.success_time") } else { base = append(base, "plan.title") } } else if t == "3" { // 立减金 if ds == "ymt" { base = append(base, "order_voucher.channel", "order_voucher.status", "goods_voucher_batch.channel_batch_no") } else { base = append(base, "order_voucher.channel", "voucher.denomination") } } else if t == "1" { // 红包 if ds == "ymt" { base = append(base, "order_cash.channel", "order_cash.receive_status", "order_cash.denomination") } else { base = append(base, "order_cash.channel", "order_cash.receive_status", "order_cash.amount") } } return base }