feat: 迁移渠道商务游戏排行榜及同期比较
This commit is contained in:
@@ -0,0 +1,161 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/glebarez/sqlite"
|
||||
"gorm.io/gorm"
|
||||
businessbiz "kra/internal/biz/business"
|
||||
"kra/internal/biz/system"
|
||||
businessdata "kra/internal/data/business"
|
||||
systemdata "kra/internal/data/system"
|
||||
"kra/internal/server/handler"
|
||||
businessservice "kra/internal/service/business"
|
||||
)
|
||||
|
||||
func TestRankingHTTP(t *testing.T) {
|
||||
db, err := gorm.Open(sqlite.Open(filepath.Join(t.TempDir(), "ranking.db")), &gorm.Config{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
pool, _ := db.DB()
|
||||
t.Cleanup(func() { _ = pool.Close() })
|
||||
for _, step := range append(systemdata.Migrations(), businessdata.Migrations()...) {
|
||||
if err := step.Migrate(db); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
for _, sql := range []string{
|
||||
"INSERT INTO sys_users(id,uuid,username,level,parent_id,id_path,enable) VALUES(1,'root','root',0,0,'0',1),(7,'owner','owner',1,0,'0',1),(8,'branch','branch',2,7,'0,7',1),(9,'leaf','leaf',3,8,'0,7,8',1),(10,'leaf2','leaf2',3,8,'0,7,8',1),(99,'other','other',1,0,'0',1)",
|
||||
"INSERT INTO sys_user_bind_platform(user_id,source_db,platform_busier_id,status) VALUES(9,'lx',14,'0'),(10,'hw',14,'0'),(99,'yq',14,'0')",
|
||||
"CREATE TABLE tab_promote(id INTEGER,source_db TEXT,account TEXT,promote_level INTEGER,top_promote_id INTEGER,busier_id INTEGER)",
|
||||
"INSERT INTO tab_promote VALUES(100,'lx','渠道甲',1,0,14),(101,'lx','渠道甲下级',2,100,14),(100,'hw','汇玩同号渠道',1,0,14),(100,'yq','其他商务渠道',1,0,14)",
|
||||
"CREATE TABLE tab_game(id INTEGER,source_db TEXT,game_name TEXT)",
|
||||
"INSERT INTO tab_game VALUES(1,'lx','游戏甲'),(1,'hw','同号游戏'),(1,'yq','无权游戏')",
|
||||
"CREATE TABLE tab_sw_report_day(source_db TEXT,promote_id INTEGER,game_id INTEGER,dedup_mode INTEGER,stat_date DATE,total_pay DECIMAL(20,2))",
|
||||
"INSERT INTO tab_sw_report_day VALUES('lx',100,1,0,'2026-11-04',10),('lx',101,1,0,'2026-11-04',20),('hw',100,1,0,'2026-11-04',40),('yq',100,1,0,'2026-11-04',80),('lx',100,1,0,'2026-11-03',10),('lx',100,1,1,'2026-11-04',9999)",
|
||||
"CREATE TABLE tab_sw_report_day_key(source_db TEXT,promote_id INTEGER,game_id INTEGER,dedup_mode INTEGER,stat_date DATE,metric INTEGER,identity_key TEXT)",
|
||||
} {
|
||||
if err := db.Exec(sql).Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
for _, row := range []struct {
|
||||
source string
|
||||
promote int
|
||||
}{{"lx", 100}, {"lx", 101}, {"hw", 100}, {"yq", 100}} {
|
||||
for _, metric := range []int{1, 2, 3} {
|
||||
if err := db.Exec("INSERT INTO tab_sw_report_day_key VALUES(?,?,1,1,'2026-11-04',?,'A')", row.source, row.promote, metric).Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := db.Exec("UPDATE tab_sw_report_day_key SET identity_key='B' WHERE source_db='lx' AND promote_id=101 AND metric=2").Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := db.Exec("INSERT INTO tab_sw_report_day_key SELECT source_db,promote_id,game_id,dedup_mode,'2026-11-03',metric,identity_key FROM tab_sw_report_day_key WHERE source_db='lx' AND promote_id=100").Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
provider := businessHTTPData{db}
|
||||
uc := businessbiz.NewRankingUsecase(businessdata.NewRankingRepo(provider), businessbiz.NewAccountUsecase(businessdata.NewAccountRepo(provider)), businessbiz.NewUserPreferenceUsecase(businessdata.NewUserPreferenceRepo(provider)))
|
||||
h := handler.NewRanking(businessservice.NewRankingService(uc))
|
||||
engine := gin.New()
|
||||
engine.Use(func(c *gin.Context) {
|
||||
id, _ := strconv.ParseUint(c.GetHeader("X-Test-User"), 10, 64)
|
||||
aid := uint(901)
|
||||
if id == 1 {
|
||||
aid = 888
|
||||
}
|
||||
c.Request = c.Request.WithContext(system.NewActorContext(c.Request.Context(), system.Actor{UserID: uint(id), AuthorityID: aid}))
|
||||
c.Next()
|
||||
})
|
||||
engine.GET("/sw/rank/channel", h.Channel)
|
||||
engine.GET("/sw/rank/business", h.Business)
|
||||
engine.GET("/sw/rank/game", h.Game)
|
||||
srv := httptest.NewServer(engine)
|
||||
defer srv.Close()
|
||||
call := func(user int, kind, query string, code int) map[string]any {
|
||||
t.Helper()
|
||||
req, _ := http.NewRequest("GET", srv.URL+"/sw/rank/"+kind+"?"+query, nil)
|
||||
req.Header.Set("X-Test-User", strconv.Itoa(user))
|
||||
res, err := srv.Client().Do(req)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer res.Body.Close()
|
||||
var body map[string]any
|
||||
if err := json.NewDecoder(res.Body).Decode(&body); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if res.StatusCode != 200 || body["code"] != float64(code) {
|
||||
t.Fatalf("%s: %+v", kind, body)
|
||||
}
|
||||
if code != 0 {
|
||||
return nil
|
||||
}
|
||||
return body["data"].(map[string]any)
|
||||
}
|
||||
query := "beginTime=2026-11-04&endTime=2026-11-04&sourceDb=lx,hw,yq"
|
||||
p := call(7, "channel", query, 0)
|
||||
regs := p["registerRankList"].([]any)
|
||||
if len(regs) != 2 {
|
||||
t.Fatal("其他商务数据不应出现")
|
||||
}
|
||||
var lx map[string]any
|
||||
for _, value := range p["payRateRankList"].([]any) {
|
||||
row := value.(map[string]any)
|
||||
if row["sourceDb"] == "lx" {
|
||||
lx = row
|
||||
}
|
||||
}
|
||||
if lx == nil || lx["metricValue"] != "50.00" || lx["momValue"] != "-50.00" || lx["momStatus"] != float64(-1) {
|
||||
t.Fatalf("付费率应计算百分点差: %+v", lx)
|
||||
}
|
||||
p = call(7, "business", query, 0)
|
||||
rows := p["registerRankList"].([]any)
|
||||
row := rows[0].(map[string]any)
|
||||
if len(rows) != 1 || row["objectId"] != "8" || row["objectName"] != "branch (L2)" || row["metricValue"] != "3" || row["sourceDb"] != nil {
|
||||
t.Fatalf("商务范围或逐渠道加总错误: %+v", p)
|
||||
}
|
||||
row = p["rechargeRankList"].([]any)[0].(map[string]any)
|
||||
if row["metricValue"] != "70.00" || row["momValue"] != "600.00" {
|
||||
t.Fatal("商务金额环比错误")
|
||||
}
|
||||
p = call(8, "business", query, 0)
|
||||
if len(p["registerRankList"].([]any)) != 2 {
|
||||
t.Fatal("二级应看直属三级")
|
||||
}
|
||||
p = call(9, "business", query, 0)
|
||||
if len(p["registerRankList"].([]any)) != 0 {
|
||||
t.Fatal("三级不应展示商务排行")
|
||||
}
|
||||
p = call(1, "business", query, 0)
|
||||
if len(p["registerRankList"].([]any)) != 5 {
|
||||
t.Fatal("超管应展示所有有数据的商务层级")
|
||||
}
|
||||
p = call(7, "game", query+"&gameId=999", 0)
|
||||
if len(p["registerRankList"].([]any)) != 2 {
|
||||
t.Fatal("旧 gameId 参数未用于筛选,不能悄悄改变范围")
|
||||
}
|
||||
for _, v := range p["registerRankList"].([]any) {
|
||||
row := v.(map[string]any)
|
||||
if row["objectId"] != row["sourceDb"].(string)+"|1" {
|
||||
t.Fatal("游戏键应包含平台")
|
||||
}
|
||||
}
|
||||
call(7, "channel", "beginTime=bad&endTime=2026-11-04", 7)
|
||||
call(7, "game", "beginTime=2026-11-05&endTime=2026-11-04", 7)
|
||||
if err := db.Exec("DROP TABLE tab_sw_report_day_key").Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
p = call(7, "channel", query, 0)
|
||||
if p["available"] != false || len(p["registerRankList"].([]any)) != 0 {
|
||||
t.Fatal("缺表不应返回假排行")
|
||||
}
|
||||
}
|
||||
Generated
+6
-1
@@ -82,11 +82,15 @@ func wireApp(configServer *config.Server, store *config.Store, logger *slog.Logg
|
||||
auditRecorderUsecase := system2.NewAuditRecorderUsecase(auditRecordRepo)
|
||||
auditRecorder := system3.NewAuditRecorder(auditRecorderUsecase)
|
||||
registry := taskRegistry()
|
||||
workbenchRepo := business.NewWorkbenchRepo(dataData)
|
||||
rankingRepo := business.NewRankingRepo(dataData)
|
||||
accountRepo := business.NewAccountRepo(dataData)
|
||||
accountUsecase := business2.NewAccountUsecase(accountRepo)
|
||||
userPreferenceRepo := business.NewUserPreferenceRepo(dataData)
|
||||
userPreferenceUsecase := business2.NewUserPreferenceUsecase(userPreferenceRepo)
|
||||
rankingUsecase := business2.NewRankingUsecase(rankingRepo, accountUsecase, userPreferenceUsecase)
|
||||
rankingService := business3.NewRankingService(rankingUsecase)
|
||||
ranking := handler.NewRanking(rankingService)
|
||||
workbenchRepo := business.NewWorkbenchRepo(dataData)
|
||||
workbenchUsecase := business2.NewWorkbenchUsecase(workbenchRepo, accountUsecase, userPreferenceUsecase)
|
||||
workbenchService := business3.NewWorkbenchService(workbenchUsecase)
|
||||
workbench := handler.NewWorkbench(workbenchService)
|
||||
@@ -243,6 +247,7 @@ func wireApp(configServer *config.Server, store *config.Store, logger *slog.Logg
|
||||
integrationConfigService := integration2.NewIntegrationConfigService(integrationConfigUsecase)
|
||||
integrationConfig := handler.NewIntegrationConfig(integrationConfigService)
|
||||
set := &handler.Set{
|
||||
Ranking: ranking,
|
||||
Workbench: workbench,
|
||||
ServerAnalysis: serverAnalysis,
|
||||
Analytics: analytics,
|
||||
|
||||
Reference in New Issue
Block a user