diff --git a/server/internal/api/creators.go b/server/internal/api/creators.go new file mode 100644 index 0000000..b986a16 --- /dev/null +++ b/server/internal/api/creators.go @@ -0,0 +1,83 @@ +package api + +import ( + "database/sql" + "net/http" + "strconv" + "strings" +) + +type CreatorsAPI struct { + marketing *sql.DB +} + +func CreatorsHandler(marketing *sql.DB) http.Handler { + api := &CreatorsAPI{marketing: marketing} + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + p := strings.TrimPrefix(r.URL.Path, "/api/creators") + if r.Method == http.MethodGet && p == "" { + api.list(w, r) + return + } + w.WriteHeader(http.StatusNotFound) + }) +} + +func (a *CreatorsAPI) list(w http.ResponseWriter, r *http.Request) { + q := r.URL.Query().Get("q") + limitStr := r.URL.Query().Get("limit") + limit := 2000 + if limitStr != "" { + if n, err := strconv.Atoi(limitStr); err == nil && n > 0 && n <= 10000 { limit = n } + } + // Try plan table first (creator, creator_name) + sql1 := "SELECT DISTINCT creator, COALESCE(creator_name, '') AS name FROM plan WHERE creator IS NOT NULL" + args := []interface{}{} + if q != "" { + sql1 += " AND (CAST(creator AS CHAR) LIKE ? OR creator_name LIKE ?)" + like := "%" + q + "%" + args = append(args, like, like) + } + sql1 += " ORDER BY creator ASC LIMIT ?" + args = append(args, limit) + rows, err := a.marketing.Query(sql1, args...) + out := []map[string]interface{}{} + if err == nil { + defer rows.Close() + for rows.Next() { + var id sql.NullInt64 + var name sql.NullString + if err := rows.Scan(&id, &name); err != nil { continue } + if !id.Valid { continue } + m := map[string]interface{}{"id": id.Int64, "name": name.String} + out = append(out, m) + } + } + // Fallback to order table if empty or error + if err != nil || len(out) == 0 { + sql2 := "SELECT DISTINCT creator, '' AS name FROM `order` WHERE creator IS NOT NULL" + args2 := []interface{}{} + if q != "" { + sql2 += " AND CAST(creator AS CHAR) LIKE ?" + args2 = append(args2, "%"+q+"%") + } + sql2 += " ORDER BY creator ASC LIMIT ?" + args2 = append(args2, limit) + rows2, err2 := a.marketing.Query(sql2, args2...) + if err2 != nil { + fail(w, r, http.StatusInternalServerError, err2.Error()) + return + } + defer rows2.Close() + out = out[:0] + for rows2.Next() { + var id sql.NullInt64 + var name sql.NullString + if err := rows2.Scan(&id, &name); err != nil { continue } + if !id.Valid { continue } + m := map[string]interface{}{"id": id.Int64, "name": name.String} + out = append(out, m) + } + } + ok(w, r, out) +} diff --git a/server/internal/api/router.go b/server/internal/api/router.go index 1397eed..65e12c8 100644 --- a/server/internal/api/router.go +++ b/server/internal/api/router.go @@ -12,6 +12,8 @@ func NewRouter(metaDB *sql.DB, marketingDB *sql.DB) http.Handler { mux.Handle("/api/templates/", withAccess(withTrace(TemplatesHandler(metaDB, marketingDB)))) mux.Handle("/api/exports", withAccess(withTrace(ExportsHandler(metaDB, marketingDB)))) mux.Handle("/api/exports/", withAccess(withTrace(ExportsHandler(metaDB, marketingDB)))) + mux.Handle("/api/creators", withAccess(withTrace(CreatorsHandler(marketingDB)))) + mux.Handle("/api/creators/", withAccess(withTrace(CreatorsHandler(marketingDB)))) sd := staticDir() mux.Handle("/", http.FileServer(http.Dir(sd))) return mux diff --git a/server/internal/exporter/sqlbuilder.go b/server/internal/exporter/sqlbuilder.go index 8bed3a7..60e1b52 100644 --- a/server/internal/exporter/sqlbuilder.go +++ b/server/internal/exporter/sqlbuilder.go @@ -123,6 +123,10 @@ func BuildSQL(req BuildRequest, whitelist map[string]bool) (string, []interface{ 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) } diff --git a/server/log/server-20251125.log b/server/log/server-20251125.log index 12aa0f7..a2a21e1 100644 --- a/server/log/server-20251125.log +++ b/server/log/server-20251125.log @@ -115,3 +115,35 @@ server listening on :8077 {"bytes":1363,"duration_ms":121,"kind":"access","level":"INFO","method":"","path":"","query":"","remote":"","status":200,"trace_id":"","ts":"2025-11-25T14:18:40+08:00"} {"bytes":388,"duration_ms":57,"kind":"access","level":"INFO","method":"","path":"","query":"","remote":"","status":200,"trace_id":"","ts":"2025-11-25T14:18:54+08:00"} {"bytes":1363,"duration_ms":105,"kind":"access","level":"INFO","method":"","path":"","query":"","remote":"","status":200,"trace_id":"","ts":"2025-11-25T14:18:55+08:00"} +trace_id=c37b35f4c4a8303ebe0a132356e46490 sql=INSERT INTO export_templates (name, datasource, main_table, fields_json, filters_json, file_format, visibility, owner_id, enabled, stats_enabled, last_validated_at, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?) args=[测试2 marketing order [91 34 111 114 100 101 114 46 111 114 100 101 114 95 110 117 109 98 101 114 34 44 34 111 114 100 101 114 46 99 114 101 97 116 111 114 34 44 34 111 114 100 101 114 46 111 117 116 95 116 114 97 100 101 95 110 111 34 44 34 111 114 100 101 114 46 116 121 112 101 34 44 34 111 114 100 101 114 46 115 116 97 116 117 115 34 44 34 111 114 100 101 114 46 99 111 110 116 114 97 99 116 95 112 114 105 99 101 34 44 34 111 114 100 101 114 46 110 117 109 34 44 34 111 114 100 101 114 46 116 111 116 97 108 34 44 34 111 114 100 101 114 46 112 97 121 95 97 109 111 117 110 116 34 44 34 111 114 100 101 114 46 99 114 101 97 116 101 95 116 105 109 101 34 44 34 111 114 100 101 114 46 117 112 100 97 116 101 95 116 105 109 101 34 44 34 111 114 100 101 114 95 100 101 116 97 105 108 46 112 108 97 110 95 116 105 116 108 101 34 44 34 111 114 100 101 114 95 100 101 116 97 105 108 46 114 101 115 101 108 108 101 114 95 110 97 109 101 34 44 34 111 114 100 101 114 95 100 101 116 97 105 108 46 112 114 111 100 117 99 116 95 110 97 109 101 34 44 34 111 114 100 101 114 95 100 101 116 97 105 108 46 115 104 111 119 95 117 114 108 34 44 34 111 114 100 101 114 95 100 101 116 97 105 108 46 111 102 102 105 99 105 97 108 95 112 114 105 99 101 34 44 34 111 114 100 101 114 95 100 101 116 97 105 108 46 99 111 115 116 95 112 114 105 99 101 34 44 34 111 114 100 101 114 95 100 101 116 97 105 108 46 99 114 101 97 116 101 95 116 105 109 101 34 44 34 111 114 100 101 114 95 100 101 116 97 105 108 46 117 112 100 97 116 101 95 116 105 109 101 34 44 34 111 114 100 101 114 95 118 111 117 99 104 101 114 46 99 104 97 110 110 101 108 34 44 34 111 114 100 101 114 95 118 111 117 99 104 101 114 46 99 104 97 110 110 101 108 95 97 99 116 105 118 105 116 121 95 105 100 34 44 34 111 114 100 101 114 95 118 111 117 99 104 101 114 46 99 104 97 110 110 101 108 95 118 111 117 99 104 101 114 95 105 100 34 44 34 111 114 100 101 114 95 118 111 117 99 104 101 114 46 115 116 97 116 117 115 34 44 34 111 114 100 101 114 95 118 111 117 99 104 101 114 46 103 114 97 110 116 95 116 105 109 101 34 44 34 111 114 100 101 114 95 118 111 117 99 104 101 114 46 117 115 97 103 101 95 116 105 109 101 34 44 34 111 114 100 101 114 95 118 111 117 99 104 101 114 46 114 101 102 117 110 100 95 116 105 109 101 34 44 34 111 114 100 101 114 95 118 111 117 99 104 101 114 46 115 116 97 116 117 115 95 109 111 100 105 102 121 95 116 105 109 101 34 44 34 111 114 100 101 114 95 118 111 117 99 104 101 114 46 111 118 101 114 100 117 101 95 116 105 109 101 34 44 34 111 114 100 101 114 95 118 111 117 99 104 101 114 46 114 101 102 117 110 100 95 97 109 111 117 110 116 34 44 34 111 114 100 101 114 95 118 111 117 99 104 101 114 46 111 102 102 105 99 105 97 108 95 112 114 105 99 101 34 44 34 111 114 100 101 114 95 118 111 117 99 104 101 114 46 111 117 116 95 98 105 122 95 110 111 34 44 34 111 114 100 101 114 95 118 111 117 99 104 101 114 46 97 99 99 111 117 110 116 95 110 111 34 44 34 118 111 117 99 104 101 114 46 99 104 97 110 110 101 108 34 44 34 118 111 117 99 104 101 114 46 99 104 97 110 110 101 108 95 97 99 116 105 118 105 116 121 95 105 100 34 44 34 118 111 117 99 104 101 114 46 112 114 105 99 101 34 44 34 118 111 117 99 104 101 114 46 98 97 108 97 110 99 101 34 44 34 118 111 117 99 104 101 114 46 117 115 101 100 95 97 109 111 117 110 116 34 44 34 118 111 117 99 104 101 114 46 100 101 110 111 109 105 110 97 116 105 111 110 34 44 34 118 111 117 99 104 101 114 95 98 97 116 99 104 46 99 104 97 110 110 101 108 95 97 99 116 105 118 105 116 121 95 105 100 34 44 34 118 111 117 99 104 101 114 95 98 97 116 99 104 46 116 101 109 112 95 110 111 34 44 34 118 111 117 99 104 101 114 95 98 97 116 99 104 46 112 114 111 118 105 100 101 114 34 44 34 118 111 117 99 104 101 114 95 98 97 116 99 104 46 119 101 105 103 104 116 34 44 34 112 108 97 110 46 105 100 34 44 34 112 108 97 110 46 116 105 116 108 101 34 44 34 112 108 97 110 46 115 116 97 116 117 115 34 44 34 112 108 97 110 46 98 101 103 105 110 95 116 105 109 101 34 44 34 112 108 97 110 46 101 110 100 95 116 105 109 101 34 44 34 107 101 121 95 98 97 116 99 104 46 105 100 34 44 34 107 101 121 95 98 97 116 99 104 46 98 97 116 99 104 95 110 97 109 101 34 44 34 107 101 121 95 98 97 116 99 104 46 98 105 110 100 95 111 98 106 101 99 116 34 44 34 107 101 121 95 98 97 116 99 104 46 113 117 97 110 116 105 116 121 34 44 34 107 101 121 95 98 97 116 99 104 46 115 116 111 99 107 34 44 34 107 101 121 95 98 97 116 99 104 46 98 101 103 105 110 95 116 105 109 101 34 44 34 107 101 121 95 98 97 116 99 104 46 101 110 100 95 116 105 109 101 34 44 34 99 111 100 101 95 98 97 116 99 104 46 105 100 34 44 34 99 111 100 101 95 98 97 116 99 104 46 116 105 116 108 101 34 44 34 99 111 100 101 95 98 97 116 99 104 46 115 116 97 116 117 115 34 44 34 99 111 100 101 95 98 97 116 99 104 46 98 101 103 105 110 95 116 105 109 101 34 44 34 99 111 100 101 95 98 97 116 99 104 46 101 110 100 95 116 105 109 101 34 44 34 99 111 100 101 95 98 97 116 99 104 46 113 117 97 110 116 105 116 121 34 44 34 99 111 100 101 95 98 97 116 99 104 46 117 115 97 103 101 34 44 34 99 111 100 101 95 98 97 116 99 104 46 115 116 111 99 107 34 93] xlsx private 0 1 0 2025-11-25 14:20:50.834224 +0800 CST m=+1130.796237043 2025-11-25 14:20:50.834224 +0800 CST m=+1130.796237043 2025-11-25 14:20:50.834224 +0800 CST m=+1130.796237043] +{"bytes":79,"duration_ms":112,"kind":"access","level":"INFO","method":"","path":"","query":"","remote":"","status":201,"trace_id":"","ts":"2025-11-25T14:20:50+08:00"} +{"bytes":695,"duration_ms":56,"kind":"access","level":"INFO","method":"","path":"","query":"","remote":"","status":200,"trace_id":"","ts":"2025-11-25T14:20:51+08:00"} +{"bytes":1795,"duration_ms":112,"kind":"access","level":"INFO","method":"","path":"","query":"","remote":"","status":200,"trace_id":"","ts":"2025-11-25T14:20:57+08:00"} +trace_id=29bebf66b8a0d5dcc13e150f44162dc1 sql=INSERT INTO export_templates (name, datasource, main_table, fields_json, filters_json, file_format, visibility, owner_id, enabled, stats_enabled, last_validated_at, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?) args=[测试红包 marketing order [91 34 111 114 100 101 114 46 111 114 100 101 114 95 110 117 109 98 101 114 34 44 34 111 114 100 101 114 46 99 114 101 97 116 111 114 34 44 34 111 114 100 101 114 46 111 117 116 95 116 114 97 100 101 95 110 111 34 44 34 111 114 100 101 114 46 116 121 112 101 34 44 34 111 114 100 101 114 46 115 116 97 116 117 115 34 44 34 111 114 100 101 114 46 99 111 110 116 114 97 99 116 95 112 114 105 99 101 34 44 34 111 114 100 101 114 46 110 117 109 34 44 34 111 114 100 101 114 46 116 111 116 97 108 34 44 34 111 114 100 101 114 46 112 97 121 95 97 109 111 117 110 116 34 44 34 111 114 100 101 114 46 99 114 101 97 116 101 95 116 105 109 101 34 44 34 111 114 100 101 114 46 117 112 100 97 116 101 95 116 105 109 101 34 44 34 111 114 100 101 114 95 100 101 116 97 105 108 46 112 108 97 110 95 116 105 116 108 101 34 44 34 111 114 100 101 114 95 100 101 116 97 105 108 46 114 101 115 101 108 108 101 114 95 110 97 109 101 34 44 34 111 114 100 101 114 95 100 101 116 97 105 108 46 112 114 111 100 117 99 116 95 110 97 109 101 34 44 34 111 114 100 101 114 95 100 101 116 97 105 108 46 115 104 111 119 95 117 114 108 34 44 34 111 114 100 101 114 95 100 101 116 97 105 108 46 111 102 102 105 99 105 97 108 95 112 114 105 99 101 34 44 34 111 114 100 101 114 95 100 101 116 97 105 108 46 99 111 115 116 95 112 114 105 99 101 34 44 34 111 114 100 101 114 95 100 101 116 97 105 108 46 99 114 101 97 116 101 95 116 105 109 101 34 44 34 111 114 100 101 114 95 100 101 116 97 105 108 46 117 112 100 97 116 101 95 116 105 109 101 34 44 34 111 114 100 101 114 95 99 97 115 104 46 99 104 97 110 110 101 108 34 44 34 111 114 100 101 114 95 99 97 115 104 46 99 97 115 104 95 97 99 116 105 118 105 116 121 95 105 100 34 44 34 111 114 100 101 114 95 99 97 115 104 46 114 101 99 101 105 118 101 95 115 116 97 116 117 115 34 44 34 111 114 100 101 114 95 99 97 115 104 46 114 101 99 101 105 118 101 95 116 105 109 101 34 44 34 111 114 100 101 114 95 99 97 115 104 46 99 97 115 104 95 112 97 99 107 101 116 95 105 100 34 44 34 111 114 100 101 114 95 99 97 115 104 46 99 97 115 104 95 105 100 34 44 34 111 114 100 101 114 95 99 97 115 104 46 97 109 111 117 110 116 34 44 34 111 114 100 101 114 95 99 97 115 104 46 115 116 97 116 117 115 34 44 34 111 114 100 101 114 95 99 97 115 104 46 101 120 112 105 114 101 95 116 105 109 101 34 44 34 111 114 100 101 114 95 99 97 115 104 46 117 112 100 97 116 101 95 116 105 109 101 34 44 34 112 108 97 110 46 105 100 34 44 34 112 108 97 110 46 116 105 116 108 101 34 44 34 112 108 97 110 46 115 116 97 116 117 115 34 44 34 112 108 97 110 46 98 101 103 105 110 95 116 105 109 101 34 44 34 112 108 97 110 46 101 110 100 95 116 105 109 101 34 44 34 107 101 121 95 98 97 116 99 104 46 105 100 34 44 34 107 101 121 95 98 97 116 99 104 46 98 97 116 99 104 95 110 97 109 101 34 44 34 107 101 121 95 98 97 116 99 104 46 98 105 110 100 95 111 98 106 101 99 116 34 44 34 107 101 121 95 98 97 116 99 104 46 113 117 97 110 116 105 116 121 34 44 34 107 101 121 95 98 97 116 99 104 46 115 116 111 99 107 34 44 34 107 101 121 95 98 97 116 99 104 46 98 101 103 105 110 95 116 105 109 101 34 44 34 107 101 121 95 98 97 116 99 104 46 101 110 100 95 116 105 109 101 34 44 34 99 111 100 101 95 98 97 116 99 104 46 105 100 34 44 34 99 111 100 101 95 98 97 116 99 104 46 116 105 116 108 101 34 44 34 99 111 100 101 95 98 97 116 99 104 46 115 116 97 116 117 115 34 44 34 99 111 100 101 95 98 97 116 99 104 46 98 101 103 105 110 95 116 105 109 101 34 44 34 99 111 100 101 95 98 97 116 99 104 46 101 110 100 95 116 105 109 101 34 44 34 99 111 100 101 95 98 97 116 99 104 46 113 117 97 110 116 105 116 121 34 44 34 99 111 100 101 95 98 97 116 99 104 46 117 115 97 103 101 34 44 34 99 111 100 101 95 98 97 116 99 104 46 115 116 111 99 107 34 93] xlsx private 0 1 0 2025-11-25 14:21:24.50211 +0800 CST m=+1164.464280876 2025-11-25 14:21:24.50211 +0800 CST m=+1164.464280876 2025-11-25 14:21:24.50211 +0800 CST m=+1164.464280876] +{"bytes":79,"duration_ms":105,"kind":"access","level":"INFO","method":"","path":"","query":"","remote":"","status":201,"trace_id":"","ts":"2025-11-25T14:21:24+08:00"} +{"bytes":1007,"duration_ms":51,"kind":"access","level":"INFO","method":"","path":"","query":"","remote":"","status":200,"trace_id":"","ts":"2025-11-25T14:21:24+08:00"} +{"bytes":79,"duration_ms":110,"kind":"access","level":"INFO","method":"","path":"","query":"","remote":"","status":200,"trace_id":"","ts":"2025-11-25T14:21:30+08:00"} +{"bytes":1015,"duration_ms":51,"kind":"access","level":"INFO","method":"","path":"","query":"","remote":"","status":200,"trace_id":"","ts":"2025-11-25T14:21:30+08:00"} +{"bytes":79,"duration_ms":106,"kind":"access","level":"INFO","method":"","path":"","query":"","remote":"","status":200,"trace_id":"","ts":"2025-11-25T14:21:39+08:00"} +{"bytes":1021,"duration_ms":52,"kind":"access","level":"INFO","method":"","path":"","query":"","remote":"","status":200,"trace_id":"","ts":"2025-11-25T14:21:39+08:00"} +{"bytes":1430,"duration_ms":128,"kind":"access","level":"INFO","method":"","path":"","query":"","remote":"","status":200,"trace_id":"","ts":"2025-11-25T14:21:41+08:00"} +{"bytes":1021,"duration_ms":52,"kind":"access","level":"INFO","method":"","path":"","query":"","remote":"","status":200,"trace_id":"","ts":"2025-11-25T14:26:10+08:00"} +{"bytes":1430,"duration_ms":101,"kind":"access","level":"INFO","method":"","path":"","query":"","remote":"","status":200,"trace_id":"","ts":"2025-11-25T14:26:12+08:00"} +connecting YMT MySQL: 47.97.27.195:3306 db merketing user root +connecting Marketing MySQL: 192.168.6.92:3306 db market user root +YMT DSN: root:lansexiongdi6,@tcp(47.97.27.195:3306)/merketing?parseTime=True&loc=Local&charset=utf8mb4 +Marketing DSN: root:lansexiongdi@tcp(192.168.6.92:3306)/market?parseTime=True&loc=Local&charset=utf8mb4 +server listening on :8077 +{"bytes":1021,"duration_ms":58,"kind":"access","level":"INFO","method":"","path":"","query":"","remote":"","status":200,"trace_id":"","ts":"2025-11-25T14:27:09+08:00"} +{"bytes":1021,"duration_ms":48,"kind":"access","level":"INFO","method":"","path":"","query":"","remote":"","status":200,"trace_id":"","ts":"2025-11-25T14:27:09+08:00"} +{"bytes":1430,"duration_ms":101,"kind":"access","level":"INFO","method":"","path":"","query":"","remote":"","status":200,"trace_id":"","ts":"2025-11-25T14:27:11+08:00"} +{"bytes":1021,"duration_ms":48,"kind":"access","level":"INFO","method":"","path":"","query":"","remote":"","status":200,"trace_id":"","ts":"2025-11-25T14:32:46+08:00"} +{"bytes":1430,"duration_ms":99,"kind":"access","level":"INFO","method":"","path":"","query":"","remote":"","status":200,"trace_id":"","ts":"2025-11-25T14:32:49+08:00"} +{"bytes":1021,"duration_ms":46,"kind":"access","level":"INFO","method":"","path":"","query":"","remote":"","status":200,"trace_id":"","ts":"2025-11-25T14:33:11+08:00"} +{"bytes":1430,"duration_ms":100,"kind":"access","level":"INFO","method":"","path":"","query":"","remote":"","status":200,"trace_id":"","ts":"2025-11-25T14:33:18+08:00"} +connecting YMT MySQL: 47.97.27.195:3306 db merketing user root +connecting Marketing MySQL: 192.168.6.92:3306 db market user root +YMT DSN: root:lansexiongdi6,@tcp(47.97.27.195:3306)/merketing?parseTime=True&loc=Local&charset=utf8mb4 +Marketing DSN: root:lansexiongdi@tcp(192.168.6.92:3306)/market?parseTime=True&loc=Local&charset=utf8mb4 +server listening on :8077 +{"bytes":1021,"duration_ms":49,"kind":"access","level":"INFO","method":"","path":"","query":"","remote":"","status":200,"trace_id":"","ts":"2025-11-25T14:33:47+08:00"} diff --git a/web/index.html b/web/index.html index e301d3d..7be8568 100644 --- a/web/index.html +++ b/web/index.html @@ -153,6 +153,45 @@ + 层级筛选 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -161,22 +200,7 @@ - - - - - - - - - - - - - - - - + diff --git a/web/main.js b/web/main.js index a33f71e..4b6eb9d 100644 --- a/web/main.js +++ b/web/main.js @@ -23,7 +23,7 @@ const { createApp, reactive } = Vue; createWidth: (localStorage.getItem('tplDialogWidth') || '900px'), editWidth: (localStorage.getItem('tplEditDialogWidth') || '600px'), edit: { id: null, name: '', visibility: 'private', file_format: 'csv' }, - exportForm: { tplId: null, datasource: 'marketing', file_format: 'xlsx', dateRange: [], outTradeNo: '', account: '', planId: null, productId: null, resellerId: null, codeBatchId: null, cashActivityId: '', voucherChannelActivityId: '', voucherBatchChannelActivityId: '', outBizNo: '' }, + exportForm: { tplId: null, datasource: 'marketing', file_format: 'xlsx', dateRange: [], creatorIds: [], creatorIdsRaw: '', resellerId: null, planId: null, keyBatchId: null, codeBatchId: null, productId: null, outTradeNo: '', account: '', cashActivityId: '', voucherChannelActivityId: '', voucherBatchChannelActivityId: '', outBizNo: '' }, exportTpl: { id: null, filters: {}, main_table: '', fields: [], datasource: '', file_format: '' } }) @@ -344,6 +344,20 @@ const { createApp, reactive } = Vue; if(v==='ymt') return '易码通' return v || '' } + const creatorOptions = Vue.ref([]) + const hasCreators = Vue.computed(()=> Array.isArray(state.exportForm.creatorIds) && state.exportForm.creatorIds.length>0 ) + const hasReseller = Vue.computed(()=> !!state.exportForm.resellerId) + const hasPlan = Vue.computed(()=> !!state.exportForm.planId) + const hasKeyBatch = Vue.computed(()=> !!state.exportForm.keyBatchId) + const hasCodeBatch = Vue.computed(()=> !!state.exportForm.codeBatchId) + const loadCreators = async ()=>{ + try{ + const res = await fetch(API_BASE + '/api/creators') + const data = await res.json() + const arr = Array.isArray(data?.data) ? data.data : (Array.isArray(data) ? data : []) + creatorOptions.value = arr.map(it=>({label: it.name || String(it.id), value: Number(it.id)})) + }catch(_e){ creatorOptions.value = [] } + } const exportType = Vue.computed(()=>{ const f = state.exportTpl && state.exportTpl.filters if(!f) return null @@ -448,6 +462,7 @@ const { createApp, reactive } = Vue; await loadTemplateDetail(row.id) state.exportForm.datasource = state.exportTpl.datasource || row.datasource || 'marketing' state.exportForm.file_format = state.exportTpl.file_format || row.file_format || 'xlsx' + if(state.exportForm.datasource==='marketing'){ loadCreators() } state.exportVisible = true } const loadTemplateDetail = async (id)=>{ @@ -472,11 +487,14 @@ const { createApp, reactive } = Vue; if(state.exportForm.planId){ filters.plan_id_eq = Number(state.exportForm.planId) } if(state.exportForm.productId){ filters.product_id_eq = Number(state.exportForm.productId) } if(state.exportForm.resellerId){ filters.reseller_id_eq = Number(state.exportForm.resellerId) } + if(state.exportForm.keyBatchId){ filters.key_batch_id_eq = Number(state.exportForm.keyBatchId) } if(state.exportForm.codeBatchId){ filters.code_batch_id_eq = Number(state.exportForm.codeBatchId) } if(state.exportForm.cashActivityId){ filters.order_cash_cash_activity_id_eq = state.exportForm.cashActivityId } if(state.exportForm.voucherChannelActivityId){ filters.order_voucher_channel_activity_id_eq = state.exportForm.voucherChannelActivityId } if(state.exportForm.voucherBatchChannelActivityId){ filters.voucher_batch_channel_activity_id_eq = state.exportForm.voucherBatchChannelActivityId } if(state.exportForm.outBizNo){ filters.merchant_out_biz_no_eq = state.exportForm.outBizNo } + if(Array.isArray(state.exportForm.creatorIds) && state.exportForm.creatorIds.length){ filters.creator_in = state.exportForm.creatorIds.map(Number) } + else if(state.exportForm.creatorIdsRaw){ const arr = String(state.exportForm.creatorIdsRaw).split(',').map(s=>s.trim()).filter(Boolean); if(arr.length){ filters.creator_in = arr } } const payload={template_id:Number(id),requested_by:1,permission:{},options:{},filters, file_format: state.exportForm.file_format, datasource: state.exportForm.datasource}; const r=await fetch(API_BASE + '/api/exports',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(payload)}); @@ -485,6 +503,11 @@ const { createApp, reactive } = Vue; state.exportVisible=false if(jid){ loadJob(jid) } else { msg('任务创建返回异常','error') } } + Vue.watch(()=>state.exportForm.creatorIds, ()=>{ state.exportForm.resellerId=null; state.exportForm.planId=null; state.exportForm.keyBatchId=null; state.exportForm.codeBatchId=null; state.exportForm.productId=null }) + Vue.watch(()=>state.exportForm.resellerId, ()=>{ state.exportForm.planId=null; state.exportForm.keyBatchId=null; state.exportForm.codeBatchId=null; state.exportForm.productId=null }) + Vue.watch(()=>state.exportForm.planId, ()=>{ state.exportForm.keyBatchId=null; state.exportForm.codeBatchId=null; state.exportForm.productId=null }) + Vue.watch(()=>state.exportForm.keyBatchId, ()=>{ state.exportForm.codeBatchId=null; state.exportForm.productId=null }) + Vue.watch(()=>state.exportForm.codeBatchId, ()=>{ state.exportForm.productId=null }) const clampWidth = (w)=>{ const n = Math.max(500, Math.min(1400, w)) return n + 'px'