feat(api): 支持营销代理数据库并优化代理列表查询
- 新增配置项支持营销代理数据库连接 - 主服务启动时根据配置连接营销代理MySQL,若无配置则使用营销库回退 - ResellersAPI 使用独立的营销代理数据库替代原营销数据库查询 - 优化代理列表接口,改为从reseller表查询代理Id及名称 - 修改路由注册,使用营销代理数据库处理代理相关路由请求 - 调整相关代码实现,提升代理数据查询灵活性和健壮性
This commit is contained in:
parent
6dbc3eb1a1
commit
11a93996e5
|
|
@ -60,7 +60,18 @@ func main() {
|
||||||
}
|
}
|
||||||
// apply pool settings from env for Meta (templates/jobs)
|
// apply pool settings from env for Meta (templates/jobs)
|
||||||
db.ApplyPoolFromEnv(meta, "YMT_TEST_DB_")
|
db.ApplyPoolFromEnv(meta, "YMT_TEST_DB_")
|
||||||
r := api.NewRouter(meta, marketing, marketingAuth, ymt)
|
// Marketing Reseller DB
|
||||||
|
var resellerDB *sql.DB
|
||||||
|
if cfg.MarketingResellerDB.DSN() != "" {
|
||||||
|
resellerDB, err = db.ConnectMySQL(cfg.MarketingResellerDB.DSN())
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
log.Println("connecting Marketing Reseller MySQL:", cfg.MarketingResellerDB.Host+":"+cfg.MarketingResellerDB.Port, "db", cfg.MarketingResellerDB.Name)
|
||||||
|
} else {
|
||||||
|
resellerDB = marketing // fallback
|
||||||
|
}
|
||||||
|
r := api.NewRouter(meta, marketing, marketingAuth, resellerDB, ymt)
|
||||||
addr := ":" + func() string {
|
addr := ":" + func() string {
|
||||||
s := cfg.Port
|
s := cfg.Port
|
||||||
if s == "" {
|
if s == "" {
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,11 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type ResellersAPI struct {
|
type ResellersAPI struct {
|
||||||
marketing *sql.DB
|
resellerDB *sql.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
func ResellersHandler(marketing *sql.DB) http.Handler {
|
func ResellersHandler(resellerDB *sql.DB) http.Handler {
|
||||||
api := &ResellersAPI{marketing: marketing}
|
api := &ResellersAPI{resellerDB: resellerDB}
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
p := strings.TrimPrefix(r.URL.Path, "/api/resellers")
|
p := strings.TrimPrefix(r.URL.Path, "/api/resellers")
|
||||||
if r.Method == http.MethodGet && p == "" {
|
if r.Method == http.MethodGet && p == "" {
|
||||||
|
|
@ -24,35 +24,25 @@ func ResellersHandler(marketing *sql.DB) http.Handler {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *ResellersAPI) list(w http.ResponseWriter, r *http.Request) {
|
func (a *ResellersAPI) list(w http.ResponseWriter, r *http.Request) {
|
||||||
creatorsParam := r.URL.Query().Get("creator")
|
|
||||||
q := r.URL.Query().Get("q")
|
q := r.URL.Query().Get("q")
|
||||||
limitStr := r.URL.Query().Get("limit")
|
limitStr := r.URL.Query().Get("limit")
|
||||||
limit := 2000
|
limit := 2000
|
||||||
if limitStr != "" {
|
if limitStr != "" {
|
||||||
if n, err := strconv.Atoi(limitStr); err == nil && n > 0 && n <= 10000 { limit = n }
|
if n, err := strconv.Atoi(limitStr); err == nil && n > 0 && n <= 10000 {
|
||||||
|
limit = n
|
||||||
}
|
}
|
||||||
creators := []string{}
|
|
||||||
for _, s := range strings.Split(creatorsParam, ",") {
|
|
||||||
s = strings.TrimSpace(s)
|
|
||||||
if s != "" { creators = append(creators, s) }
|
|
||||||
}
|
}
|
||||||
if len(creators) == 0 {
|
|
||||||
ok(w, r, []map[string]interface{}{})
|
sql1 := "SELECT id, COALESCE(name,'') AS name FROM reseller WHERE 1=1"
|
||||||
return
|
|
||||||
}
|
|
||||||
ph := strings.Repeat("?,", len(creators))
|
|
||||||
ph = strings.TrimSuffix(ph, ",")
|
|
||||||
sql1 := "SELECT DISTINCT reseller_id, COALESCE(reseller_name,'') AS name FROM plan WHERE reseller_id IS NOT NULL AND creator IN (" + ph + ")"
|
|
||||||
args := []interface{}{}
|
args := []interface{}{}
|
||||||
for _, c := range creators { args = append(args, c) }
|
|
||||||
if q != "" {
|
if q != "" {
|
||||||
sql1 += " AND (CAST(reseller_id AS CHAR) LIKE ? OR reseller_name LIKE ?)"
|
sql1 += " AND (CAST(id AS CHAR) LIKE ? OR name LIKE ?)"
|
||||||
like := "%" + q + "%"
|
like := "%" + q + "%"
|
||||||
args = append(args, like, like)
|
args = append(args, like, like)
|
||||||
}
|
}
|
||||||
sql1 += " ORDER BY reseller_id ASC LIMIT ?"
|
sql1 += " ORDER BY id ASC LIMIT ?"
|
||||||
args = append(args, limit)
|
args = append(args, limit)
|
||||||
rows, err := a.marketing.Query(sql1, args...)
|
rows, err := a.resellerDB.Query(sql1, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fail(w, r, http.StatusInternalServerError, err.Error())
|
fail(w, r, http.StatusInternalServerError, err.Error())
|
||||||
return
|
return
|
||||||
|
|
@ -62,11 +52,14 @@ func (a *ResellersAPI) list(w http.ResponseWriter, r *http.Request) {
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var id sql.NullInt64
|
var id sql.NullInt64
|
||||||
var name sql.NullString
|
var name sql.NullString
|
||||||
if err := rows.Scan(&id, &name); err != nil { continue }
|
if err := rows.Scan(&id, &name); err != nil {
|
||||||
if !id.Valid { continue }
|
continue
|
||||||
|
}
|
||||||
|
if !id.Valid {
|
||||||
|
continue
|
||||||
|
}
|
||||||
m := map[string]interface{}{"id": id.Int64, "name": name.String}
|
m := map[string]interface{}{"id": id.Int64, "name": name.String}
|
||||||
out = append(out, m)
|
out = append(out, m)
|
||||||
}
|
}
|
||||||
ok(w, r, out)
|
ok(w, r, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewRouter(metaDB *sql.DB, marketingDB *sql.DB, marketingAuthDB *sql.DB, ymtDB *sql.DB) http.Handler {
|
func NewRouter(metaDB *sql.DB, marketingDB *sql.DB, marketingAuthDB *sql.DB, resellerDB *sql.DB, ymtDB *sql.DB) http.Handler {
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
mux.Handle("/api/templates", withAccess(withTrace(TemplatesHandler(metaDB, marketingDB))))
|
mux.Handle("/api/templates", withAccess(withTrace(TemplatesHandler(metaDB, marketingDB))))
|
||||||
mux.Handle("/api/templates/", withAccess(withTrace(TemplatesHandler(metaDB, marketingDB))))
|
mux.Handle("/api/templates/", withAccess(withTrace(TemplatesHandler(metaDB, marketingDB))))
|
||||||
|
|
@ -17,8 +17,8 @@ func NewRouter(metaDB *sql.DB, marketingDB *sql.DB, marketingAuthDB *sql.DB, ymt
|
||||||
mux.Handle("/api/fields/", withAccess(withTrace(FieldsHandler(marketingDB, ymtDB))))
|
mux.Handle("/api/fields/", withAccess(withTrace(FieldsHandler(marketingDB, ymtDB))))
|
||||||
mux.Handle("/api/creators", withAccess(withTrace(CreatorsHandler(marketingAuthDB))))
|
mux.Handle("/api/creators", withAccess(withTrace(CreatorsHandler(marketingAuthDB))))
|
||||||
mux.Handle("/api/creators/", withAccess(withTrace(CreatorsHandler(marketingAuthDB))))
|
mux.Handle("/api/creators/", withAccess(withTrace(CreatorsHandler(marketingAuthDB))))
|
||||||
mux.Handle("/api/resellers", withAccess(withTrace(ResellersHandler(marketingDB))))
|
mux.Handle("/api/resellers", withAccess(withTrace(ResellersHandler(resellerDB))))
|
||||||
mux.Handle("/api/resellers/", withAccess(withTrace(ResellersHandler(marketingDB))))
|
mux.Handle("/api/resellers/", withAccess(withTrace(ResellersHandler(resellerDB))))
|
||||||
mux.Handle("/api/plans", withAccess(withTrace(PlansHandler(marketingDB))))
|
mux.Handle("/api/plans", withAccess(withTrace(PlansHandler(marketingDB))))
|
||||||
mux.Handle("/api/plans/", withAccess(withTrace(PlansHandler(marketingDB))))
|
mux.Handle("/api/plans/", withAccess(withTrace(PlansHandler(marketingDB))))
|
||||||
mux.Handle("/api/ymt/users", withAccess(withTrace(YMTUsersHandler(ymtDB))))
|
mux.Handle("/api/ymt/users", withAccess(withTrace(YMTUsersHandler(ymtDB))))
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ type App struct {
|
||||||
Port string `yaml:"port"`
|
Port string `yaml:"port"`
|
||||||
MarketingDB DB `yaml:"marketing_db"`
|
MarketingDB DB `yaml:"marketing_db"`
|
||||||
MarketingAuthorizationDB DB `yaml:"marketing_authorization_db"`
|
MarketingAuthorizationDB DB `yaml:"marketing_authorization_db"`
|
||||||
|
MarketingResellerDB DB `yaml:"marketing_reseller_db"`
|
||||||
YMTDB DB `yaml:"ymt_db"`
|
YMTDB DB `yaml:"ymt_db"`
|
||||||
YMTTestDB DB `yaml:"ymt_test_db"`
|
YMTTestDB DB `yaml:"ymt_test_db"`
|
||||||
YMTKeyDecryptKeyB64 string `yaml:"ymt_key_decrypt_key_b64"`
|
YMTKeyDecryptKeyB64 string `yaml:"ymt_key_decrypt_key_b64"`
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue