feat: 按原型更新商务明细与游戏分析并清理临时资料
This commit is contained in:
@@ -79,6 +79,9 @@ type analyticsAggPO struct {
|
||||
|
||||
func analyticsRoot(db *gorm.DB, kind business.AnalyticsKind, scope business.AnalyticsScope, f business.AnalyticsFilter, table string, mode int, pay bool) (*gorm.DB, string) {
|
||||
q := analyticsQuery(db, scope, f, table, mode)
|
||||
if kind == business.GameAnalytics {
|
||||
q = q.Where("(r.source_db,r.game_id) IN (?)", approvedGamesQuery(db, scope.Viewer, f.Sources).Select("g.source_db,g.id"))
|
||||
}
|
||||
id := "r.game_id"
|
||||
if kind == business.ChannelAnalytics {
|
||||
id = "r.promote_id"
|
||||
@@ -124,6 +127,16 @@ func (r *analyticsRepo) Aggregate(ctx context.Context, kind business.AnalyticsKi
|
||||
if empty || !available {
|
||||
return result, nil
|
||||
}
|
||||
if kind == business.GameAnalytics {
|
||||
available, err := approvedGamesAvailable(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !available {
|
||||
result.Available = false
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
for _, table := range []string{"tab_sw_report_day", "tab_sw_report_day_key"} {
|
||||
available, err := businessTableAvailable(db, table)
|
||||
if err != nil {
|
||||
|
||||
@@ -12,6 +12,7 @@ func prepareAnalyticsData(t *testing.T) (*gorm.DB, business.AnalyticsRepo, busin
|
||||
t.Helper()
|
||||
db, _ := prepareChannels(t)
|
||||
for _, sql := range []string{
|
||||
"INSERT INTO tab_promote_apply VALUES('hw',100,1,1)",
|
||||
"ALTER TABLE tab_sw_report_day ADD COLUMN game_name TEXT",
|
||||
"ALTER TABLE tab_sw_report_day_key ADD COLUMN game_name TEXT",
|
||||
"UPDATE tab_sw_report_day SET game_name=CASE WHEN game_id=1 THEN '历史游戏甲' ELSE '游戏乙' END",
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package business
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
"kra/internal/biz/business"
|
||||
)
|
||||
|
||||
func approvedGamesAvailable(db *gorm.DB) (bool, error) {
|
||||
for _, table := range []string{"tab_game", "tab_promote", "tab_promote_apply"} {
|
||||
available, err := businessTableAvailable(db, table)
|
||||
if err != nil || !available {
|
||||
return available, err
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// 游戏可选范围来自可见渠道的有效申请,不受统计时是否包含下级的开关影响。
|
||||
// 用平台和 ID 配对,避免同号游戏或其他商务的申请扩大可选范围。
|
||||
func approvedGamesQuery(db *gorm.DB, viewer business.UserScope, sources []string) *gorm.DB {
|
||||
promotes := ledgerBasePromotes(db, business.LedgerScope{Viewer: viewer, IncludeSub: true, Unrestricted: viewer.All}, business.LedgerFilter{Sources: sources}, "approved_p").Select("approved_p.source_db,approved_p.id")
|
||||
applications := db.Table("tab_promote_apply a").Select("a.source_db,a.game_id").Where("a.status=1").Where("(a.source_db,a.promote_id) IN (?)", promotes)
|
||||
q := db.Table("tab_game g").Where("(g.source_db,g.id) IN (?)", applications)
|
||||
if len(sources) > 0 {
|
||||
q = q.Where("g.source_db IN ?", sources)
|
||||
}
|
||||
return q
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package business
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"kra/internal/biz/business"
|
||||
)
|
||||
|
||||
func TestGameOptionsRequireVisibleApprovedApplications(t *testing.T) {
|
||||
db, _ := prepareChannels(t)
|
||||
for _, sql := range []string{
|
||||
"INSERT INTO tab_game VALUES('lx',3,'子渠道游戏'),('lx',4,'未申请包服'),('lx',5,'其他商务游戏'),('lx',6,'待审核游戏')",
|
||||
"INSERT INTO tab_promote_apply VALUES('lx',104,5,1),('lx',100,6,0)",
|
||||
} {
|
||||
if err := db.Exec(sql).Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
repo := NewLedgerRepo(testData{db})
|
||||
ctx := context.Background()
|
||||
rows, err := repo.Games(ctx, channelTestScope(), nil, "", 100)
|
||||
if err != nil || len(rows) != 3 {
|
||||
t.Fatalf("只能返回可见渠道已通过申请的游戏,重复申请不能重复: %+v %v", rows, err)
|
||||
}
|
||||
for _, row := range rows {
|
||||
if row.SourceDB != "lx" || row.ID > 3 {
|
||||
t.Fatalf("泄漏未申请或其他商务的游戏: %+v", row)
|
||||
}
|
||||
}
|
||||
rows, err = repo.Games(ctx, channelTestScope(), []string{"hw"}, "", 100)
|
||||
if err != nil || len(rows) != 0 {
|
||||
t.Fatal("不能借用其他平台同号游戏的申请")
|
||||
}
|
||||
rows, err = repo.Games(ctx, business.UserScope{SelfID: 99, OnlySelf: true}, []string{"lx"}, "", 100)
|
||||
if err != nil || len(rows) != 0 {
|
||||
t.Fatal("无可见绑定不能退化为全部游戏")
|
||||
}
|
||||
rows, err = repo.Games(ctx, channelTestScope(), nil, "子渠道", 1)
|
||||
if err != nil || len(rows) != 1 || rows[0].ID != 3 {
|
||||
t.Fatal("应支持已申请游戏的关键词与数量筛选")
|
||||
}
|
||||
if err := db.Exec("DROP TABLE tab_promote_apply").Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := repo.Games(ctx, channelTestScope(), nil, "", 100); err != business.ErrGameOptionsUnavailable {
|
||||
t.Fatal("缺申请表不能开放所有游戏")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGameReportsRejectUnapprovedGamesEvenWithVisibleHistory(t *testing.T) {
|
||||
db, repo, scope, filter := prepareAnalyticsData(t)
|
||||
if err := db.Exec("UPDATE tab_promote_apply SET status=0 WHERE source_db='lx' AND game_id=1").Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
filter.Sources = []string{"lx"}
|
||||
filter.GameNames = []string{"历史游戏甲"}
|
||||
rows, err := repo.Aggregate(context.Background(), business.GameAnalytics, scope, filter)
|
||||
if err != nil || !rows.Available || len(rows.Rows) != 0 {
|
||||
t.Fatalf("直接指定未申请游戏也不能返回统计: %+v %v", rows, err)
|
||||
}
|
||||
}
|
||||
@@ -32,11 +32,8 @@ func ledgerPromotes(db *gorm.DB, scope business.LedgerScope, filter business.Led
|
||||
return q
|
||||
}
|
||||
hits := ledgerBasePromotes(db, scope, filter, "hit")
|
||||
exact := "TRIM(hit.account) = ? COLLATE BINARY"
|
||||
if db.Dialector.Name() == "mysql" {
|
||||
exact = "BINARY TRIM(hit.account) = ?"
|
||||
}
|
||||
hits = hits.Where(exact, filter.PromoteAccount).Where("hit.source_db=" + alias + ".source_db")
|
||||
keyword := strings.ToLower(strings.TrimSpace(filter.PromoteAccount))
|
||||
hits = hits.Where("(INSTR(LOWER(hit.account),?) > 0 OR INSTR(LOWER(hit.nickname),?) > 0)", keyword, keyword).Where("hit.source_db=" + alias + ".source_db")
|
||||
if scope.IncludeSub {
|
||||
root := "CASE WHEN hit.promote_level=1 THEN hit.id WHEN hit.top_promote_id>0 THEN hit.top_promote_id ELSE hit.id END"
|
||||
hits = hits.Where("(" + alias + ".id = (" + root + ") OR " + alias + ".top_promote_id = (" + root + "))")
|
||||
@@ -232,7 +229,8 @@ func spendQuery(db *gorm.DB, scope business.LedgerScope, filter business.LedgerF
|
||||
q := ledgerScopeQuery(db, scope, filter, "tab_spend").Where("r.pay_time BETWEEN ? AND ?", filter.BeginUnix, filter.EndUnix)
|
||||
if successOnly {
|
||||
q = q.Where("r.pay_status = 1")
|
||||
} else if filter.PayStatus != nil {
|
||||
}
|
||||
if filter.PayStatus != nil {
|
||||
q = q.Where("r.pay_status = ?", *filter.PayStatus)
|
||||
}
|
||||
if len(filter.GameNames) > 0 {
|
||||
@@ -353,11 +351,13 @@ func fillLedgerNames(db *gorm.DB, scope business.LedgerScope, filter business.Le
|
||||
SourceDB string `gorm:"column:source_db"`
|
||||
PlatformBusierID uint64
|
||||
PlatformBusierAccount, Username string
|
||||
UserID uint
|
||||
IDPath string `gorm:"column:id_path"`
|
||||
}
|
||||
names := map[business.PlatformKey]bindName{}
|
||||
for start := 0; start < len(pairs); start += 300 {
|
||||
var rows []bindName
|
||||
q := channelBindingQuery(db, scope.Viewer, business.ChannelFilter{}).Select("b.source_db,b.platform_busier_id,b.platform_busier_account,u.username").Where("(b.source_db,b.platform_busier_id) IN ?", portraitBindingPairs(pairs[start:min(start+300, len(pairs))])).Order("b.user_id")
|
||||
q := channelBindingQuery(db, scope.Viewer, business.ChannelFilter{}).Select("b.source_db,b.platform_busier_id,b.platform_busier_account,b.user_id,u.username,u.id_path").Where("(b.source_db,b.platform_busier_id) IN ?", portraitBindingPairs(pairs[start:min(start+300, len(pairs))])).Order("b.user_id")
|
||||
if err := q.Scan(&rows).Error; err != nil {
|
||||
return business.ErrStorage
|
||||
}
|
||||
@@ -368,6 +368,31 @@ func fillLedgerNames(db *gorm.DB, scope business.LedgerScope, filter business.Le
|
||||
}
|
||||
}
|
||||
}
|
||||
ancestorIDs := map[uint]bool{}
|
||||
paths := map[business.PlatformKey][]uint{}
|
||||
for key, binding := range names {
|
||||
for _, part := range strings.Split(binding.IDPath, ",") {
|
||||
id, err := strconv.ParseUint(strings.TrimSpace(part), 10, 32)
|
||||
if err == nil && id > 0 && uint(id) != binding.UserID {
|
||||
paths[key] = append(paths[key], uint(id))
|
||||
ancestorIDs[uint(id)] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
ids := make([]uint, 0, len(ancestorIDs))
|
||||
for id := range ancestorIDs {
|
||||
ids = append(ids, id)
|
||||
}
|
||||
ancestors := map[uint]string{}
|
||||
for start := 0; start < len(ids); start += 300 {
|
||||
var rows []accountPO
|
||||
if err := db.Select("id,username").Where("id IN ? AND level > 0", ids[start:min(start+300, len(ids))]).Find(&rows).Error; err != nil {
|
||||
return business.ErrStorage
|
||||
}
|
||||
for _, row := range rows {
|
||||
ancestors[row.ID] = row.Username
|
||||
}
|
||||
}
|
||||
for _, target := range targets {
|
||||
n := target.Names
|
||||
if n.PromoteID == nil || *n.PromoteID < 0 {
|
||||
@@ -380,33 +405,38 @@ func fillLedgerNames(db *gorm.DB, scope business.LedgerScope, filter business.Le
|
||||
if binding, ok := names[business.PlatformKey{SourceDB: c.SourceDB, BusierID: c.BusierID}]; ok {
|
||||
n.BindingAccount = binding.PlatformBusierAccount
|
||||
n.BindingUserName = binding.Username
|
||||
for _, id := range paths[business.PlatformKey{SourceDB: c.SourceDB, BusierID: c.BusierID}] {
|
||||
if name := strings.TrimSpace(ancestors[id]); name != "" {
|
||||
n.BusinessPath = append(n.BusinessPath, name)
|
||||
}
|
||||
}
|
||||
if name := strings.TrimSpace(binding.Username); name != "" {
|
||||
n.BusinessPath = append(n.BusinessPath, name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (r *ledgerRepo) Games(ctx context.Context, sources []string, keyword string, limit int) ([]*business.GameOption, error) {
|
||||
func (r *ledgerRepo) Games(ctx context.Context, viewer business.UserScope, sources []string, keyword string, limit int) ([]*business.GameOption, error) {
|
||||
db := r.data.DB().WithContext(ctx)
|
||||
available, err := businessTableAvailable(db, "tab_game")
|
||||
available, err := approvedGamesAvailable(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !available {
|
||||
return nil, business.ErrGameOptionsUnavailable
|
||||
}
|
||||
q := db.Table("tab_game")
|
||||
if len(sources) > 0 {
|
||||
q = q.Where("source_db IN ?", sources)
|
||||
}
|
||||
q := approvedGamesQuery(db, viewer, sources)
|
||||
if keyword != "" {
|
||||
q = q.Where("game_name LIKE ?", "%"+keyword+"%")
|
||||
q = q.Where("INSTR(LOWER(g.game_name),?) > 0", strings.ToLower(keyword))
|
||||
}
|
||||
var rows []struct {
|
||||
ID uint64
|
||||
SourceDB string `gorm:"column:source_db"`
|
||||
GameName string
|
||||
}
|
||||
if err := q.Select("id,source_db,game_name").Order("game_name,id,source_db").Limit(limit).Scan(&rows).Error; err != nil {
|
||||
if err := q.Select("g.id,g.source_db,g.game_name").Distinct().Order("g.game_name,g.id,g.source_db").Limit(limit).Scan(&rows).Error; err != nil {
|
||||
return nil, business.ErrStorage
|
||||
}
|
||||
result := make([]*business.GameOption, 0, len(rows))
|
||||
|
||||
@@ -40,7 +40,7 @@ func TestRegistrationScopePuidAndUnboundedPlayerPay(t *testing.T) {
|
||||
first = row
|
||||
}
|
||||
}
|
||||
if first == nil || first.TotalPayAmount == nil || portraitTestMoney(*first.TotalPayAmount) != "710.10" || first.FirstGameName != "历史游戏名" || first.DisplayBusiness() != "lx-business(leaf)" {
|
||||
if first == nil || first.TotalPayAmount == nil || portraitTestMoney(*first.TotalPayAmount) != "710.10" || first.FirstGameName != "历史游戏名" || first.DisplayBusiness() != "parent→branch→leaf" {
|
||||
t.Fatalf("累计充值不能受本次时间/渠道限制,且需保留游戏快照: %+v", first)
|
||||
}
|
||||
filter.SortField = "totalPayAmount"
|
||||
@@ -59,19 +59,19 @@ func TestRegistrationScopePuidAndUnboundedPlayerPay(t *testing.T) {
|
||||
if err != nil || page.Total != 2 {
|
||||
t.Fatal("精确子渠道账号应扩到同一一级树内的可见渠道")
|
||||
}
|
||||
filter.PromoteAccount = "CHILD-channel"
|
||||
filter.PromoteAccount = "CHILD-chan"
|
||||
page, err = repo.Registrations(ctx, scope, filter, business.LedgerListOptions{Limit: 20})
|
||||
if err != nil || page.Total != 0 {
|
||||
t.Fatal("渠道账号应保持区分大小写的精确匹配")
|
||||
if err != nil || page.Total != 2 {
|
||||
t.Fatal("渠道应支持不区分大小写的模糊匹配")
|
||||
}
|
||||
}
|
||||
func TestSpendSummaryIgnoresSelectedFailureStatusAndKeepsSnapshot(t *testing.T) {
|
||||
func TestSpendSummaryRespectsSelectedStatusAndKeepsSnapshot(t *testing.T) {
|
||||
_, repo, scope, filter := prepareLedgerData(t)
|
||||
status := 0
|
||||
filter.PayStatus = &status
|
||||
page, err := repo.Spends(context.Background(), scope, filter, business.LedgerListOptions{Limit: 20})
|
||||
if err != nil || page.Total != 1 || page.Rows[0].ID != 904 || portraitTestMoney(*page.TotalPayAmount) != "80.80" {
|
||||
t.Fatalf("失败列表与成功支付合计不能使用同一个状态条件: %+v %v", page, err)
|
||||
if err != nil || page.Total != 1 || page.Rows[0].ID != 904 || portraitTestMoney(*page.TotalPayAmount) != "0.00" {
|
||||
t.Fatalf("失败状态筛选下不能汇总筛选外成功订单: %+v %v", page, err)
|
||||
}
|
||||
status = 2
|
||||
page, err = repo.Spends(context.Background(), scope, filter, business.LedgerListOptions{Limit: 20})
|
||||
@@ -125,3 +125,25 @@ func TestLedgerLargeTreeFilterDoesNotFallBackToAll(t *testing.T) {
|
||||
t.Fatal("缺渠道范围表不能把限制解释为全量")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLedgerChannelNicknameAndLiteralFuzzyFilter(t *testing.T) {
|
||||
db, repo, scope, filter := prepareLedgerData(t)
|
||||
if err := db.Exec("UPDATE tab_promote SET nickname='推广公会' WHERE source_db='lx' AND id=100").Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
filter.PromoteAccount = "公会"
|
||||
page, err := repo.Spends(context.Background(), scope, filter, business.LedgerListOptions{Limit: 20})
|
||||
if err != nil || page.Total != 4 {
|
||||
t.Fatalf("昵称片段应命中渠道及可见下级: %+v %v", page, err)
|
||||
}
|
||||
filter.PromoteAccount = "%"
|
||||
page, err = repo.Spends(context.Background(), scope, filter, business.LedgerListOptions{Limit: 20})
|
||||
if err != nil || page.Total != 0 {
|
||||
t.Fatal("模糊输入中的百分号应按文字匹配")
|
||||
}
|
||||
filter.PromoteAccount = "other"
|
||||
page, err = repo.Spends(context.Background(), scope, filter, business.LedgerListOptions{Limit: 20})
|
||||
if err != nil || page.Total != 0 {
|
||||
t.Fatal("模糊搜索不得扩大商务范围")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ func NewServerAnalysisRepo(data Provider) business.ServerAnalysisRepo {
|
||||
func serverReportQuery(db *gorm.DB, scope business.AnalyticsScope, f business.ServerAnalysisFilter, table string, mode int) *gorm.DB {
|
||||
q := ledgerScopeQuery(db, business.LedgerScope{Viewer: scope.Viewer, IncludeSub: scope.IncludeSub, Unrestricted: scope.Viewer.All}, business.LedgerFilter{Sources: f.Sources}, table)
|
||||
q = q.Where("r.stat_date >= ? AND r.stat_date <= ? AND r.dedup_mode=? AND r.server_num != ''", f.Begin, f.End, mode).Where("r.game_name IN ?", f.GameNames)
|
||||
q = q.Where("(r.source_db,r.game_id) IN (?)", approvedGamesQuery(db, scope.Viewer, f.Sources).Select("g.source_db,g.id"))
|
||||
if f.ServerNum != "" {
|
||||
q = q.Where("r.server_num=?", f.ServerNum)
|
||||
}
|
||||
@@ -44,7 +45,7 @@ func (r *serverAnalysisRepo) Aggregate(ctx context.Context, scope business.Analy
|
||||
if empty || !available {
|
||||
return out, nil
|
||||
}
|
||||
for _, table := range []string{"tab_sw_report_server_day", "tab_sw_report_server_day_key", "tab_game_server", "tab_game"} {
|
||||
for _, table := range []string{"tab_sw_report_server_day", "tab_sw_report_server_day_key", "tab_game_server", "tab_game", "tab_promote_apply"} {
|
||||
available, err := businessTableAvailable(db, table)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -144,9 +145,9 @@ func fillServerAnalysisNames(db *gorm.DB, rows map[business.ServerAnalysisKey]*b
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (r *serverAnalysisRepo) Servers(ctx context.Context, sources, games []string, keyword string, limit int) ([]*business.ServerOption, error) {
|
||||
func (r *serverAnalysisRepo) Servers(ctx context.Context, viewer business.UserScope, sources, games []string, keyword string, limit int) ([]*business.ServerOption, error) {
|
||||
db := r.data.DB().WithContext(ctx)
|
||||
for _, table := range []string{"tab_game", "tab_game_server"} {
|
||||
for _, table := range []string{"tab_game", "tab_game_server", "tab_promote", "tab_promote_apply"} {
|
||||
available, err := businessTableAvailable(db, table)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -158,7 +159,7 @@ func (r *serverAnalysisRepo) Servers(ctx context.Context, sources, games []strin
|
||||
// MySQL 5.7 不会将相关 EXISTS 展开为半连接,导致扫描全部区服。
|
||||
// 多列 IN 让优化器先按游戏名索引定位,再使用区服的 game_id 索引,
|
||||
// 同时保留平台匹配和重复游戏资料不扩增结果的语义。
|
||||
gamesQuery := db.Table("tab_game g").Select("g.source_db,g.id").Where("g.game_name IN ?", games)
|
||||
gamesQuery := approvedGamesQuery(db, viewer, sources).Select("g.source_db,g.id").Where("g.game_name IN ?", games)
|
||||
q := db.Table("tab_game_server s").Where("(s.source_db,s.game_id) IN (?)", gamesQuery)
|
||||
if len(sources) > 0 {
|
||||
q = q.Where("s.source_db IN ?", sources)
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
func TestServerAnalysisStorageScopeSnapshotAndPreference(t *testing.T) {
|
||||
db, _ := prepareChannels(t)
|
||||
for _, sql := range []string{
|
||||
"INSERT INTO tab_promote_apply VALUES('hw',100,1,1)",
|
||||
"CREATE TABLE tab_game_server(id INTEGER,source_db TEXT,game_id INTEGER,server_num TEXT,server_name TEXT,start_time INTEGER)",
|
||||
"INSERT INTO tab_game_server VALUES(1,'lx',1,'001','龙翔一区',100),(2,'hw',1,'001','汇玩一区',200),(3,'lx',2,'001','游戏乙一区',300),(4,'yq',1,'001','无权区服',400)",
|
||||
"CREATE TABLE tab_sw_report_server_day(source_db TEXT,game_id INTEGER,game_name TEXT,promote_id INTEGER,server_num TEXT,stat_date DATE,dedup_mode INTEGER,total_pay DECIMAL(20,2))",
|
||||
@@ -68,7 +69,7 @@ func TestServerAnalysisStorageScopeSnapshotAndPreference(t *testing.T) {
|
||||
if err != nil || len(p.Rows) != 1 {
|
||||
t.Fatal("区服编号筛选错误")
|
||||
}
|
||||
options, err := r.Servers(ctx, []string{"lx"}, []string{"游戏甲"}, "一区", 50)
|
||||
options, err := r.Servers(ctx, s.Viewer, []string{"lx"}, []string{"游戏甲"}, "一区", 50)
|
||||
if err != nil || len(options) != 1 || options[0].Number != "001" || options[0].Name != "龙翔一区" {
|
||||
t.Fatal("选项应按当前游戏名、同平台游戏关联及区服名称筛选")
|
||||
}
|
||||
@@ -77,6 +78,18 @@ func TestServerAnalysisStorageScopeSnapshotAndPreference(t *testing.T) {
|
||||
if err != nil || len(p.Rows) != 0 {
|
||||
t.Fatal("报表必须按快照游戏名筛选")
|
||||
}
|
||||
if err := db.Exec("UPDATE tab_promote_apply SET status=0 WHERE source_db='lx' AND game_id=1").Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
options, err = r.Servers(ctx, s.Viewer, []string{"lx"}, []string{"游戏甲"}, "", 50)
|
||||
if err != nil || len(options) != 0 {
|
||||
t.Fatal("没有有效申请的游戏不能获取区服选项")
|
||||
}
|
||||
f.GameNames = []string{"历史游戏"}
|
||||
p, err = r.Aggregate(ctx, s, f)
|
||||
if err != nil || len(p.Rows) != 0 {
|
||||
t.Fatal("直接传入未申请游戏也不能获取区服数据")
|
||||
}
|
||||
if err := db.Exec("DROP TABLE tab_sw_report_server_day_key").Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -89,6 +102,10 @@ func TestServerAnalysisStorageScopeSnapshotAndPreference(t *testing.T) {
|
||||
func TestServerOptionsPreservePlatformFilterAndDoNotDuplicateMatches(t *testing.T) {
|
||||
db := openTestDB(t)
|
||||
for _, sql := range []string{
|
||||
"CREATE TABLE tab_promote(id INTEGER,source_db TEXT)",
|
||||
"INSERT INTO tab_promote VALUES(100,'lx'),(100,'hw')",
|
||||
"CREATE TABLE tab_promote_apply(source_db TEXT,promote_id INTEGER,game_id INTEGER,status INTEGER)",
|
||||
"INSERT INTO tab_promote_apply VALUES('lx',100,1,1),('lx',100,2,1),('hw',100,1,1)",
|
||||
"CREATE TABLE tab_game(id INTEGER,source_db TEXT,game_name TEXT)",
|
||||
"INSERT INTO tab_game VALUES(1,'lx','甲'),(1,'lx','甲'),(1,'hw','乙'),(2,'lx','乙')",
|
||||
"CREATE TABLE tab_game_server(id INTEGER,source_db TEXT,game_id INTEGER,server_num TEXT,server_name TEXT,start_time INTEGER)",
|
||||
@@ -99,15 +116,15 @@ func TestServerOptionsPreservePlatformFilterAndDoNotDuplicateMatches(t *testing.
|
||||
}
|
||||
}
|
||||
repo := NewServerAnalysisRepo(testData{db})
|
||||
rows, err := repo.Servers(context.Background(), nil, []string{"甲"}, "", 100)
|
||||
rows, err := repo.Servers(context.Background(), business.UserScope{All: true}, nil, []string{"甲"}, "", 100)
|
||||
if err != nil || len(rows) != 2 || rows[0].Name != "一区" || rows[1].Number != "002" {
|
||||
t.Fatalf("相同游戏资料不能扩增区服,异平台同号不能匹配: %+v %v", rows, err)
|
||||
}
|
||||
rows, err = repo.Servers(context.Background(), []string{"lx"}, []string{"甲", "乙"}, "区", 1)
|
||||
rows, err = repo.Servers(context.Background(), business.UserScope{All: true}, []string{"lx"}, []string{"甲", "乙"}, "区", 1)
|
||||
if err != nil || len(rows) != 1 || rows[0].Name != "一区" {
|
||||
t.Fatalf("名称筛选、排序或数量限制改变: %+v %v", rows, err)
|
||||
}
|
||||
rows, err = repo.Servers(context.Background(), []string{"hw"}, []string{"甲"}, "", 100)
|
||||
rows, err = repo.Servers(context.Background(), business.UserScope{All: true}, []string{"hw"}, []string{"甲"}, "", 100)
|
||||
if err != nil || len(rows) != 0 {
|
||||
t.Fatalf("平台筛选被忽略: %+v %v", rows, err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user