feat: 迁移游戏商务绑定审核流程和列表

This commit is contained in:
Yvan
2026-11-03 18:26:26 +08:00
parent 43f0ec1b15
commit c0a3692068
31 changed files with 1304 additions and 30 deletions
+65 -4
View File
@@ -6,6 +6,7 @@ import (
"net/http"
"net/http/httptest"
"path/filepath"
"strings"
"testing"
"github.com/gin-gonic/gin"
@@ -24,6 +25,16 @@ type businessHTTPData struct{ db *gorm.DB }
func (d businessHTTPData) DB() *gorm.DB { return d.db }
type httpPlatformAccounts struct{}
func (httpPlatformAccounts) FindByAccount(context.Context, string, string) (*businessbiz.PlatformAccount, error) {
return &businessbiz.PlatformAccount{ID: 77, Status: 1}, nil
}
type httpPlatformPasswords struct{}
func (httpPlatformPasswords) Verify(string, string) (bool, error) { return true, nil }
func TestBusinessHTTPListWithSystemOnlyAndCompleteDatabase(t *testing.T) {
db, err := gorm.Open(sqlite.Open(filepath.Join(t.TempDir(), "http.db")), &gorm.Config{})
if err != nil {
@@ -40,7 +51,8 @@ func TestBusinessHTTPListWithSystemOnlyAndCompleteDatabase(t *testing.T) {
}
}
for _, statement := range []string{
"INSERT INTO sys_users(id,uuid,username,authority_id,level,id_path) VALUES (1,'admin','admin',888,0,'0'),(2,'child','child',901,1,'0'),(3,'empty','empty',901,1,'0')",
"INSERT INTO sys_users(id,uuid,username,authority_id,level,id_path) VALUES (1,'admin','admin',888,0,'0'),(2,'child','child',901,1,'0'),(3,'empty','empty',903,3,'0,2')",
"INSERT INTO sys_authorities(authority_id,authority_name) VALUES (901,'一级商务')",
"INSERT INTO sys_user_bind_platform(user_id,source_db,platform_busier_id,status) VALUES (2,'lx',9,'0')",
} {
if err := db.Exec(statement).Error; err != nil {
@@ -48,15 +60,21 @@ func TestBusinessHTTPListWithSystemOnlyAndCompleteDatabase(t *testing.T) {
}
}
provider := businessHTTPData{db}
accounts := businessservice.NewAccountService(businessbiz.NewAccountUsecase(businessdata.NewAccountRepo(provider)))
accountUsecase := businessbiz.NewAccountUsecase(businessdata.NewAccountRepo(provider))
accounts := businessservice.NewAccountService(accountUsecase)
bindings := businessservice.NewBindingService(businessbiz.NewBindingUsecase(businessdata.NewBindingRepo(provider), accountUsecase, httpPlatformAccounts{}, httpPlatformPasswords{}))
prefs := businessservice.NewUserPreferenceService(businessbiz.NewUserPreferenceUsecase(businessdata.NewUserPreferenceRepo(provider)))
engine := gin.New()
// 此契约测试固定已认证身份;真实登录另通过运行实例验证。
engine.Use(func(c *gin.Context) {
c.Request = c.Request.WithContext(system.NewActorContext(c.Request.Context(), system.Actor{UserID: 1, AuthorityID: 888}))
actor := system.Actor{UserID: 1, AuthorityID: 888}
if c.GetHeader("X-Test-Actor") == "3" {
actor = system.Actor{UserID: 3, AuthorityID: 903}
}
c.Request = c.Request.WithContext(system.NewActorContext(c.Request.Context(), actor))
c.Next()
})
router.RegisterBusiness(engine.Group(""), handler.NewBusiness(prefs, accounts))
router.RegisterBusiness(engine.Group(""), handler.NewBusiness(prefs, accounts, bindings))
server := httptest.NewServer(engine)
defer server.Close()
requestList := func() map[string]any {
@@ -99,4 +117,47 @@ func TestBusinessHTTPListWithSystemOnlyAndCompleteDatabase(t *testing.T) {
if child["promoteCount"] != float64(1) {
t.Fatalf("完整数据应恢复真实且按平台隔离的渠道数: %+v", child)
}
call := func(method, path, body, actor string) map[string]any {
t.Helper()
req, _ := http.NewRequest(method, server.URL+path, strings.NewReader(body))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-Test-Actor", actor)
response, err := server.Client().Do(req)
if err != nil {
t.Fatal(err)
}
defer response.Body.Close()
var value map[string]any
if err := json.NewDecoder(response.Body).Decode(&value); err != nil {
t.Fatal(err)
}
if value["code"] != float64(0) {
t.Fatalf("%s %s 失败: %+v", method, path, value)
}
return value
}
created := call("POST", "/sw/business", `{"userName":"http_child","realName":"接口测试","password":"abc123"}`, "")["data"].(map[string]any)
if created["userId"] != float64(4) || created["level"] != float64(1) || created["authorityId"] != float64(901) {
t.Fatalf("HTTP 新增层级或角色不正确: %+v", created)
}
call("PUT", "/sw/business", `{"userId":4,"realName":"更新姓名"}`, "")
updated := call("GET", "/sw/business/4", "", "")["data"].(map[string]any)
if updated["realName"] != "更新姓名" || updated["status"] != "0" {
t.Fatalf("HTTP 部分编辑不正确: %+v", updated)
}
call("PUT", "/sw/user/preference", `{"includeSubPromote":false,"idcardDedup":false}`, "")
preference := call("GET", "/sw/user/preference", "", "")["data"].(map[string]any)
if preference["includeSubPromote"] != false || preference["idcardDedup"] != false {
t.Fatalf("HTTP 偏好关闭未保存: %+v", preference)
}
call("POST", "/sw/business/bindPlatform", `{"sourceDb":"lx","account":"sdk-test","password":"test-only"}`, "3")
bound := call("GET", "/sw/business/bindPlatform", "", "3")["data"].(map[string]any)
if bound["total"] != float64(1) || bound["rows"].([]any)[0].(map[string]any)["status"] != "3" {
t.Fatalf("HTTP 绑定未进入待审核: %+v", bound)
}
call("DELETE", "/sw/business/bindPlatform", `{"sourceDb":"lx","platformBusierId":77}`, "3")
bound = call("GET", "/sw/business/bindPlatform", "", "3")["data"].(map[string]any)
if bound["total"] != float64(0) {
t.Fatalf("HTTP 解绑未删除当前账号绑定: %+v", bound)
}
}
+7 -1
View File
@@ -24,6 +24,7 @@ import (
integration4 "kra/internal/integration"
"kra/internal/integration/cache"
"kra/internal/integration/email"
"kra/internal/integration/gameplatform"
"kra/internal/integration/mq"
"kra/internal/integration/payment"
"kra/internal/integration/sms"
@@ -87,7 +88,12 @@ func wireApp(configServer *config.Server, store *config.Store, logger *slog.Logg
accountRepo := business.NewAccountRepo(dataData)
accountUsecase := business2.NewAccountUsecase(accountRepo)
accountService := business3.NewAccountService(accountUsecase)
handlerBusiness := handler.NewBusiness(userPreferenceService, accountService)
bindingRepo := business.NewBindingRepo(dataData)
platformAccountRepo := business.NewPlatformAccountRepo(dataData)
platformPasswordVerifier := gameplatform.NewPasswords()
bindingUsecase := business2.NewBindingUsecase(bindingRepo, accountUsecase, platformAccountRepo, platformPasswordVerifier)
bindingService := business3.NewBindingService(bindingUsecase)
handlerBusiness := handler.NewBusiness(userPreferenceService, accountService, bindingService)
runtimeconfigStore := data.NewIntegrationRuntime(dataData)
smsSender := sms.NewSender(runtimeconfigStore)
smsUsecase := integration.NewSMSUsecase(smsSender)