feat: add dashboard recharge user metrics
This commit is contained in:
parent
422fab1bf3
commit
fcc11122d4
@ -36,7 +36,7 @@ func (m *Mapper) Map(ctx context.Context, schema string, table string, action st
|
|||||||
case "order_purchase_history":
|
case "order_purchase_history":
|
||||||
return m.mapOfficialRecharge(ctx, schema, table, action, row)
|
return m.mapOfficialRecharge(ctx, schema, table, action, row)
|
||||||
case "order_user_purchase_pay":
|
case "order_user_purchase_pay":
|
||||||
return m.mapMifapayRecharge(ctx, schema, table, action, row)
|
return m.mapThirdPartyRecharge(ctx, schema, table, action, row)
|
||||||
case "game_lucky_gift_count":
|
case "game_lucky_gift_count":
|
||||||
return m.mapLuckyGift(ctx, schema, table, action, row)
|
return m.mapLuckyGift(ctx, schema, table, action, row)
|
||||||
case "game_lucky_box_count":
|
case "game_lucky_box_count":
|
||||||
@ -96,6 +96,7 @@ func (m *Mapper) mapOfficialRecharge(ctx context.Context, schema string, table s
|
|||||||
}
|
}
|
||||||
if payPlatform == "GOOGLE" {
|
if payPlatform == "GOOGLE" {
|
||||||
c.GoogleRecharge = amount
|
c.GoogleRecharge = amount
|
||||||
|
c.UserRecharge = amount
|
||||||
}
|
}
|
||||||
c.NewUserRechargeCandidate = amount
|
c.NewUserRechargeCandidate = amount
|
||||||
c.RechargeDetail = rechargeDetail("OFFICIAL", rowPK(row), payPlatform, row, user, amount,
|
c.RechargeDetail = rechargeDetail("OFFICIAL", rowPK(row), payPlatform, row, user, amount,
|
||||||
@ -103,19 +104,26 @@ func (m *Mapper) mapOfficialRecharge(ctx context.Context, schema string, table s
|
|||||||
return []Contribution{c}, nil
|
return []Contribution{c}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mapper) mapMifapayRecharge(ctx context.Context, schema string, table string, action string, row Row) ([]Contribution, error) {
|
func (m *Mapper) mapThirdPartyRecharge(ctx context.Context, schema string, table string, action string, row Row) ([]Contribution, error) {
|
||||||
if row.String("evn") != "PROD" || row.String("factory_code") != "MIFA_PAY" ||
|
if row.String("evn") != "PROD" ||
|
||||||
row.String("pay_status") != "SUCCESSFUL" || row.String("receipt_type") != "PAYMENT" ||
|
row.String("pay_status") != "SUCCESSFUL" || row.String("receipt_type") != "PAYMENT" ||
|
||||||
row.String("refund_status") != "NONE" {
|
row.String("refund_status") != "NONE" {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
items, err := m.amountContribution(ctx, schema, table, action, row, row.Decimal("compute_usd_amount"), func(c *Contribution, amount decimal.Decimal) {
|
items, err := m.amountContribution(ctx, schema, table, action, row, row.Decimal("compute_usd_amount"), func(c *Contribution, amount decimal.Decimal) {
|
||||||
c.MifapayRecharge = amount
|
c.UserRecharge = amount
|
||||||
|
if row.String("factory_code") == "MIFA_PAY" {
|
||||||
|
c.MifapayRecharge = amount
|
||||||
|
}
|
||||||
})
|
})
|
||||||
if err != nil || len(items) == 0 {
|
if err != nil || len(items) == 0 {
|
||||||
return items, err
|
return items, err
|
||||||
}
|
}
|
||||||
items[0].RechargeDetail = rechargeDetail("MIFAPAY", rowPK(row), row.String("factory_code"), row,
|
sourceType := "THIRD_PARTY"
|
||||||
|
if row.String("factory_code") == "MIFA_PAY" {
|
||||||
|
sourceType = "MIFAPAY"
|
||||||
|
}
|
||||||
|
items[0].RechargeDetail = rechargeDetail(sourceType, rowPK(row), row.String("factory_code"), row,
|
||||||
detailUser(items[0]), row.Decimal("compute_usd_amount"), decimal.Zero, "")
|
detailUser(items[0]), row.Decimal("compute_usd_amount"), decimal.Zero, "")
|
||||||
return items, nil
|
return items, nil
|
||||||
}
|
}
|
||||||
@ -126,6 +134,7 @@ func (m *Mapper) mapDealerRecharge(ctx context.Context, schema string, table str
|
|||||||
}
|
}
|
||||||
items, err := m.amountContribution(ctx, schema, table, action, row, row.Decimal("amount"), func(c *Contribution, amount decimal.Decimal) {
|
items, err := m.amountContribution(ctx, schema, table, action, row, row.Decimal("amount"), func(c *Contribution, amount decimal.Decimal) {
|
||||||
c.DealerRecharge = amount
|
c.DealerRecharge = amount
|
||||||
|
c.NewDealerUserRecharge = amount
|
||||||
})
|
})
|
||||||
if err != nil || len(items) == 0 {
|
if err != nil || len(items) == 0 {
|
||||||
return items, err
|
return items, err
|
||||||
|
|||||||
@ -123,3 +123,74 @@ func TestUserCreateTimeDisplayOffsetIsApplied(t *testing.T) {
|
|||||||
t.Fatalf("expected country new user contribution, got %d", contributions[0].CountryNewUser)
|
t.Fatalf("expected country new user contribution, got %d", contributions[0].CountryNewUser)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGoogleRechargeContributesToUserRecharge(t *testing.T) {
|
||||||
|
mapper := NewMapper(walletMapperTestStore{users: map[int64]UserCountry{
|
||||||
|
1001: {
|
||||||
|
UserID: 1001,
|
||||||
|
SysOrigin: "LIKEI",
|
||||||
|
Country: Country{Code: "BD", Name: "Bangladesh"},
|
||||||
|
CreatedAt: time.Date(2026, 5, 27, 8, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
}}, []string{"LIKEI"}, "UNKNOWN", 0)
|
||||||
|
|
||||||
|
contributions, err := mapper.Map(context.Background(), "likei", "order_purchase_history", "insert", Row{
|
||||||
|
"id": int64(21),
|
||||||
|
"user_id": int64(1001),
|
||||||
|
"sys_origin": "LIKEI",
|
||||||
|
"evn": "PROD",
|
||||||
|
"status": "COMPLETE",
|
||||||
|
"is_trial_period": int64(0),
|
||||||
|
"unit_price": decimal.NewFromInt(99),
|
||||||
|
"pay_platform": "GOOGLE",
|
||||||
|
"create_time": time.Date(2026, 5, 27, 9, 0, 0, 0, time.UTC),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if len(contributions) != 1 {
|
||||||
|
t.Fatalf("expected one contribution, got %d", len(contributions))
|
||||||
|
}
|
||||||
|
if !contributions[0].GoogleRecharge.Equal(decimal.NewFromInt(99)) {
|
||||||
|
t.Fatalf("expected google recharge 99, got %s", contributions[0].GoogleRecharge)
|
||||||
|
}
|
||||||
|
if !contributions[0].UserRecharge.Equal(decimal.NewFromInt(99)) {
|
||||||
|
t.Fatalf("expected user recharge 99, got %s", contributions[0].UserRecharge)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestThirdPartyRechargeContributesToUserRechargeForAnyFactory(t *testing.T) {
|
||||||
|
mapper := NewMapper(walletMapperTestStore{users: map[int64]UserCountry{
|
||||||
|
1001: {
|
||||||
|
UserID: 1001,
|
||||||
|
SysOrigin: "LIKEI",
|
||||||
|
Country: Country{Code: "BD", Name: "Bangladesh"},
|
||||||
|
CreatedAt: time.Date(2026, 5, 27, 8, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
}}, []string{"LIKEI"}, "UNKNOWN", 0)
|
||||||
|
|
||||||
|
contributions, err := mapper.Map(context.Background(), "likei", "order_user_purchase_pay", "insert", Row{
|
||||||
|
"id": int64(22),
|
||||||
|
"user_id": int64(1001),
|
||||||
|
"sys_origin": "LIKEI",
|
||||||
|
"evn": "PROD",
|
||||||
|
"factory_code": "OTHER_PAY",
|
||||||
|
"pay_status": "SUCCESSFUL",
|
||||||
|
"receipt_type": "PAYMENT",
|
||||||
|
"refund_status": "NONE",
|
||||||
|
"compute_usd_amount": decimal.NewFromInt(12),
|
||||||
|
"create_time": time.Date(2026, 5, 27, 9, 0, 0, 0, time.UTC),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if len(contributions) != 1 {
|
||||||
|
t.Fatalf("expected one contribution, got %d", len(contributions))
|
||||||
|
}
|
||||||
|
if !contributions[0].UserRecharge.Equal(decimal.NewFromInt(12)) {
|
||||||
|
t.Fatalf("expected user recharge 12, got %s", contributions[0].UserRecharge)
|
||||||
|
}
|
||||||
|
if !contributions[0].MifapayRecharge.IsZero() {
|
||||||
|
t.Fatalf("expected non MifaPay recharge to keep mifapay zero, got %s", contributions[0].MifapayRecharge)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -24,10 +24,16 @@ func (p *Projector) writeRealtimeRedis(ctx context.Context, contributions []Cont
|
|||||||
c.Country.Code,
|
c.Country.Code,
|
||||||
)
|
)
|
||||||
sign := decimal.NewFromInt(int64(c.DeltaSign))
|
sign := decimal.NewFromInt(int64(c.DeltaSign))
|
||||||
|
newDealerUserRecharge := decimal.Zero
|
||||||
|
if SamePeriod(c.UserCreatedAt, c.EventTime, PeriodWindow{Type: PeriodDay}, p.storageZone) {
|
||||||
|
newDealerUserRecharge = c.NewDealerUserRecharge
|
||||||
|
}
|
||||||
hincrDecimal(pipe, ctx, key, "official_recharge", c.OfficialRecharge.Mul(sign))
|
hincrDecimal(pipe, ctx, key, "official_recharge", c.OfficialRecharge.Mul(sign))
|
||||||
hincrDecimal(pipe, ctx, key, "mifapay_recharge", c.MifapayRecharge.Mul(sign))
|
hincrDecimal(pipe, ctx, key, "mifapay_recharge", c.MifapayRecharge.Mul(sign))
|
||||||
hincrDecimal(pipe, ctx, key, "google_recharge", c.GoogleRecharge.Mul(sign))
|
hincrDecimal(pipe, ctx, key, "google_recharge", c.GoogleRecharge.Mul(sign))
|
||||||
hincrDecimal(pipe, ctx, key, "dealer_recharge", c.DealerRecharge.Mul(sign))
|
hincrDecimal(pipe, ctx, key, "dealer_recharge", c.DealerRecharge.Mul(sign))
|
||||||
|
hincrDecimal(pipe, ctx, key, "user_recharge", c.UserRecharge.Mul(sign))
|
||||||
|
hincrDecimal(pipe, ctx, key, "new_dealer_user_recharge", newDealerUserRecharge.Mul(sign))
|
||||||
hincrDecimal(pipe, ctx, key, "salary_exchange", c.SalaryExchange.Mul(sign))
|
hincrDecimal(pipe, ctx, key, "salary_exchange", c.SalaryExchange.Mul(sign))
|
||||||
hincrDecimal(pipe, ctx, key, "salary_transfer", c.SalaryTransfer.Mul(sign))
|
hincrDecimal(pipe, ctx, key, "salary_transfer", c.SalaryTransfer.Mul(sign))
|
||||||
hincrDecimal(pipe, ctx, key, "lucky_gift_total_flow", c.LuckyGiftTotalFlow.Mul(sign))
|
hincrDecimal(pipe, ctx, key, "lucky_gift_total_flow", c.LuckyGiftTotalFlow.Mul(sign))
|
||||||
|
|||||||
@ -18,6 +18,7 @@ const (
|
|||||||
MetricCountryNewUser = "COUNTRY_NEW_USER"
|
MetricCountryNewUser = "COUNTRY_NEW_USER"
|
||||||
MetricLuckyGiftUser = "LUCKY_GIFT_USER"
|
MetricLuckyGiftUser = "LUCKY_GIFT_USER"
|
||||||
MetricGameUser = "GAME_USER"
|
MetricGameUser = "GAME_USER"
|
||||||
|
MetricRechargeUser = "RECHARGE_USER"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Country struct {
|
type Country struct {
|
||||||
@ -46,6 +47,8 @@ type Contribution struct {
|
|||||||
MifapayRecharge decimal.Decimal
|
MifapayRecharge decimal.Decimal
|
||||||
GoogleRecharge decimal.Decimal
|
GoogleRecharge decimal.Decimal
|
||||||
DealerRecharge decimal.Decimal
|
DealerRecharge decimal.Decimal
|
||||||
|
UserRecharge decimal.Decimal
|
||||||
|
NewDealerUserRecharge decimal.Decimal
|
||||||
SalaryExchange decimal.Decimal
|
SalaryExchange decimal.Decimal
|
||||||
SalaryTransfer decimal.Decimal
|
SalaryTransfer decimal.Decimal
|
||||||
GiftConsume decimal.Decimal
|
GiftConsume decimal.Decimal
|
||||||
@ -82,6 +85,8 @@ func (c Contribution) Empty() bool {
|
|||||||
c.MifapayRecharge.IsZero() &&
|
c.MifapayRecharge.IsZero() &&
|
||||||
c.GoogleRecharge.IsZero() &&
|
c.GoogleRecharge.IsZero() &&
|
||||||
c.DealerRecharge.IsZero() &&
|
c.DealerRecharge.IsZero() &&
|
||||||
|
c.UserRecharge.IsZero() &&
|
||||||
|
c.NewDealerUserRecharge.IsZero() &&
|
||||||
c.SalaryExchange.IsZero() &&
|
c.SalaryExchange.IsZero() &&
|
||||||
c.SalaryTransfer.IsZero() &&
|
c.SalaryTransfer.IsZero() &&
|
||||||
c.GiftConsume.IsZero() &&
|
c.GiftConsume.IsZero() &&
|
||||||
|
|||||||
@ -611,9 +611,9 @@ INSERT INTO country_dashboard_period_metric (
|
|||||||
period_type, period_key, stat_timezone, period_name, period_start_date, period_end_date,
|
period_type, period_key, stat_timezone, period_name, period_start_date, period_end_date,
|
||||||
sys_origin, country_code, country_name,
|
sys_origin, country_code, country_name,
|
||||||
country_new_user, daily_active_user, new_user_recharge, official_recharge, mifapay_recharge,
|
country_new_user, daily_active_user, new_user_recharge, official_recharge, mifapay_recharge,
|
||||||
google_recharge, dealer_recharge, salary_exchange, salary_transfer, gift_consume,
|
google_recharge, dealer_recharge, user_recharge, new_dealer_user_recharge, salary_exchange, salary_transfer, gift_consume,
|
||||||
lucky_gift_total_flow, lucky_gift_user, lucky_gift_payout, lucky_gift_anchor_share,
|
lucky_gift_total_flow, lucky_gift_user, lucky_gift_payout, lucky_gift_anchor_share,
|
||||||
game_total_flow, game_user, game_payout,
|
game_total_flow, daily_recharge_user, game_user, game_payout,
|
||||||
d1_retention_user, d1_retention_base_user, d7_retention_user, d7_retention_base_user,
|
d1_retention_user, d1_retention_base_user, d7_retention_user, d7_retention_base_user,
|
||||||
d30_retention_user, d30_retention_base_user, refreshed_at
|
d30_retention_user, d30_retention_base_user, refreshed_at
|
||||||
)
|
)
|
||||||
@ -626,6 +626,8 @@ SELECT 'ALL', 'ALL', ?, '全部', NULL, NULL,
|
|||||||
IFNULL(SUM(d.mifapay_recharge), 0),
|
IFNULL(SUM(d.mifapay_recharge), 0),
|
||||||
IFNULL(SUM(d.google_recharge), 0),
|
IFNULL(SUM(d.google_recharge), 0),
|
||||||
IFNULL(SUM(d.dealer_recharge), 0),
|
IFNULL(SUM(d.dealer_recharge), 0),
|
||||||
|
IFNULL(SUM(d.user_recharge), 0),
|
||||||
|
IFNULL(SUM(d.new_dealer_user_recharge), 0),
|
||||||
IFNULL(SUM(d.salary_exchange), 0),
|
IFNULL(SUM(d.salary_exchange), 0),
|
||||||
IFNULL(SUM(d.salary_transfer), 0),
|
IFNULL(SUM(d.salary_transfer), 0),
|
||||||
IFNULL(SUM(d.gift_consume), 0),
|
IFNULL(SUM(d.gift_consume), 0),
|
||||||
@ -634,6 +636,7 @@ SELECT 'ALL', 'ALL', ?, '全部', NULL, NULL,
|
|||||||
IFNULL(SUM(d.lucky_gift_payout), 0),
|
IFNULL(SUM(d.lucky_gift_payout), 0),
|
||||||
IFNULL(SUM(d.lucky_gift_anchor_share), 0),
|
IFNULL(SUM(d.lucky_gift_anchor_share), 0),
|
||||||
IFNULL(SUM(d.game_total_flow), 0),
|
IFNULL(SUM(d.game_total_flow), 0),
|
||||||
|
IFNULL(MAX(u.daily_recharge_user), 0),
|
||||||
IFNULL(MAX(u.game_user), 0),
|
IFNULL(MAX(u.game_user), 0),
|
||||||
IFNULL(SUM(d.game_payout), 0),
|
IFNULL(SUM(d.game_payout), 0),
|
||||||
IFNULL(SUM(d.d1_retention_user), 0),
|
IFNULL(SUM(d.d1_retention_user), 0),
|
||||||
@ -648,6 +651,7 @@ LEFT JOIN (
|
|||||||
SELECT country_code,
|
SELECT country_code,
|
||||||
SUM(metric_type = 'COUNTRY_NEW_USER') AS country_new_user,
|
SUM(metric_type = 'COUNTRY_NEW_USER') AS country_new_user,
|
||||||
SUM(metric_type = 'LUCKY_GIFT_USER') AS lucky_gift_user,
|
SUM(metric_type = 'LUCKY_GIFT_USER') AS lucky_gift_user,
|
||||||
|
SUM(metric_type = 'RECHARGE_USER') AS daily_recharge_user,
|
||||||
SUM(metric_type = 'GAME_USER') AS game_user
|
SUM(metric_type = 'GAME_USER') AS game_user
|
||||||
FROM country_dashboard_period_user_metric
|
FROM country_dashboard_period_user_metric
|
||||||
WHERE period_type = 'ALL' AND period_key = 'ALL' AND stat_timezone = ? AND sys_origin = ?
|
WHERE period_type = 'ALL' AND period_key = 'ALL' AND stat_timezone = ? AND sys_origin = ?
|
||||||
|
|||||||
@ -17,10 +17,12 @@ func (r *MySQLRepository) ApplyDailyContribution(ctx context.Context, tx *sql.Tx
|
|||||||
}
|
}
|
||||||
day := dashboard.DailyDate(c.EventTime, zone)
|
day := dashboard.DailyDate(c.EventTime, zone)
|
||||||
newUserRecharge := decimal.Zero
|
newUserRecharge := decimal.Zero
|
||||||
|
newDealerUserRecharge := decimal.Zero
|
||||||
if dashboard.SamePeriod(c.UserCreatedAt, c.EventTime, dashboard.PeriodWindow{Type: dashboard.PeriodDay}, zone) {
|
if dashboard.SamePeriod(c.UserCreatedAt, c.EventTime, dashboard.PeriodWindow{Type: dashboard.PeriodDay}, zone) {
|
||||||
newUserRecharge = c.NewUserRechargeCandidate
|
newUserRecharge = c.NewUserRechargeCandidate
|
||||||
|
newDealerUserRecharge = c.NewDealerUserRecharge
|
||||||
}
|
}
|
||||||
if err := r.upsertDailyAmounts(ctx, tx, c, day, newUserRecharge); err != nil {
|
if err := r.upsertDailyAmounts(ctx, tx, c, day, newUserRecharge, newDealerUserRecharge); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if c.CountryNewUser > 0 {
|
if c.CountryNewUser > 0 {
|
||||||
@ -38,6 +40,11 @@ func (r *MySQLRepository) ApplyDailyContribution(ctx context.Context, tx *sql.Tx
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if c.UserRecharge.GreaterThan(decimal.Zero) {
|
||||||
|
if err := r.applyDailyUserMetric(ctx, tx, c, day, dashboard.MetricRechargeUser); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,10 +55,12 @@ func (r *MySQLRepository) ApplyPeriodContribution(ctx context.Context, tx *sql.T
|
|||||||
}
|
}
|
||||||
for _, window := range dashboard.PeriodWindows(c.EventTime, zone) {
|
for _, window := range dashboard.PeriodWindows(c.EventTime, zone) {
|
||||||
newUserRecharge := decimal.Zero
|
newUserRecharge := decimal.Zero
|
||||||
|
newDealerUserRecharge := decimal.Zero
|
||||||
if dashboard.SamePeriod(c.UserCreatedAt, c.EventTime, window, zone) {
|
if dashboard.SamePeriod(c.UserCreatedAt, c.EventTime, window, zone) {
|
||||||
newUserRecharge = c.NewUserRechargeCandidate
|
newUserRecharge = c.NewUserRechargeCandidate
|
||||||
|
newDealerUserRecharge = c.NewDealerUserRecharge
|
||||||
}
|
}
|
||||||
if err := r.upsertPeriodAmounts(ctx, tx, c, window, statTimezone, newUserRecharge); err != nil {
|
if err := r.upsertPeriodAmounts(ctx, tx, c, window, statTimezone, newUserRecharge, newDealerUserRecharge); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if c.CountryNewUser > 0 {
|
if c.CountryNewUser > 0 {
|
||||||
@ -69,6 +78,11 @@ func (r *MySQLRepository) ApplyPeriodContribution(ctx context.Context, tx *sql.T
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if c.UserRecharge.GreaterThan(decimal.Zero) {
|
||||||
|
if err := r.applyPeriodUserMetric(ctx, tx, c, window, statTimezone, dashboard.MetricRechargeUser); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -94,15 +108,15 @@ func (r *MySQLRepository) ApplyGamePeriodContribution(ctx context.Context, tx *s
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *MySQLRepository) upsertDailyAmounts(ctx context.Context, tx *sql.Tx, c dashboard.Contribution, day time.Time, newUserRecharge decimal.Decimal) error {
|
func (r *MySQLRepository) upsertDailyAmounts(ctx context.Context, tx *sql.Tx, c dashboard.Contribution, day time.Time, newUserRecharge decimal.Decimal, newDealerUserRecharge decimal.Decimal) error {
|
||||||
sign := decimal.NewFromInt(int64(c.DeltaSign))
|
sign := decimal.NewFromInt(int64(c.DeltaSign))
|
||||||
_, err := tx.ExecContext(ctx, `
|
_, err := tx.ExecContext(ctx, `
|
||||||
INSERT INTO country_dashboard_daily_metric (
|
INSERT INTO country_dashboard_daily_metric (
|
||||||
stat_date, date_number, sys_origin, country_code, country_name,
|
stat_date, date_number, sys_origin, country_code, country_name,
|
||||||
new_user_recharge, official_recharge, mifapay_recharge, google_recharge,
|
new_user_recharge, official_recharge, mifapay_recharge, google_recharge,
|
||||||
dealer_recharge, salary_exchange, salary_transfer, gift_consume, lucky_gift_total_flow, lucky_gift_payout,
|
dealer_recharge, user_recharge, new_dealer_user_recharge, salary_exchange, salary_transfer, gift_consume, lucky_gift_total_flow, lucky_gift_payout,
|
||||||
game_total_flow, game_payout, refreshed_at
|
game_total_flow, game_payout, refreshed_at
|
||||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())
|
||||||
ON DUPLICATE KEY UPDATE
|
ON DUPLICATE KEY UPDATE
|
||||||
country_name = VALUES(country_name),
|
country_name = VALUES(country_name),
|
||||||
new_user_recharge = new_user_recharge + VALUES(new_user_recharge),
|
new_user_recharge = new_user_recharge + VALUES(new_user_recharge),
|
||||||
@ -110,6 +124,8 @@ ON DUPLICATE KEY UPDATE
|
|||||||
mifapay_recharge = mifapay_recharge + VALUES(mifapay_recharge),
|
mifapay_recharge = mifapay_recharge + VALUES(mifapay_recharge),
|
||||||
google_recharge = google_recharge + VALUES(google_recharge),
|
google_recharge = google_recharge + VALUES(google_recharge),
|
||||||
dealer_recharge = dealer_recharge + VALUES(dealer_recharge),
|
dealer_recharge = dealer_recharge + VALUES(dealer_recharge),
|
||||||
|
user_recharge = user_recharge + VALUES(user_recharge),
|
||||||
|
new_dealer_user_recharge = new_dealer_user_recharge + VALUES(new_dealer_user_recharge),
|
||||||
salary_exchange = salary_exchange + VALUES(salary_exchange),
|
salary_exchange = salary_exchange + VALUES(salary_exchange),
|
||||||
salary_transfer = salary_transfer + VALUES(salary_transfer),
|
salary_transfer = salary_transfer + VALUES(salary_transfer),
|
||||||
gift_consume = gift_consume + VALUES(gift_consume),
|
gift_consume = gift_consume + VALUES(gift_consume),
|
||||||
@ -120,20 +136,20 @@ ON DUPLICATE KEY UPDATE
|
|||||||
refreshed_at = NOW()
|
refreshed_at = NOW()
|
||||||
`, day, dashboard.DateNumber(day), c.SysOrigin, c.Country.Code, c.Country.Name,
|
`, day, dashboard.DateNumber(day), c.SysOrigin, c.Country.Code, c.Country.Name,
|
||||||
newUserRecharge.Mul(sign), c.OfficialRecharge.Mul(sign), c.MifapayRecharge.Mul(sign), c.GoogleRecharge.Mul(sign),
|
newUserRecharge.Mul(sign), c.OfficialRecharge.Mul(sign), c.MifapayRecharge.Mul(sign), c.GoogleRecharge.Mul(sign),
|
||||||
c.DealerRecharge.Mul(sign), c.SalaryExchange.Mul(sign), c.SalaryTransfer.Mul(sign), c.GiftConsume.Mul(sign), c.LuckyGiftTotalFlow.Mul(sign), c.LuckyGiftPayout.Mul(sign),
|
c.DealerRecharge.Mul(sign), c.UserRecharge.Mul(sign), newDealerUserRecharge.Mul(sign), c.SalaryExchange.Mul(sign), c.SalaryTransfer.Mul(sign), c.GiftConsume.Mul(sign), c.LuckyGiftTotalFlow.Mul(sign), c.LuckyGiftPayout.Mul(sign),
|
||||||
c.GameTotalFlow.Mul(sign), c.GamePayout.Mul(sign))
|
c.GameTotalFlow.Mul(sign), c.GamePayout.Mul(sign))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *MySQLRepository) upsertPeriodAmounts(ctx context.Context, tx *sql.Tx, c dashboard.Contribution, window dashboard.PeriodWindow, statTimezone string, newUserRecharge decimal.Decimal) error {
|
func (r *MySQLRepository) upsertPeriodAmounts(ctx context.Context, tx *sql.Tx, c dashboard.Contribution, window dashboard.PeriodWindow, statTimezone string, newUserRecharge decimal.Decimal, newDealerUserRecharge decimal.Decimal) error {
|
||||||
sign := decimal.NewFromInt(int64(c.DeltaSign))
|
sign := decimal.NewFromInt(int64(c.DeltaSign))
|
||||||
_, err := tx.ExecContext(ctx, `
|
_, err := tx.ExecContext(ctx, `
|
||||||
INSERT INTO country_dashboard_period_metric (
|
INSERT INTO country_dashboard_period_metric (
|
||||||
period_type, period_key, stat_timezone, period_name, period_start_date, period_end_date,
|
period_type, period_key, stat_timezone, period_name, period_start_date, period_end_date,
|
||||||
sys_origin, country_code, country_name, new_user_recharge, official_recharge, mifapay_recharge,
|
sys_origin, country_code, country_name, new_user_recharge, official_recharge, mifapay_recharge,
|
||||||
google_recharge, dealer_recharge, salary_exchange, salary_transfer, gift_consume, lucky_gift_total_flow, lucky_gift_payout,
|
google_recharge, dealer_recharge, user_recharge, new_dealer_user_recharge, salary_exchange, salary_transfer, gift_consume, lucky_gift_total_flow, lucky_gift_payout,
|
||||||
game_total_flow, game_payout, refreshed_at
|
game_total_flow, game_payout, refreshed_at
|
||||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())
|
||||||
ON DUPLICATE KEY UPDATE
|
ON DUPLICATE KEY UPDATE
|
||||||
period_name = VALUES(period_name),
|
period_name = VALUES(period_name),
|
||||||
period_start_date = VALUES(period_start_date),
|
period_start_date = VALUES(period_start_date),
|
||||||
@ -144,6 +160,8 @@ ON DUPLICATE KEY UPDATE
|
|||||||
mifapay_recharge = mifapay_recharge + VALUES(mifapay_recharge),
|
mifapay_recharge = mifapay_recharge + VALUES(mifapay_recharge),
|
||||||
google_recharge = google_recharge + VALUES(google_recharge),
|
google_recharge = google_recharge + VALUES(google_recharge),
|
||||||
dealer_recharge = dealer_recharge + VALUES(dealer_recharge),
|
dealer_recharge = dealer_recharge + VALUES(dealer_recharge),
|
||||||
|
user_recharge = user_recharge + VALUES(user_recharge),
|
||||||
|
new_dealer_user_recharge = new_dealer_user_recharge + VALUES(new_dealer_user_recharge),
|
||||||
salary_exchange = salary_exchange + VALUES(salary_exchange),
|
salary_exchange = salary_exchange + VALUES(salary_exchange),
|
||||||
salary_transfer = salary_transfer + VALUES(salary_transfer),
|
salary_transfer = salary_transfer + VALUES(salary_transfer),
|
||||||
gift_consume = gift_consume + VALUES(gift_consume),
|
gift_consume = gift_consume + VALUES(gift_consume),
|
||||||
@ -152,9 +170,9 @@ ON DUPLICATE KEY UPDATE
|
|||||||
game_total_flow = game_total_flow + VALUES(game_total_flow),
|
game_total_flow = game_total_flow + VALUES(game_total_flow),
|
||||||
game_payout = game_payout + VALUES(game_payout),
|
game_payout = game_payout + VALUES(game_payout),
|
||||||
refreshed_at = NOW()
|
refreshed_at = NOW()
|
||||||
`, window.Type, window.Key, statTimezone, window.Name, window.StartDate, window.EndDate,
|
`, window.Type, window.Key, statTimezone, window.Name, window.StartDate, window.EndDate,
|
||||||
c.SysOrigin, c.Country.Code, c.Country.Name, newUserRecharge.Mul(sign), c.OfficialRecharge.Mul(sign),
|
c.SysOrigin, c.Country.Code, c.Country.Name, newUserRecharge.Mul(sign), c.OfficialRecharge.Mul(sign),
|
||||||
c.MifapayRecharge.Mul(sign), c.GoogleRecharge.Mul(sign), c.DealerRecharge.Mul(sign), c.SalaryExchange.Mul(sign),
|
c.MifapayRecharge.Mul(sign), c.GoogleRecharge.Mul(sign), c.DealerRecharge.Mul(sign), c.UserRecharge.Mul(sign), newDealerUserRecharge.Mul(sign), c.SalaryExchange.Mul(sign),
|
||||||
c.SalaryTransfer.Mul(sign), c.GiftConsume.Mul(sign), c.LuckyGiftTotalFlow.Mul(sign), c.LuckyGiftPayout.Mul(sign),
|
c.SalaryTransfer.Mul(sign), c.GiftConsume.Mul(sign), c.LuckyGiftTotalFlow.Mul(sign), c.LuckyGiftPayout.Mul(sign),
|
||||||
c.GameTotalFlow.Mul(sign), c.GamePayout.Mul(sign))
|
c.GameTotalFlow.Mul(sign), c.GamePayout.Mul(sign))
|
||||||
return err
|
return err
|
||||||
|
|||||||
@ -14,18 +14,20 @@ import (
|
|||||||
const bulkInsertChunkSize = 500
|
const bulkInsertChunkSize = 500
|
||||||
|
|
||||||
type amountTotals struct {
|
type amountTotals struct {
|
||||||
newUserRecharge decimal.Decimal
|
newUserRecharge decimal.Decimal
|
||||||
officialRecharge decimal.Decimal
|
officialRecharge decimal.Decimal
|
||||||
mifapayRecharge decimal.Decimal
|
mifapayRecharge decimal.Decimal
|
||||||
googleRecharge decimal.Decimal
|
googleRecharge decimal.Decimal
|
||||||
dealerRecharge decimal.Decimal
|
dealerRecharge decimal.Decimal
|
||||||
salaryExchange decimal.Decimal
|
userRecharge decimal.Decimal
|
||||||
salaryTransfer decimal.Decimal
|
newDealerUserRecharge decimal.Decimal
|
||||||
giftConsume decimal.Decimal
|
salaryExchange decimal.Decimal
|
||||||
luckyGiftTotalFlow decimal.Decimal
|
salaryTransfer decimal.Decimal
|
||||||
luckyGiftPayout decimal.Decimal
|
giftConsume decimal.Decimal
|
||||||
gameTotalFlow decimal.Decimal
|
luckyGiftTotalFlow decimal.Decimal
|
||||||
gamePayout decimal.Decimal
|
luckyGiftPayout decimal.Decimal
|
||||||
|
gameTotalFlow decimal.Decimal
|
||||||
|
gamePayout decimal.Decimal
|
||||||
}
|
}
|
||||||
|
|
||||||
type gameAmountTotals struct {
|
type gameAmountTotals struct {
|
||||||
@ -150,12 +152,14 @@ func (r *MySQLRepository) ApplyContributionBatch(ctx context.Context, tx *sql.Tx
|
|||||||
}
|
}
|
||||||
day := dashboard.DailyDate(c.EventTime, storageZone)
|
day := dashboard.DailyDate(c.EventTime, storageZone)
|
||||||
newUserRecharge := decimal.Zero
|
newUserRecharge := decimal.Zero
|
||||||
|
newDealerUserRecharge := decimal.Zero
|
||||||
if dashboard.SamePeriod(c.UserCreatedAt, c.EventTime, dashboard.PeriodWindow{Type: dashboard.PeriodDay}, storageZone) {
|
if dashboard.SamePeriod(c.UserCreatedAt, c.EventTime, dashboard.PeriodWindow{Type: dashboard.PeriodDay}, storageZone) {
|
||||||
newUserRecharge = c.NewUserRechargeCandidate
|
newUserRecharge = c.NewUserRechargeCandidate
|
||||||
|
newDealerUserRecharge = c.NewDealerUserRecharge
|
||||||
}
|
}
|
||||||
dailyKey := dailyAmountKey{day: day, sysOrigin: c.SysOrigin, countryCode: c.Country.Code, countryName: c.Country.Name}
|
dailyKey := dailyAmountKey{day: day, sysOrigin: c.SysOrigin, countryCode: c.Country.Code, countryName: c.Country.Name}
|
||||||
totals := dailyAmounts[dailyKey]
|
totals := dailyAmounts[dailyKey]
|
||||||
totals.add(c, newUserRecharge)
|
totals.add(c, newUserRecharge, newDealerUserRecharge)
|
||||||
dailyAmounts[dailyKey] = totals
|
dailyAmounts[dailyKey] = totals
|
||||||
addDailyUserGroups(dailyUsers, c, day)
|
addDailyUserGroups(dailyUsers, c, day)
|
||||||
|
|
||||||
@ -163,8 +167,10 @@ func (r *MySQLRepository) ApplyContributionBatch(ctx context.Context, tx *sql.Tx
|
|||||||
for _, window := range dashboard.PeriodWindows(c.EventTime, zone) {
|
for _, window := range dashboard.PeriodWindows(c.EventTime, zone) {
|
||||||
startDate, endDate := windowDates(window)
|
startDate, endDate := windowDates(window)
|
||||||
newUserRecharge = decimal.Zero
|
newUserRecharge = decimal.Zero
|
||||||
|
newDealerUserRecharge = decimal.Zero
|
||||||
if dashboard.SamePeriod(c.UserCreatedAt, c.EventTime, window, zone) {
|
if dashboard.SamePeriod(c.UserCreatedAt, c.EventTime, window, zone) {
|
||||||
newUserRecharge = c.NewUserRechargeCandidate
|
newUserRecharge = c.NewUserRechargeCandidate
|
||||||
|
newDealerUserRecharge = c.NewDealerUserRecharge
|
||||||
}
|
}
|
||||||
periodKey := periodAmountKey{
|
periodKey := periodAmountKey{
|
||||||
periodType: window.Type, periodKey: window.Key, statTimezone: statTimezone,
|
periodType: window.Type, periodKey: window.Key, statTimezone: statTimezone,
|
||||||
@ -172,7 +178,7 @@ func (r *MySQLRepository) ApplyContributionBatch(ctx context.Context, tx *sql.Tx
|
|||||||
sysOrigin: c.SysOrigin, countryCode: c.Country.Code, countryName: c.Country.Name,
|
sysOrigin: c.SysOrigin, countryCode: c.Country.Code, countryName: c.Country.Name,
|
||||||
}
|
}
|
||||||
periodTotal := periodAmounts[periodKey]
|
periodTotal := periodAmounts[periodKey]
|
||||||
periodTotal.add(c, newUserRecharge)
|
periodTotal.add(c, newUserRecharge, newDealerUserRecharge)
|
||||||
periodAmounts[periodKey] = periodTotal
|
periodAmounts[periodKey] = periodTotal
|
||||||
addPeriodUserGroups(periodUsers, c, window, statTimezone)
|
addPeriodUserGroups(periodUsers, c, window, statTimezone)
|
||||||
|
|
||||||
@ -250,13 +256,15 @@ func (r *MySQLRepository) ApplyContributionBatch(ctx context.Context, tx *sql.Tx
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *amountTotals) add(c dashboard.Contribution, newUserRecharge decimal.Decimal) {
|
func (t *amountTotals) add(c dashboard.Contribution, newUserRecharge decimal.Decimal, newDealerUserRecharge decimal.Decimal) {
|
||||||
sign := decimal.NewFromInt(int64(c.DeltaSign))
|
sign := decimal.NewFromInt(int64(c.DeltaSign))
|
||||||
t.newUserRecharge = t.newUserRecharge.Add(newUserRecharge.Mul(sign))
|
t.newUserRecharge = t.newUserRecharge.Add(newUserRecharge.Mul(sign))
|
||||||
t.officialRecharge = t.officialRecharge.Add(c.OfficialRecharge.Mul(sign))
|
t.officialRecharge = t.officialRecharge.Add(c.OfficialRecharge.Mul(sign))
|
||||||
t.mifapayRecharge = t.mifapayRecharge.Add(c.MifapayRecharge.Mul(sign))
|
t.mifapayRecharge = t.mifapayRecharge.Add(c.MifapayRecharge.Mul(sign))
|
||||||
t.googleRecharge = t.googleRecharge.Add(c.GoogleRecharge.Mul(sign))
|
t.googleRecharge = t.googleRecharge.Add(c.GoogleRecharge.Mul(sign))
|
||||||
t.dealerRecharge = t.dealerRecharge.Add(c.DealerRecharge.Mul(sign))
|
t.dealerRecharge = t.dealerRecharge.Add(c.DealerRecharge.Mul(sign))
|
||||||
|
t.userRecharge = t.userRecharge.Add(c.UserRecharge.Mul(sign))
|
||||||
|
t.newDealerUserRecharge = t.newDealerUserRecharge.Add(newDealerUserRecharge.Mul(sign))
|
||||||
t.salaryExchange = t.salaryExchange.Add(c.SalaryExchange.Mul(sign))
|
t.salaryExchange = t.salaryExchange.Add(c.SalaryExchange.Mul(sign))
|
||||||
t.salaryTransfer = t.salaryTransfer.Add(c.SalaryTransfer.Mul(sign))
|
t.salaryTransfer = t.salaryTransfer.Add(c.SalaryTransfer.Mul(sign))
|
||||||
t.giftConsume = t.giftConsume.Add(c.GiftConsume.Mul(sign))
|
t.giftConsume = t.giftConsume.Add(c.GiftConsume.Mul(sign))
|
||||||
@ -268,7 +276,8 @@ func (t *amountTotals) add(c dashboard.Contribution, newUserRecharge decimal.Dec
|
|||||||
|
|
||||||
func (t amountTotals) empty() bool {
|
func (t amountTotals) empty() bool {
|
||||||
return t.newUserRecharge.IsZero() && t.officialRecharge.IsZero() && t.mifapayRecharge.IsZero() &&
|
return t.newUserRecharge.IsZero() && t.officialRecharge.IsZero() && t.mifapayRecharge.IsZero() &&
|
||||||
t.googleRecharge.IsZero() && t.dealerRecharge.IsZero() && t.salaryExchange.IsZero() &&
|
t.googleRecharge.IsZero() && t.dealerRecharge.IsZero() && t.userRecharge.IsZero() &&
|
||||||
|
t.newDealerUserRecharge.IsZero() && t.salaryExchange.IsZero() &&
|
||||||
t.salaryTransfer.IsZero() &&
|
t.salaryTransfer.IsZero() &&
|
||||||
t.giftConsume.IsZero() && t.luckyGiftTotalFlow.IsZero() && t.luckyGiftPayout.IsZero() &&
|
t.giftConsume.IsZero() && t.luckyGiftTotalFlow.IsZero() && t.luckyGiftPayout.IsZero() &&
|
||||||
t.gameTotalFlow.IsZero() && t.gamePayout.IsZero()
|
t.gameTotalFlow.IsZero() && t.gamePayout.IsZero()
|
||||||
@ -299,6 +308,9 @@ func addDailyUserGroups(groups map[dailyUserKey]map[int64]struct{}, c dashboard.
|
|||||||
if c.GameUser {
|
if c.GameUser {
|
||||||
addDailyUser(groups, c, day, dashboard.MetricGameUser)
|
addDailyUser(groups, c, day, dashboard.MetricGameUser)
|
||||||
}
|
}
|
||||||
|
if c.UserRecharge.GreaterThan(decimal.Zero) {
|
||||||
|
addDailyUser(groups, c, day, dashboard.MetricRechargeUser)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func addPeriodUserGroups(groups map[periodUserKey]map[int64]struct{}, c dashboard.Contribution, window dashboard.PeriodWindow, statTimezone string) {
|
func addPeriodUserGroups(groups map[periodUserKey]map[int64]struct{}, c dashboard.Contribution, window dashboard.PeriodWindow, statTimezone string) {
|
||||||
@ -314,6 +326,9 @@ func addPeriodUserGroups(groups map[periodUserKey]map[int64]struct{}, c dashboar
|
|||||||
if c.GameUser {
|
if c.GameUser {
|
||||||
addPeriodUser(groups, c, window, statTimezone, dashboard.MetricGameUser)
|
addPeriodUser(groups, c, window, statTimezone, dashboard.MetricGameUser)
|
||||||
}
|
}
|
||||||
|
if c.UserRecharge.GreaterThan(decimal.Zero) {
|
||||||
|
addPeriodUser(groups, c, window, statTimezone, dashboard.MetricRechargeUser)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func addDailyUser(groups map[dailyUserKey]map[int64]struct{}, c dashboard.Contribution, day time.Time, metricType string) {
|
func addDailyUser(groups map[dailyUserKey]map[int64]struct{}, c dashboard.Contribution, day time.Time, metricType string) {
|
||||||
|
|||||||
@ -11,9 +11,9 @@ func (r *MySQLRepository) upsertDailyAmountTotals(ctx context.Context, tx *sql.T
|
|||||||
INSERT INTO country_dashboard_daily_metric (
|
INSERT INTO country_dashboard_daily_metric (
|
||||||
stat_date, date_number, sys_origin, country_code, country_name,
|
stat_date, date_number, sys_origin, country_code, country_name,
|
||||||
new_user_recharge, official_recharge, mifapay_recharge, google_recharge,
|
new_user_recharge, official_recharge, mifapay_recharge, google_recharge,
|
||||||
dealer_recharge, salary_exchange, salary_transfer, gift_consume, lucky_gift_total_flow, lucky_gift_payout,
|
dealer_recharge, user_recharge, new_dealer_user_recharge, salary_exchange, salary_transfer, gift_consume, lucky_gift_total_flow, lucky_gift_payout,
|
||||||
game_total_flow, game_payout, refreshed_at
|
game_total_flow, game_payout, refreshed_at
|
||||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())
|
||||||
ON DUPLICATE KEY UPDATE
|
ON DUPLICATE KEY UPDATE
|
||||||
country_name = VALUES(country_name),
|
country_name = VALUES(country_name),
|
||||||
new_user_recharge = new_user_recharge + VALUES(new_user_recharge),
|
new_user_recharge = new_user_recharge + VALUES(new_user_recharge),
|
||||||
@ -21,6 +21,8 @@ ON DUPLICATE KEY UPDATE
|
|||||||
mifapay_recharge = mifapay_recharge + VALUES(mifapay_recharge),
|
mifapay_recharge = mifapay_recharge + VALUES(mifapay_recharge),
|
||||||
google_recharge = google_recharge + VALUES(google_recharge),
|
google_recharge = google_recharge + VALUES(google_recharge),
|
||||||
dealer_recharge = dealer_recharge + VALUES(dealer_recharge),
|
dealer_recharge = dealer_recharge + VALUES(dealer_recharge),
|
||||||
|
user_recharge = user_recharge + VALUES(user_recharge),
|
||||||
|
new_dealer_user_recharge = new_dealer_user_recharge + VALUES(new_dealer_user_recharge),
|
||||||
salary_exchange = salary_exchange + VALUES(salary_exchange),
|
salary_exchange = salary_exchange + VALUES(salary_exchange),
|
||||||
salary_transfer = salary_transfer + VALUES(salary_transfer),
|
salary_transfer = salary_transfer + VALUES(salary_transfer),
|
||||||
gift_consume = gift_consume + VALUES(gift_consume),
|
gift_consume = gift_consume + VALUES(gift_consume),
|
||||||
@ -31,7 +33,7 @@ ON DUPLICATE KEY UPDATE
|
|||||||
refreshed_at = NOW()
|
refreshed_at = NOW()
|
||||||
`, key.day, dateNumber(key.day), key.sysOrigin, key.countryCode, key.countryName,
|
`, key.day, dateNumber(key.day), key.sysOrigin, key.countryCode, key.countryName,
|
||||||
totals.newUserRecharge, totals.officialRecharge, totals.mifapayRecharge, totals.googleRecharge,
|
totals.newUserRecharge, totals.officialRecharge, totals.mifapayRecharge, totals.googleRecharge,
|
||||||
totals.dealerRecharge, totals.salaryExchange, totals.salaryTransfer, totals.giftConsume, totals.luckyGiftTotalFlow, totals.luckyGiftPayout,
|
totals.dealerRecharge, totals.userRecharge, totals.newDealerUserRecharge, totals.salaryExchange, totals.salaryTransfer, totals.giftConsume, totals.luckyGiftTotalFlow, totals.luckyGiftPayout,
|
||||||
totals.gameTotalFlow, totals.gamePayout)
|
totals.gameTotalFlow, totals.gamePayout)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -41,9 +43,9 @@ func (r *MySQLRepository) upsertPeriodAmountTotals(ctx context.Context, tx *sql.
|
|||||||
INSERT INTO country_dashboard_period_metric (
|
INSERT INTO country_dashboard_period_metric (
|
||||||
period_type, period_key, stat_timezone, period_name, period_start_date, period_end_date,
|
period_type, period_key, stat_timezone, period_name, period_start_date, period_end_date,
|
||||||
sys_origin, country_code, country_name, new_user_recharge, official_recharge, mifapay_recharge,
|
sys_origin, country_code, country_name, new_user_recharge, official_recharge, mifapay_recharge,
|
||||||
google_recharge, dealer_recharge, salary_exchange, salary_transfer, gift_consume, lucky_gift_total_flow, lucky_gift_payout,
|
google_recharge, dealer_recharge, user_recharge, new_dealer_user_recharge, salary_exchange, salary_transfer, gift_consume, lucky_gift_total_flow, lucky_gift_payout,
|
||||||
game_total_flow, game_payout, refreshed_at
|
game_total_flow, game_payout, refreshed_at
|
||||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())
|
||||||
ON DUPLICATE KEY UPDATE
|
ON DUPLICATE KEY UPDATE
|
||||||
period_name = VALUES(period_name),
|
period_name = VALUES(period_name),
|
||||||
period_start_date = VALUES(period_start_date),
|
period_start_date = VALUES(period_start_date),
|
||||||
@ -54,6 +56,8 @@ ON DUPLICATE KEY UPDATE
|
|||||||
mifapay_recharge = mifapay_recharge + VALUES(mifapay_recharge),
|
mifapay_recharge = mifapay_recharge + VALUES(mifapay_recharge),
|
||||||
google_recharge = google_recharge + VALUES(google_recharge),
|
google_recharge = google_recharge + VALUES(google_recharge),
|
||||||
dealer_recharge = dealer_recharge + VALUES(dealer_recharge),
|
dealer_recharge = dealer_recharge + VALUES(dealer_recharge),
|
||||||
|
user_recharge = user_recharge + VALUES(user_recharge),
|
||||||
|
new_dealer_user_recharge = new_dealer_user_recharge + VALUES(new_dealer_user_recharge),
|
||||||
salary_exchange = salary_exchange + VALUES(salary_exchange),
|
salary_exchange = salary_exchange + VALUES(salary_exchange),
|
||||||
salary_transfer = salary_transfer + VALUES(salary_transfer),
|
salary_transfer = salary_transfer + VALUES(salary_transfer),
|
||||||
gift_consume = gift_consume + VALUES(gift_consume),
|
gift_consume = gift_consume + VALUES(gift_consume),
|
||||||
@ -62,9 +66,9 @@ ON DUPLICATE KEY UPDATE
|
|||||||
game_total_flow = game_total_flow + VALUES(game_total_flow),
|
game_total_flow = game_total_flow + VALUES(game_total_flow),
|
||||||
game_payout = game_payout + VALUES(game_payout),
|
game_payout = game_payout + VALUES(game_payout),
|
||||||
refreshed_at = NOW()
|
refreshed_at = NOW()
|
||||||
`, key.periodType, key.periodKey, key.statTimezone, key.periodName, ptrOrNil(key.startDate), ptrOrNil(key.endDate),
|
`, key.periodType, key.periodKey, key.statTimezone, key.periodName, ptrOrNil(key.startDate), ptrOrNil(key.endDate),
|
||||||
key.sysOrigin, key.countryCode, key.countryName, totals.newUserRecharge, totals.officialRecharge,
|
key.sysOrigin, key.countryCode, key.countryName, totals.newUserRecharge, totals.officialRecharge,
|
||||||
totals.mifapayRecharge, totals.googleRecharge, totals.dealerRecharge, totals.salaryExchange,
|
totals.mifapayRecharge, totals.googleRecharge, totals.dealerRecharge, totals.userRecharge, totals.newDealerUserRecharge, totals.salaryExchange,
|
||||||
totals.salaryTransfer, totals.giftConsume, totals.luckyGiftTotalFlow, totals.luckyGiftPayout,
|
totals.salaryTransfer, totals.giftConsume, totals.luckyGiftTotalFlow, totals.luckyGiftPayout,
|
||||||
totals.gameTotalFlow, totals.gamePayout)
|
totals.gameTotalFlow, totals.gamePayout)
|
||||||
return err
|
return err
|
||||||
|
|||||||
@ -30,12 +30,13 @@ type officialRechargeRow struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type mifapayRechargeRow struct {
|
type mifapayRechargeRow struct {
|
||||||
id string
|
id string
|
||||||
userID int64
|
userID int64
|
||||||
sysOrigin string
|
sysOrigin string
|
||||||
amount decimal.Decimal
|
factoryCode string
|
||||||
eventTime time.Time
|
amount decimal.Decimal
|
||||||
user dashboard.UserCountry
|
eventTime time.Time
|
||||||
|
user dashboard.UserCountry
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *MySQLRepository) BuildRechargeReconcileEvents(ctx context.Context, since time.Time,
|
func (r *MySQLRepository) BuildRechargeReconcileEvents(ctx context.Context, since time.Time,
|
||||||
@ -79,6 +80,7 @@ func (r *MySQLRepository) BuildRechargeReconcileEvents(ctx context.Context, sinc
|
|||||||
}
|
}
|
||||||
if row.payPlatform == "GOOGLE" {
|
if row.payPlatform == "GOOGLE" {
|
||||||
contribution.GoogleRecharge = row.unitPrice
|
contribution.GoogleRecharge = row.unitPrice
|
||||||
|
contribution.UserRecharge = row.unitPrice
|
||||||
}
|
}
|
||||||
events = append(events, dashboard.Event{
|
events = append(events, dashboard.Event{
|
||||||
EventKey: rechargeReconcileEventKey(reconcileOfficialSource, row.id),
|
EventKey: rechargeReconcileEventKey(reconcileOfficialSource, row.id),
|
||||||
@ -102,9 +104,12 @@ func (r *MySQLRepository) BuildRechargeReconcileEvents(ctx context.Context, sinc
|
|||||||
EventTime: row.eventTime,
|
EventTime: row.eventTime,
|
||||||
UserCreatedAt: row.user.CreatedAt,
|
UserCreatedAt: row.user.CreatedAt,
|
||||||
NewUserRechargeCandidate: row.amount,
|
NewUserRechargeCandidate: row.amount,
|
||||||
MifapayRecharge: row.amount,
|
UserRecharge: row.amount,
|
||||||
RechargeDetail: mifapayRechargeDetail(row),
|
RechargeDetail: mifapayRechargeDetail(row),
|
||||||
}
|
}
|
||||||
|
if row.factoryCode == "MIFA_PAY" {
|
||||||
|
contribution.MifapayRecharge = row.amount
|
||||||
|
}
|
||||||
events = append(events, dashboard.Event{
|
events = append(events, dashboard.Event{
|
||||||
EventKey: rechargeReconcileEventKey(reconcileMifapaySource, row.id),
|
EventKey: rechargeReconcileEventKey(reconcileMifapaySource, row.id),
|
||||||
Source: reconcileMifapaySource,
|
Source: reconcileMifapaySource,
|
||||||
@ -193,7 +198,7 @@ LIMIT ?`, r.cfg.Dashboard.UnknownCountryCode, r.cfg.Dashboard.UnknownCountryCode
|
|||||||
func (r *MySQLRepository) listMifapayRechargeRows(ctx context.Context, since time.Time,
|
func (r *MySQLRepository) listMifapayRechargeRows(ctx context.Context, since time.Time,
|
||||||
limit int) ([]mifapayRechargeRow, error) {
|
limit int) ([]mifapayRechargeRow, error) {
|
||||||
rows, err := r.db.QueryContext(ctx, `
|
rows, err := r.db.QueryContext(ctx, `
|
||||||
SELECT CAST(o.id AS CHAR), o.user_id, o.sys_origin, o.compute_usd_amount, o.create_time,
|
SELECT CAST(o.id AS CHAR), o.user_id, o.sys_origin, o.factory_code, o.compute_usd_amount, o.create_time,
|
||||||
u.id, u.origin_sys, IFNULL(NULLIF(u.country_code, ''), ?),
|
u.id, u.origin_sys, IFNULL(NULLIF(u.country_code, ''), ?),
|
||||||
IFNULL(NULLIF(u.country_name, ''), IFNULL(NULLIF(u.country_code, ''), ?)),
|
IFNULL(NULLIF(u.country_name, ''), IFNULL(NULLIF(u.country_code, ''), ?)),
|
||||||
IFNULL(u.is_del, 0), u.create_time, u.update_time
|
IFNULL(u.is_del, 0), u.create_time, u.update_time
|
||||||
@ -201,7 +206,6 @@ FROM order_user_purchase_pay o
|
|||||||
JOIN user_base_info u ON u.id = o.user_id
|
JOIN user_base_info u ON u.id = o.user_id
|
||||||
WHERE o.create_time >= ?
|
WHERE o.create_time >= ?
|
||||||
AND o.evn = 'PROD'
|
AND o.evn = 'PROD'
|
||||||
AND o.factory_code = 'MIFA_PAY'
|
|
||||||
AND o.pay_status = 'SUCCESSFUL'
|
AND o.pay_status = 'SUCCESSFUL'
|
||||||
AND o.receipt_type = 'PAYMENT'
|
AND o.receipt_type = 'PAYMENT'
|
||||||
AND o.refund_status = 'NONE'
|
AND o.refund_status = 'NONE'
|
||||||
@ -217,7 +221,7 @@ LIMIT ?`, r.cfg.Dashboard.UnknownCountryCode, r.cfg.Dashboard.UnknownCountryCode
|
|||||||
var countryCode, countryName string
|
var countryCode, countryName string
|
||||||
var isDeleted bool
|
var isDeleted bool
|
||||||
var userCreatedAt, userUpdatedAt sql.NullTime
|
var userCreatedAt, userUpdatedAt sql.NullTime
|
||||||
if err := rows.Scan(&item.id, &item.userID, &item.sysOrigin, &item.amount,
|
if err := rows.Scan(&item.id, &item.userID, &item.sysOrigin, &item.factoryCode, &item.amount,
|
||||||
&item.eventTime, &item.user.UserID, &item.user.SysOrigin, &countryCode,
|
&item.eventTime, &item.user.UserID, &item.user.SysOrigin, &countryCode,
|
||||||
&countryName, &isDeleted, &userCreatedAt, &userUpdatedAt); err != nil {
|
&countryName, &isDeleted, &userCreatedAt, &userUpdatedAt); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -272,10 +276,14 @@ func officialRechargeDetail(row officialRechargeRow) *dashboard.RechargeDetail {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func mifapayRechargeDetail(row mifapayRechargeRow) *dashboard.RechargeDetail {
|
func mifapayRechargeDetail(row mifapayRechargeRow) *dashboard.RechargeDetail {
|
||||||
|
sourceType := "THIRD_PARTY"
|
||||||
|
if row.factoryCode == "MIFA_PAY" {
|
||||||
|
sourceType = "MIFAPAY"
|
||||||
|
}
|
||||||
return &dashboard.RechargeDetail{
|
return &dashboard.RechargeDetail{
|
||||||
SourceType: "MIFAPAY",
|
SourceType: sourceType,
|
||||||
RecordID: row.id,
|
RecordID: row.id,
|
||||||
SourceChannel: "MIFA_PAY",
|
SourceChannel: row.factoryCode,
|
||||||
SysOrigin: row.user.SysOrigin,
|
SysOrigin: row.user.SysOrigin,
|
||||||
UserID: row.userID,
|
UserID: row.userID,
|
||||||
Country: row.user.Country,
|
Country: row.user.Country,
|
||||||
|
|||||||
@ -64,6 +64,8 @@ const createDailyMetricTable = `CREATE TABLE IF NOT EXISTS country_dashboard_dai
|
|||||||
mifapay_recharge decimal(20,2) NOT NULL DEFAULT 0,
|
mifapay_recharge decimal(20,2) NOT NULL DEFAULT 0,
|
||||||
google_recharge decimal(20,2) NOT NULL DEFAULT 0,
|
google_recharge decimal(20,2) NOT NULL DEFAULT 0,
|
||||||
dealer_recharge decimal(20,2) NOT NULL DEFAULT 0,
|
dealer_recharge decimal(20,2) NOT NULL DEFAULT 0,
|
||||||
|
user_recharge decimal(20,2) NOT NULL DEFAULT 0,
|
||||||
|
new_dealer_user_recharge decimal(20,2) NOT NULL DEFAULT 0,
|
||||||
salary_exchange decimal(20,2) NOT NULL DEFAULT 0,
|
salary_exchange decimal(20,2) NOT NULL DEFAULT 0,
|
||||||
salary_transfer decimal(20,2) NOT NULL DEFAULT 0,
|
salary_transfer decimal(20,2) NOT NULL DEFAULT 0,
|
||||||
gift_consume decimal(20,2) NOT NULL DEFAULT 0,
|
gift_consume decimal(20,2) NOT NULL DEFAULT 0,
|
||||||
@ -71,6 +73,7 @@ const createDailyMetricTable = `CREATE TABLE IF NOT EXISTS country_dashboard_dai
|
|||||||
lucky_gift_user bigint NOT NULL DEFAULT 0,
|
lucky_gift_user bigint NOT NULL DEFAULT 0,
|
||||||
lucky_gift_payout decimal(20,2) NOT NULL DEFAULT 0,
|
lucky_gift_payout decimal(20,2) NOT NULL DEFAULT 0,
|
||||||
game_total_flow decimal(20,2) NOT NULL DEFAULT 0,
|
game_total_flow decimal(20,2) NOT NULL DEFAULT 0,
|
||||||
|
daily_recharge_user bigint NOT NULL DEFAULT 0,
|
||||||
game_user bigint NOT NULL DEFAULT 0,
|
game_user bigint NOT NULL DEFAULT 0,
|
||||||
game_payout decimal(20,2) NOT NULL DEFAULT 0,
|
game_payout decimal(20,2) NOT NULL DEFAULT 0,
|
||||||
refreshed_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
refreshed_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
@ -110,6 +113,8 @@ const createPeriodMetricTable = `CREATE TABLE IF NOT EXISTS country_dashboard_pe
|
|||||||
mifapay_recharge decimal(20,2) NOT NULL DEFAULT 0,
|
mifapay_recharge decimal(20,2) NOT NULL DEFAULT 0,
|
||||||
google_recharge decimal(20,2) NOT NULL DEFAULT 0,
|
google_recharge decimal(20,2) NOT NULL DEFAULT 0,
|
||||||
dealer_recharge decimal(20,2) NOT NULL DEFAULT 0,
|
dealer_recharge decimal(20,2) NOT NULL DEFAULT 0,
|
||||||
|
user_recharge decimal(20,2) NOT NULL DEFAULT 0,
|
||||||
|
new_dealer_user_recharge decimal(20,2) NOT NULL DEFAULT 0,
|
||||||
salary_exchange decimal(20,2) NOT NULL DEFAULT 0,
|
salary_exchange decimal(20,2) NOT NULL DEFAULT 0,
|
||||||
salary_transfer decimal(20,2) NOT NULL DEFAULT 0,
|
salary_transfer decimal(20,2) NOT NULL DEFAULT 0,
|
||||||
gift_consume decimal(20,2) NOT NULL DEFAULT 0,
|
gift_consume decimal(20,2) NOT NULL DEFAULT 0,
|
||||||
@ -117,6 +122,7 @@ const createPeriodMetricTable = `CREATE TABLE IF NOT EXISTS country_dashboard_pe
|
|||||||
lucky_gift_user bigint NOT NULL DEFAULT 0,
|
lucky_gift_user bigint NOT NULL DEFAULT 0,
|
||||||
lucky_gift_payout decimal(20,2) NOT NULL DEFAULT 0,
|
lucky_gift_payout decimal(20,2) NOT NULL DEFAULT 0,
|
||||||
game_total_flow decimal(20,2) NOT NULL DEFAULT 0,
|
game_total_flow decimal(20,2) NOT NULL DEFAULT 0,
|
||||||
|
daily_recharge_user bigint NOT NULL DEFAULT 0,
|
||||||
game_user bigint NOT NULL DEFAULT 0,
|
game_user bigint NOT NULL DEFAULT 0,
|
||||||
game_payout decimal(20,2) NOT NULL DEFAULT 0,
|
game_payout decimal(20,2) NOT NULL DEFAULT 0,
|
||||||
refreshed_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
refreshed_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
@ -134,6 +140,30 @@ func (r *MySQLRepository) ensureMetricColumns(ctx context.Context) error {
|
|||||||
"ALTER TABLE country_dashboard_period_metric ADD COLUMN salary_transfer decimal(20,2) NOT NULL DEFAULT 0 AFTER salary_exchange"); err != nil {
|
"ALTER TABLE country_dashboard_period_metric ADD COLUMN salary_transfer decimal(20,2) NOT NULL DEFAULT 0 AFTER salary_exchange"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := r.addColumnIfMissing(ctx, "country_dashboard_daily_metric", "user_recharge",
|
||||||
|
"ALTER TABLE country_dashboard_daily_metric ADD COLUMN user_recharge decimal(20,2) NOT NULL DEFAULT 0 AFTER dealer_recharge"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := r.addColumnIfMissing(ctx, "country_dashboard_period_metric", "user_recharge",
|
||||||
|
"ALTER TABLE country_dashboard_period_metric ADD COLUMN user_recharge decimal(20,2) NOT NULL DEFAULT 0 AFTER dealer_recharge"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := r.addColumnIfMissing(ctx, "country_dashboard_daily_metric", "new_dealer_user_recharge",
|
||||||
|
"ALTER TABLE country_dashboard_daily_metric ADD COLUMN new_dealer_user_recharge decimal(20,2) NOT NULL DEFAULT 0 AFTER user_recharge"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := r.addColumnIfMissing(ctx, "country_dashboard_period_metric", "new_dealer_user_recharge",
|
||||||
|
"ALTER TABLE country_dashboard_period_metric ADD COLUMN new_dealer_user_recharge decimal(20,2) NOT NULL DEFAULT 0 AFTER user_recharge"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := r.addColumnIfMissing(ctx, "country_dashboard_daily_metric", "daily_recharge_user",
|
||||||
|
"ALTER TABLE country_dashboard_daily_metric ADD COLUMN daily_recharge_user bigint NOT NULL DEFAULT 0 AFTER game_total_flow"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := r.addColumnIfMissing(ctx, "country_dashboard_period_metric", "daily_recharge_user",
|
||||||
|
"ALTER TABLE country_dashboard_period_metric ADD COLUMN daily_recharge_user bigint NOT NULL DEFAULT 0 AFTER game_total_flow"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return r.addIndexIfMissing(ctx, "dashboard_cdc_user_country", "idx_dashboard_cdc_user_country_origin_created",
|
return r.addIndexIfMissing(ctx, "dashboard_cdc_user_country", "idx_dashboard_cdc_user_country_origin_created",
|
||||||
"ALTER TABLE dashboard_cdc_user_country ADD INDEX idx_dashboard_cdc_user_country_origin_created (sys_origin, user_created_at, country_code)")
|
"ALTER TABLE dashboard_cdc_user_country ADD INDEX idx_dashboard_cdc_user_country_origin_created (sys_origin, user_created_at, country_code)")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -178,6 +178,8 @@ func dailyMetricColumn(metricType string) string {
|
|||||||
return "lucky_gift_user"
|
return "lucky_gift_user"
|
||||||
case dashboard.MetricGameUser:
|
case dashboard.MetricGameUser:
|
||||||
return "game_user"
|
return "game_user"
|
||||||
|
case dashboard.MetricRechargeUser:
|
||||||
|
return "daily_recharge_user"
|
||||||
default:
|
default:
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|||||||
85
migrations/002_dashboard_recharge_user_metrics.sql
Normal file
85
migrations/002_dashboard_recharge_user_metrics.sql
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
SET @current_schema = DATABASE();
|
||||||
|
|
||||||
|
SET @ddl = IF(
|
||||||
|
NOT EXISTS (
|
||||||
|
SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = @current_schema
|
||||||
|
AND TABLE_NAME = 'country_dashboard_daily_metric'
|
||||||
|
AND COLUMN_NAME = 'daily_recharge_user'
|
||||||
|
),
|
||||||
|
'ALTER TABLE `country_dashboard_daily_metric` ADD COLUMN `daily_recharge_user` bigint NOT NULL DEFAULT 0 COMMENT ''当日充值用户数'' AFTER `country_new_user`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @ddl;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
SET @ddl = IF(
|
||||||
|
NOT EXISTS (
|
||||||
|
SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = @current_schema
|
||||||
|
AND TABLE_NAME = 'country_dashboard_period_metric'
|
||||||
|
AND COLUMN_NAME = 'daily_recharge_user'
|
||||||
|
),
|
||||||
|
'ALTER TABLE `country_dashboard_period_metric` ADD COLUMN `daily_recharge_user` bigint NOT NULL DEFAULT 0 COMMENT ''当日充值用户数'' AFTER `daily_active_user`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @ddl;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
SET @ddl = IF(
|
||||||
|
NOT EXISTS (
|
||||||
|
SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = @current_schema
|
||||||
|
AND TABLE_NAME = 'country_dashboard_daily_metric'
|
||||||
|
AND COLUMN_NAME = 'user_recharge'
|
||||||
|
),
|
||||||
|
'ALTER TABLE `country_dashboard_daily_metric` ADD COLUMN `user_recharge` decimal(20,2) NOT NULL DEFAULT 0.00 COMMENT ''用户充值'' AFTER `dealer_recharge`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @ddl;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
SET @ddl = IF(
|
||||||
|
NOT EXISTS (
|
||||||
|
SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = @current_schema
|
||||||
|
AND TABLE_NAME = 'country_dashboard_period_metric'
|
||||||
|
AND COLUMN_NAME = 'user_recharge'
|
||||||
|
),
|
||||||
|
'ALTER TABLE `country_dashboard_period_metric` ADD COLUMN `user_recharge` decimal(20,2) NOT NULL DEFAULT 0.00 COMMENT ''用户充值'' AFTER `dealer_recharge`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @ddl;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
SET @ddl = IF(
|
||||||
|
NOT EXISTS (
|
||||||
|
SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = @current_schema
|
||||||
|
AND TABLE_NAME = 'country_dashboard_daily_metric'
|
||||||
|
AND COLUMN_NAME = 'new_dealer_user_recharge'
|
||||||
|
),
|
||||||
|
'ALTER TABLE `country_dashboard_daily_metric` ADD COLUMN `new_dealer_user_recharge` decimal(20,2) NOT NULL DEFAULT 0.00 COMMENT ''新增币商用户充值'' AFTER `user_recharge`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @ddl;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
SET @ddl = IF(
|
||||||
|
NOT EXISTS (
|
||||||
|
SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = @current_schema
|
||||||
|
AND TABLE_NAME = 'country_dashboard_period_metric'
|
||||||
|
AND COLUMN_NAME = 'new_dealer_user_recharge'
|
||||||
|
),
|
||||||
|
'ALTER TABLE `country_dashboard_period_metric` ADD COLUMN `new_dealer_user_recharge` decimal(20,2) NOT NULL DEFAULT 0.00 COMMENT ''新增币商用户充值'' AFTER `user_recharge`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @ddl;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
Loading…
x
Reference in New Issue
Block a user