fix: 完成商务迁移复核与接口优化并清理历史资料

This commit is contained in:
Yvan
2026-11-04 14:45:02 +08:00
parent 5a96be6a79
commit 297e80827d
176 changed files with 6803 additions and 6002 deletions
+126
View File
@@ -0,0 +1,126 @@
package main
import (
"bytes"
"context"
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"path/filepath"
"testing"
"time"
"github.com/gin-gonic/gin"
"github.com/glebarez/sqlite"
"gorm.io/gorm"
businessbiz "kra/internal/biz/business"
taskbiz "kra/internal/biz/task"
businessdata "kra/internal/data/business"
taskdata "kra/internal/data/task"
"kra/internal/server/handler"
"kra/internal/server/router"
taskservice "kra/internal/service/task"
"kra/internal/worker"
platformtask "kra/pkg/task"
)
func TestAlertTriggerThroughNativeTaskHTTP(t *testing.T) {
db, err := gorm.Open(sqlite.Open(filepath.Join(t.TempDir(), "alert-task.db")), &gorm.Config{})
if err != nil {
t.Fatal(err)
}
pool, _ := db.DB()
t.Cleanup(func() { _ = pool.Close() })
for _, step := range append(taskdata.Migrations(), businessdata.Migrations()...) {
if err := step.Migrate(db); err != nil {
t.Fatal(err)
}
}
for _, sql := range []string{
"CREATE TABLE sys_users(id INTEGER,username TEXT,level INTEGER,parent_id INTEGER,id_path TEXT,authority_id INTEGER,deleted_at DATETIME)",
"CREATE TABLE tab_promote(id INTEGER,source_db TEXT,busier_id INTEGER,account TEXT,promote_level INTEGER,status INTEGER,last_login_time INTEGER,create_time INTEGER)",
"INSERT INTO sys_users VALUES(10,'一级',1,0,'0',901,NULL),(20,'二级',2,10,'0,10',902,NULL),(30,'三级',3,20,'0,10,20',903,NULL)",
"INSERT INTO sys_user_bind_platform(user_id,source_db,platform_busier_id,platform_busier_account,status) VALUES(30,'lx',7,'绑定','0')",
"INSERT INTO tab_promote VALUES(10,'lx',7,'测试渠道',1,1,0,1)",
"INSERT INTO sys_alert_rule(rule_name,rule_type,monitor_metric,creator_id,unlogin_days,warning_color,enabled,is_deleted) VALUES('未登录规则','未登录',3,10,1,'red',1,0)",
} {
if err := db.Exec(sql).Error; err != nil {
t.Fatal(err)
}
}
provider := businessHTTPData{db}
registry := platformtask.NewRegistry()
tasks := taskbiz.NewTaskUsecaseWithRegistry(taskdata.NewTaskRepo(reportTaskHTTPData{provider}), registry)
alerts := businessbiz.NewAlertTriggerUsecase(businessdata.NewAlertTriggerRepo(provider))
worker.NewTaskMethods(tasks, nil, nil, nil, nil, alerts).RegisterTasks(registry)
scheduler := worker.NewTaskScheduler(tasks, nil, worker.NewTaskExecutorWithRegistry(tasks, registry), nil)
defer func() {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
_ = scheduler.Stop(ctx)
}()
engine := gin.New()
router.RegisterTask(engine.Group(""), handler.NewTask(taskservice.NewTaskService(taskbiz.NewTaskApplicationUsecase(tasks, scheduler))))
server := httptest.NewServer(engine)
defer server.Close()
call := func(method, path string, body any) map[string]any {
t.Helper()
raw, _ := json.Marshal(body)
req, _ := http.NewRequest(method, server.URL+"/timedTask/"+path, bytes.NewReader(raw))
req.Header.Set("Content-Type", "application/json")
res, err := server.Client().Do(req)
if err != nil {
t.Fatal(err)
}
defer res.Body.Close()
var result map[string]any
if err := json.NewDecoder(res.Body).Decode(&result); err != nil {
t.Fatal(err)
}
if result["code"] != float64(0) {
t.Fatalf("预警任务 HTTP 失败: %+v", result)
}
return result["data"].(map[string]any)
}
call("POST", "createTimedTask", map[string]any{"name": "预警 HTTP 演练", "spec": "@daily", "executorType": "method", "methodName": "alertTriggerTask", "enabled": false})
var id uint
if err := db.Table("sys_timed_tasks").Select("id").Where("name=?", "预警 HTTP 演练").Scan(&id).Error; err != nil || id == 0 {
t.Fatalf("任务未创建: %v", err)
}
for iteration := 0; iteration < 2; iteration++ {
call("POST", "triggerTimedTask", map[string]any{"id": id})
deadline := time.Now().Add(8 * time.Second)
finished := false
for time.Now().Before(deadline) {
logs := call("GET", fmt.Sprintf("getTimedTaskLogList?taskId=%d&page=1&pageSize=10", id), nil)["list"].([]any)
if len(logs) > iteration {
if logs[0].(map[string]any)["status"] != "success" {
t.Fatalf("预警任务失败: %+v", logs)
}
finished = true
break
}
time.Sleep(20 * time.Millisecond)
}
if !finished {
t.Fatal("没有收到预警执行完成日志")
}
}
var rows []struct {
BusinessID, TargetPromoteID uint
Status int
PlatformCode string
}
if err := db.Table("sys_alert_record").Scan(&rows).Error; err != nil {
t.Fatal(err)
}
if len(rows) != 1 || rows[0].BusinessID != 10 || rows[0].TargetPromoteID != 10 || rows[0].PlatformCode != "lx" || rows[0].Status != 1 {
t.Fatalf("重复触发或归属错误: %+v", rows)
}
var enabled int64
db.Table("sys_timed_tasks").Where("enabled=1").Count(&enabled)
if enabled != 0 {
t.Fatal("手动触发不应启用自动计划")
}
}
+2 -5
View File
@@ -103,11 +103,8 @@ func httpAddress(server *config.Server) string {
}
func swaggerAddress(server *config.Server, admin *config.Admin) string {
if admin != nil && admin.App != nil {
switch strings.ToLower(strings.TrimSpace(admin.App.Env)) {
case "production", "prod", "live", "staging":
return "disabled"
}
if !config.SwaggerEnabled(admin) {
return "disabled"
}
address := httpAddress(server)
if strings.HasPrefix(address, ":") {
+5 -3
View File
@@ -13,9 +13,11 @@ func TestSwaggerAddress(t *testing.T) {
admin *config.Admin
want string
}{
{name: "default", want: "http://127.0.0.1:8000/swagger/index.html"},
{name: "wildcard with prefix", server: &config.Server{HTTP: &config.ServerHTTP{Addr: "0.0.0.0:9000"}}, admin: &config.Admin{RouterPrefix: "/admin/"}, want: "http://127.0.0.1:9000/admin/swagger/index.html"},
{name: "host", server: &config.Server{HTTP: &config.ServerHTTP{Addr: "example.test:8080"}}, want: "http://example.test:8080/swagger/index.html"},
{name: "missing environment", want: "disabled"},
{name: "qa", admin: &config.Admin{App: &config.App{Env: "qa"}}, want: "disabled"},
{name: "development default", admin: &config.Admin{App: &config.App{Env: "dev"}}, want: "http://127.0.0.1:8000/swagger/index.html"},
{name: "wildcard with prefix", server: &config.Server{HTTP: &config.ServerHTTP{Addr: "0.0.0.0:9000"}}, admin: &config.Admin{RouterPrefix: "/admin/", App: &config.App{Env: "test"}}, want: "http://127.0.0.1:9000/admin/swagger/index.html"},
{name: "host", server: &config.Server{HTTP: &config.ServerHTTP{Addr: "example.test:8080"}}, admin: &config.Admin{App: &config.App{Env: "local"}}, want: "http://example.test:8080/swagger/index.html"},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
+13 -1
View File
@@ -115,7 +115,19 @@ func TestRankingHTTP(t *testing.T) {
}
}
if lx == nil || lx["metricValue"] != "50.00" || lx["momValue"] != "-50.00" || lx["momStatus"] != float64(-1) {
t.Fatalf("付费率应计算百分点差: %+v", lx)
t.Fatalf("付费率应计算相对上期增幅: %+v", lx)
}
for _, identity := range []string{"B", "C", "D"} {
if err := db.Exec("INSERT INTO tab_sw_report_day_key VALUES('lx',100,1,1,'2026-11-03',2,?)", identity).Error; err != nil {
t.Fatal(err)
}
}
p = call(7, "channel", query, 0)
for _, value := range p["payRateRankList"].([]any) {
row := value.(map[string]any)
if row["sourceDb"] == "lx" && (row["metricValue"] != "50.00" || row["momValue"] != "100.00" || row["momStatus"] != float64(1)) {
t.Fatalf("25%% 升到 50%% 应为 +100%% 环比: %+v", row)
}
}
p = call(7, "business", query, 0)
rows := p["registerRankList"].([]any)
+2 -2
View File
@@ -70,7 +70,7 @@ func TestReportBuildThroughNativeTaskHTTP(t *testing.T) {
registry := platformtask.NewRegistry()
tasks := taskbiz.NewTaskUsecaseWithRegistry(taskdata.NewTaskRepo(reportTaskHTTPData{provider}), registry)
reports := businessbiz.NewReportBuildUsecase(businessdata.NewReportBuildRepo(provider))
worker.NewTaskMethods(tasks, nil, nil, nil, reports).RegisterTasks(registry)
worker.NewTaskMethods(tasks, nil, nil, nil, reports, nil).RegisterTasks(registry)
scheduler := worker.NewTaskScheduler(tasks, nil, worker.NewTaskExecutorWithRegistry(tasks, registry), nil)
defer func() {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
@@ -102,7 +102,7 @@ func TestReportBuildThroughNativeTaskHTTP(t *testing.T) {
return value["data"].(map[string]any)
}
methods := call("GET", "getRegisteredMethods", nil)["methods"].([]any)
if len(methods) != 8 {
if len(methods) != 9 {
t.Fatalf("六个商务汇总方法未注册: %d", len(methods))
}
for index, method := range []string{"swReportDayBackfillTask", "swReportServerDayBackfillTask"} {
+3 -1
View File
@@ -290,7 +290,9 @@ func wireApp(configServer *config.Server, store *config.Store, logger *slog.Logg
maintenanceUsecase := system2.NewMaintenanceUsecase(maintenanceRepo)
reportBuildRepo := business.NewReportBuildRepo(dataData)
reportBuildUsecase := business2.NewReportBuildUsecase(reportBuildRepo)
taskMethods := worker.NewTaskMethods(taskUsecase, maintenanceUsecase, mediaUsecase, store, reportBuildUsecase)
alertTriggerRepo := business.NewAlertTriggerRepo(dataData)
alertTriggerUsecase := business2.NewAlertTriggerUsecase(alertTriggerRepo)
taskMethods := worker.NewTaskMethods(taskUsecase, maintenanceUsecase, mediaUsecase, store, reportBuildUsecase, alertTriggerUsecase)
routeRegistrar := buildRuntime(registry, routes, taskMethods)
websocketServer, cleanup2, err := websocket.New(runtimeconfigStore)
if err != nil {