经理中心配置
This commit is contained in:
parent
e370c3ca32
commit
53c6f361f9
@ -37,6 +37,15 @@ func registerManagerCenterRoutes(engine *gin.Engine, javaClient authGateway, ser
|
||||
writeOK(c, resp)
|
||||
})
|
||||
|
||||
group.GET("/countries", func(c *gin.Context) {
|
||||
resp, err := service.ListCountries(c.Request.Context(), mustAuthUser(c))
|
||||
if err != nil {
|
||||
writeError(c, err)
|
||||
return
|
||||
}
|
||||
writeOK(c, resp)
|
||||
})
|
||||
|
||||
group.GET("/props", func(c *gin.Context) {
|
||||
resp, err := service.ListProps(c.Request.Context(), mustAuthUser(c), c.Query("type"))
|
||||
if err != nil {
|
||||
@ -110,4 +119,18 @@ func registerManagerCenterRoutes(engine *gin.Engine, javaClient authGateway, ser
|
||||
}
|
||||
writeOK(c, resp)
|
||||
})
|
||||
|
||||
group.POST("/users/country", func(c *gin.Context) {
|
||||
var req managercenter.ChangeUserCountryRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
writeError(c, managercenter.NewAppError(http.StatusBadRequest, "bad_request", err.Error()))
|
||||
return
|
||||
}
|
||||
resp, err := service.ChangeUserCountry(c.Request.Context(), mustAuthUser(c), req)
|
||||
if err != nil {
|
||||
writeError(c, err)
|
||||
return
|
||||
}
|
||||
writeOK(c, resp)
|
||||
})
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"chatapp3-golang/internal/integration"
|
||||
"chatapp3-golang/internal/model"
|
||||
@ -32,21 +33,38 @@ func (teamManagerInfoRow) TableName() string {
|
||||
}
|
||||
|
||||
type userBaseInfoRow struct {
|
||||
ID int64 `gorm:"column:id;primaryKey"`
|
||||
Account string `gorm:"column:account"`
|
||||
UserAvatar string `gorm:"column:user_avatar"`
|
||||
UserNickname string `gorm:"column:user_nickname"`
|
||||
CountryCode string `gorm:"column:country_code"`
|
||||
CountryName string `gorm:"column:country_name"`
|
||||
OriginSys string `gorm:"column:origin_sys"`
|
||||
AccountStatus string `gorm:"column:account_status"`
|
||||
IsDel bool `gorm:"column:is_del"`
|
||||
ID int64 `gorm:"column:id;primaryKey"`
|
||||
Account string `gorm:"column:account"`
|
||||
UserAvatar string `gorm:"column:user_avatar"`
|
||||
UserNickname string `gorm:"column:user_nickname"`
|
||||
CountryID int64 `gorm:"column:country_id"`
|
||||
CountryCode string `gorm:"column:country_code"`
|
||||
CountryName string `gorm:"column:country_name"`
|
||||
OriginSys string `gorm:"column:origin_sys"`
|
||||
AccountStatus string `gorm:"column:account_status"`
|
||||
IsDel bool `gorm:"column:is_del"`
|
||||
UpdateTime time.Time `gorm:"column:update_time"`
|
||||
UpdateUser int64 `gorm:"column:update_user"`
|
||||
}
|
||||
|
||||
func (userBaseInfoRow) TableName() string {
|
||||
return "user_base_info"
|
||||
}
|
||||
|
||||
type sysCountryCodeRow struct {
|
||||
ID int64 `gorm:"column:id;primaryKey"`
|
||||
AlphaTwo string `gorm:"column:alpha_two"`
|
||||
CountryName string `gorm:"column:country_name"`
|
||||
NationalFlag string `gorm:"column:national_flag"`
|
||||
PhonePrefix int `gorm:"column:phone_prefix"`
|
||||
Open bool `gorm:"column:is_open"`
|
||||
Sort int `gorm:"column:sort"`
|
||||
}
|
||||
|
||||
func (sysCountryCodeRow) TableName() string {
|
||||
return "sys_country_code"
|
||||
}
|
||||
|
||||
type propsSourceRecordRow struct {
|
||||
ID int64 `gorm:"column:id;primaryKey"`
|
||||
Type string `gorm:"column:type"`
|
||||
@ -106,6 +124,34 @@ func (s *Service) SearchUser(ctx context.Context, user AuthUser, account string)
|
||||
return &UserSearchResponse{User: view}, nil
|
||||
}
|
||||
|
||||
// ListCountries 给经理中心返回当前开放国家,H5 只展示可绑定目标,避免经理手输无效国家码。
|
||||
func (s *Service) ListCountries(ctx context.Context, user AuthUser) (*CountryListResponse, error) {
|
||||
if err := s.ensureManager(ctx, user); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if s.db == nil {
|
||||
return nil, serviceUnavailable("database_unavailable", "database is unavailable")
|
||||
}
|
||||
|
||||
var rows []sysCountryCodeRow
|
||||
if err := s.db.WithContext(ctx).
|
||||
Table("sys_country_code").
|
||||
Select("id, alpha_two, country_name, national_flag, phone_prefix, is_open, sort").
|
||||
Where("is_open = ?", true).
|
||||
Order("sort ASC, country_name ASC, id ASC").
|
||||
Find(&rows).Error; err != nil {
|
||||
return nil, serverError("country_query_failed", err.Error())
|
||||
}
|
||||
|
||||
records := make([]CountryView, 0, len(rows))
|
||||
for _, row := range rows {
|
||||
if view, ok := countryRowToView(row); ok {
|
||||
records = append(records, view)
|
||||
}
|
||||
}
|
||||
return &CountryListResponse{Records: records}, nil
|
||||
}
|
||||
|
||||
func (s *Service) ListProps(ctx context.Context, user AuthUser, propsType string) (*PropsListResponse, error) {
|
||||
if err := s.ensureManager(ctx, user); err != nil {
|
||||
return nil, err
|
||||
@ -332,6 +378,66 @@ func (s *Service) UnbanUser(ctx context.Context, user AuthUser, req UnbanUserReq
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ChangeUserCountry 只允许经理移动普通用户国家;用户已有业务身份时拒绝,避免跨国家后团队、币商和主播归属数据不一致。
|
||||
func (s *Service) ChangeUserCountry(ctx context.Context, user AuthUser, req ChangeUserCountryRequest) (*ChangeUserCountryResponse, error) {
|
||||
if err := s.ensureManager(ctx, user); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if req.UserID.Int64() <= 0 {
|
||||
return nil, badRequest("user_required", "userId is required")
|
||||
}
|
||||
if req.CountryID.Int64() <= 0 {
|
||||
return nil, badRequest("country_required", "countryId is required")
|
||||
}
|
||||
if s.db == nil {
|
||||
return nil, serviceUnavailable("database_unavailable", "database is unavailable")
|
||||
}
|
||||
|
||||
target, err := s.loadUserRowByID(ctx, req.UserID.Int64())
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, notFound("user_not_found", "user not found")
|
||||
}
|
||||
return nil, serverError("user_query_failed", err.Error())
|
||||
}
|
||||
country, err := s.loadOpenCountryByID(ctx, req.CountryID.Int64())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := s.ensureUserCountryMovable(ctx, target.ID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 只改国家三元组,不触碰昵称、头像等资料审核字段;清理 Java 资料缓存后 App/H5 会重新读到新国家。
|
||||
updates := map[string]any{
|
||||
"country_id": country.ID,
|
||||
"country_code": strings.ToUpper(strings.TrimSpace(country.AlphaTwo)),
|
||||
"country_name": strings.TrimSpace(country.CountryName),
|
||||
"update_time": time.Now(),
|
||||
"update_user": user.UserID,
|
||||
}
|
||||
if err := s.db.WithContext(ctx).
|
||||
Table("user_base_info").
|
||||
Where("id = ? AND is_del = ?", target.ID, false).
|
||||
Updates(updates).Error; err != nil {
|
||||
return nil, serverError("user_country_update_failed", err.Error())
|
||||
}
|
||||
if s.java != nil {
|
||||
if err := s.java.RemoveUserProfileCacheAll(ctx, target.ID); err != nil {
|
||||
return nil, serverError("remove_profile_cache_failed", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
target.CountryID = country.ID
|
||||
target.CountryCode = strings.ToUpper(strings.TrimSpace(country.AlphaTwo))
|
||||
target.CountryName = strings.TrimSpace(country.CountryName)
|
||||
view, err := s.userRowToView(ctx, target)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ChangeUserCountryResponse{Success: true, User: view}, nil
|
||||
}
|
||||
|
||||
func (s *Service) ensureManager(ctx context.Context, user AuthUser) error {
|
||||
_, err := s.requireManagerInfo(ctx, user)
|
||||
return err
|
||||
@ -444,6 +550,65 @@ func (s *Service) loadUserRowByAccount(ctx context.Context, account string) (use
|
||||
return row, err
|
||||
}
|
||||
|
||||
func (s *Service) loadOpenCountryByID(ctx context.Context, countryID int64) (sysCountryCodeRow, error) {
|
||||
var row sysCountryCodeRow
|
||||
err := s.db.WithContext(ctx).
|
||||
Table("sys_country_code").
|
||||
Select("id, alpha_two, country_name, national_flag, phone_prefix, is_open, sort").
|
||||
Where("id = ? AND is_open = ?", countryID, true).
|
||||
First(&row).Error
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return sysCountryCodeRow{}, notFound("country_not_found", "country not found")
|
||||
}
|
||||
if err != nil {
|
||||
return sysCountryCodeRow{}, serverError("country_query_failed", err.Error())
|
||||
}
|
||||
if strings.TrimSpace(row.AlphaTwo) == "" {
|
||||
return sysCountryCodeRow{}, badRequest("country_code_required", "country code is required")
|
||||
}
|
||||
return row, nil
|
||||
}
|
||||
|
||||
// ensureUserCountryMovable 串行检查所有会绑定归属关系的身份;任一命中都返回同一个业务错误,前端显示统一提示。
|
||||
func (s *Service) ensureUserCountryMovable(ctx context.Context, userID int64) error {
|
||||
locked, err := s.userHasLockedHistoryIdentity(ctx, userID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if locked {
|
||||
return badRequest("user_identity_locked", "user has host, agency, BD, BD leader or coin seller identity and cannot be moved")
|
||||
}
|
||||
locked, err = s.userIsBDLeader(ctx, userID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if locked {
|
||||
return badRequest("user_identity_locked", "user has host, agency, BD, BD leader or coin seller identity and cannot be moved")
|
||||
}
|
||||
if s.java == nil {
|
||||
return serviceUnavailable("java_gateway_unavailable", "java gateway is unavailable")
|
||||
}
|
||||
locked, err = s.java.ExistsFreightSeller(ctx, userID)
|
||||
if err != nil {
|
||||
return serverError("coin_seller_query_failed", err.Error())
|
||||
}
|
||||
if locked {
|
||||
return badRequest("user_identity_locked", "user has host, agency, BD, BD leader or coin seller identity and cannot be moved")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) userHasLockedHistoryIdentity(ctx context.Context, userID int64) (bool, error) {
|
||||
var count int64
|
||||
if err := s.db.WithContext(ctx).
|
||||
Table("user_history_identity").
|
||||
Where("user_id = ? AND (is_host = ? OR is_agent = ? OR is_bd = ?)", userID, true, true, true).
|
||||
Count(&count).Error; err != nil {
|
||||
return false, serverError("history_identity_query_failed", err.Error())
|
||||
}
|
||||
return count > 0, nil
|
||||
}
|
||||
|
||||
func (s *Service) userRowToView(ctx context.Context, row userBaseInfoRow) (UserView, error) {
|
||||
hasRecharge, canBan := s.userRechargeEligibility(ctx, row.ID)
|
||||
canBan = canBan && !isUnbannableAccountStatus(row.AccountStatus)
|
||||
@ -452,6 +617,7 @@ func (s *Service) userRowToView(ctx context.Context, row userBaseInfoRow) (UserV
|
||||
Account: row.Account,
|
||||
UserAvatar: row.UserAvatar,
|
||||
UserNickname: row.UserNickname,
|
||||
CountryID: ID(row.CountryID),
|
||||
CountryCode: row.CountryCode,
|
||||
CountryName: row.CountryName,
|
||||
OriginSys: row.OriginSys,
|
||||
@ -469,6 +635,7 @@ func (s *Service) javaProfileToView(ctx context.Context, profile integration.Use
|
||||
Account: profile.Account,
|
||||
UserAvatar: profile.UserAvatar,
|
||||
UserNickname: profile.UserNickname,
|
||||
CountryID: ID(profile.CountryID),
|
||||
CountryCode: profile.CountryCode,
|
||||
CountryName: profile.CountryName,
|
||||
OriginSys: profile.OriginSys,
|
||||
@ -494,6 +661,9 @@ func overlayJavaProfile(view *UserView, profile integration.UserProfile) {
|
||||
if profile.CountryName != "" {
|
||||
view.CountryName = profile.CountryName
|
||||
}
|
||||
if int64(profile.CountryID) > 0 {
|
||||
view.CountryID = ID(profile.CountryID)
|
||||
}
|
||||
if profile.OriginSys != "" {
|
||||
view.OriginSys = profile.OriginSys
|
||||
}
|
||||
@ -505,6 +675,21 @@ func overlayJavaProfile(view *UserView, profile integration.UserProfile) {
|
||||
}
|
||||
}
|
||||
|
||||
func countryRowToView(row sysCountryCodeRow) (CountryView, bool) {
|
||||
code := strings.ToUpper(strings.TrimSpace(row.AlphaTwo))
|
||||
name := strings.TrimSpace(row.CountryName)
|
||||
if row.ID <= 0 || code == "" || name == "" {
|
||||
return CountryView{}, false
|
||||
}
|
||||
return CountryView{
|
||||
ID: ID(row.ID),
|
||||
CountryCode: code,
|
||||
CountryName: name,
|
||||
NationalFlag: strings.TrimSpace(row.NationalFlag),
|
||||
PhonePrefix: row.PhonePrefix,
|
||||
}, true
|
||||
}
|
||||
|
||||
func (s *Service) userHasRecharge(ctx context.Context, userID int64) (bool, error) {
|
||||
if userID <= 0 {
|
||||
return false, nil
|
||||
|
||||
@ -17,6 +17,8 @@ import (
|
||||
type fakeManagerGateway struct {
|
||||
recharges map[int64][]integration.UserTotalRecharge
|
||||
rechargeErr error
|
||||
freightSellers map[int64]bool
|
||||
freightSellerErr error
|
||||
abilities map[int64]integration.PropsNobleVIPAbility
|
||||
maxAbility integration.PropsNobleVIPAbility
|
||||
giveRequests []integration.GivePropsBackpackRequest
|
||||
@ -52,6 +54,13 @@ func (f *fakeManagerGateway) MapUserTotalRecharge(_ context.Context, userIDs []i
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (f *fakeManagerGateway) ExistsFreightSeller(_ context.Context, userID int64) (bool, error) {
|
||||
if f.freightSellerErr != nil {
|
||||
return false, f.freightSellerErr
|
||||
}
|
||||
return f.freightSellers[userID], nil
|
||||
}
|
||||
|
||||
func (f *fakeManagerGateway) GivePropsBackpack(_ context.Context, req integration.GivePropsBackpackRequest) error {
|
||||
f.giveRequests = append(f.giveRequests, req)
|
||||
return nil
|
||||
@ -732,6 +741,98 @@ func TestUnbanUserAllowsFrozenUser(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestListCountriesReturnsOpenCountries(t *testing.T) {
|
||||
service, _ := newManagerCenterTestService(t)
|
||||
db := service.db.(*gorm.DB)
|
||||
seedManager(t, db, 1)
|
||||
seedCountries(t, db,
|
||||
sysCountryCodeRow{ID: 10, AlphaTwo: "SA", CountryName: "Saudi Arabia", Open: true, Sort: 2},
|
||||
sysCountryCodeRow{ID: 11, AlphaTwo: "AE", CountryName: "United Arab Emirates", Open: true, Sort: 1},
|
||||
sysCountryCodeRow{ID: 12, AlphaTwo: "XX", CountryName: "Closed", Open: false, Sort: 3},
|
||||
)
|
||||
|
||||
resp, err := service.ListCountries(context.Background(), AuthUser{UserID: 1})
|
||||
if err != nil {
|
||||
t.Fatalf("ListCountries() error = %v", err)
|
||||
}
|
||||
if len(resp.Records) != 2 {
|
||||
t.Fatalf("countries = %+v, want two open rows", resp.Records)
|
||||
}
|
||||
if resp.Records[0].CountryCode != "AE" || resp.Records[1].CountryCode != "SA" {
|
||||
t.Fatalf("countries = %+v, want sort order AE then SA", resp.Records)
|
||||
}
|
||||
}
|
||||
|
||||
func TestChangeUserCountryUpdatesCountryAndClearsCache(t *testing.T) {
|
||||
service, fake := newManagerCenterTestService(t)
|
||||
db := service.db.(*gorm.DB)
|
||||
seedManager(t, db, 1)
|
||||
seedUsers(t, db, userBaseInfoRow{ID: 2, Account: "2", CountryID: 10, CountryCode: "SA", CountryName: "Saudi Arabia"})
|
||||
seedCountries(t, db, sysCountryCodeRow{ID: 11, AlphaTwo: "AE", CountryName: "United Arab Emirates", Open: true})
|
||||
|
||||
resp, err := service.ChangeUserCountry(context.Background(), AuthUser{UserID: 1}, ChangeUserCountryRequest{
|
||||
UserID: ID(2),
|
||||
CountryID: ID(11),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("ChangeUserCountry() error = %v", err)
|
||||
}
|
||||
if !resp.Success || resp.User.CountryCode != "AE" || resp.User.CountryName != "United Arab Emirates" {
|
||||
t.Fatalf("resp = %+v, want changed country", resp)
|
||||
}
|
||||
|
||||
var row userBaseInfoRow
|
||||
if err := db.Where("id = ?", int64(2)).First(&row).Error; err != nil {
|
||||
t.Fatalf("load user: %v", err)
|
||||
}
|
||||
if row.CountryID != 11 || row.CountryCode != "AE" || row.CountryName != "United Arab Emirates" || row.UpdateUser != 1 {
|
||||
t.Fatalf("user row = %+v, want AE country and manager updater", row)
|
||||
}
|
||||
if !equalInt64Slice(fake.cacheCleared, []int64{2}) {
|
||||
t.Fatalf("cacheCleared = %+v, want [2]", fake.cacheCleared)
|
||||
}
|
||||
}
|
||||
|
||||
func TestChangeUserCountryRejectsHistoryIdentity(t *testing.T) {
|
||||
service, _ := newManagerCenterTestService(t)
|
||||
db := service.db.(*gorm.DB)
|
||||
seedManager(t, db, 1)
|
||||
seedUsers(t, db, userBaseInfoRow{ID: 2, Account: "2", CountryID: 10, CountryCode: "SA"})
|
||||
seedCountries(t, db, sysCountryCodeRow{ID: 11, AlphaTwo: "AE", CountryName: "United Arab Emirates", Open: true})
|
||||
if err := db.Create(&userHistoryIdentityRow{UserID: 2, IsHost: true}).Error; err != nil {
|
||||
t.Fatalf("seed identity: %v", err)
|
||||
}
|
||||
|
||||
_, err := service.ChangeUserCountry(context.Background(), AuthUser{UserID: 1}, ChangeUserCountryRequest{UserID: ID(2), CountryID: ID(11)})
|
||||
assertAppErrorCode(t, err, "user_identity_locked")
|
||||
}
|
||||
|
||||
func TestChangeUserCountryRejectsBDLeader(t *testing.T) {
|
||||
service, _ := newManagerCenterTestService(t)
|
||||
db := service.db.(*gorm.DB)
|
||||
seedManager(t, db, 1)
|
||||
seedUsers(t, db, userBaseInfoRow{ID: 2, Account: "2", CountryID: 10, CountryCode: "SA"})
|
||||
seedCountries(t, db, sysCountryCodeRow{ID: 11, AlphaTwo: "AE", CountryName: "United Arab Emirates", Open: true})
|
||||
if err := db.Create(&bdLeaderRow{ID: 20, UserID: 2, Origin: "LIKEI", RegionID: "SA"}).Error; err != nil {
|
||||
t.Fatalf("seed bd leader: %v", err)
|
||||
}
|
||||
|
||||
_, err := service.ChangeUserCountry(context.Background(), AuthUser{UserID: 1}, ChangeUserCountryRequest{UserID: ID(2), CountryID: ID(11)})
|
||||
assertAppErrorCode(t, err, "user_identity_locked")
|
||||
}
|
||||
|
||||
func TestChangeUserCountryRejectsCoinSeller(t *testing.T) {
|
||||
service, fake := newManagerCenterTestService(t)
|
||||
db := service.db.(*gorm.DB)
|
||||
seedManager(t, db, 1)
|
||||
seedUsers(t, db, userBaseInfoRow{ID: 2, Account: "2", CountryID: 10, CountryCode: "SA"})
|
||||
seedCountries(t, db, sysCountryCodeRow{ID: 11, AlphaTwo: "AE", CountryName: "United Arab Emirates", Open: true})
|
||||
fake.freightSellers[2] = true
|
||||
|
||||
_, err := service.ChangeUserCountry(context.Background(), AuthUser{UserID: 1}, ChangeUserCountryRequest{UserID: ID(2), CountryID: ID(11)})
|
||||
assertAppErrorCode(t, err, "user_identity_locked")
|
||||
}
|
||||
|
||||
func newManagerCenterTestService(t *testing.T) (*Service, *fakeManagerGateway) {
|
||||
t.Helper()
|
||||
db, err := gorm.Open(sqlite.Open("file:"+t.Name()+"?mode=memory&cache=shared"), &gorm.Config{})
|
||||
@ -741,6 +842,7 @@ func newManagerCenterTestService(t *testing.T) (*Service, *fakeManagerGateway) {
|
||||
if err := db.AutoMigrate(
|
||||
&teamManagerInfoRow{},
|
||||
&userBaseInfoRow{},
|
||||
&sysCountryCodeRow{},
|
||||
&bdLeaderRow{},
|
||||
&businessDevelopmentBaseInfoRow{},
|
||||
&userHistoryIdentityRow{},
|
||||
@ -755,8 +857,9 @@ func newManagerCenterTestService(t *testing.T) (*Service, *fakeManagerGateway) {
|
||||
t.Fatalf("auto migrate: %v", err)
|
||||
}
|
||||
fake := &fakeManagerGateway{
|
||||
recharges: map[int64][]integration.UserTotalRecharge{},
|
||||
abilities: map[int64]integration.PropsNobleVIPAbility{},
|
||||
recharges: map[int64][]integration.UserTotalRecharge{},
|
||||
freightSellers: map[int64]bool{},
|
||||
abilities: map[int64]integration.PropsNobleVIPAbility{},
|
||||
}
|
||||
return NewService(db, fake), fake
|
||||
}
|
||||
@ -803,6 +906,15 @@ func seedUsers(t *testing.T, db *gorm.DB, rows ...userBaseInfoRow) {
|
||||
}
|
||||
}
|
||||
|
||||
func seedCountries(t *testing.T, db *gorm.DB, rows ...sysCountryCodeRow) {
|
||||
t.Helper()
|
||||
for _, row := range rows {
|
||||
if err := db.Create(&row).Error; err != nil {
|
||||
t.Fatalf("seed country: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func seedProps(t *testing.T, db *gorm.DB, rows ...propsSourceRecordRow) {
|
||||
t.Helper()
|
||||
for _, row := range rows {
|
||||
|
||||
@ -60,6 +60,7 @@ type managerGateway interface {
|
||||
GetUserProfile(ctx context.Context, userID int64) (integration.UserProfile, error)
|
||||
GetUserProfileByAccountOne(ctx context.Context, account string) (integration.UserProfile, error)
|
||||
MapUserTotalRecharge(ctx context.Context, userIDs []int64) (map[int64][]integration.UserTotalRecharge, error)
|
||||
ExistsFreightSeller(ctx context.Context, userID int64) (bool, error)
|
||||
GivePropsBackpack(ctx context.Context, req integration.GivePropsBackpackRequest) error
|
||||
GetNobleVIPAbility(ctx context.Context, sourceID int64) (integration.PropsNobleVIPAbility, error)
|
||||
GetUserMaxNobleVIPAbility(ctx context.Context, userID int64) (integration.PropsNobleVIPAbility, error)
|
||||
@ -130,11 +131,24 @@ type UserSearchResponse struct {
|
||||
User UserView `json:"user"`
|
||||
}
|
||||
|
||||
type CountryListResponse struct {
|
||||
Records []CountryView `json:"records"`
|
||||
}
|
||||
|
||||
type CountryView struct {
|
||||
ID ID `json:"id"`
|
||||
CountryCode string `json:"countryCode"`
|
||||
CountryName string `json:"countryName"`
|
||||
NationalFlag string `json:"nationalFlag,omitempty"`
|
||||
PhonePrefix int `json:"phonePrefix,omitempty"`
|
||||
}
|
||||
|
||||
type UserView struct {
|
||||
UserID ID `json:"userId"`
|
||||
Account string `json:"account"`
|
||||
UserAvatar string `json:"userAvatar"`
|
||||
UserNickname string `json:"userNickname"`
|
||||
CountryID ID `json:"countryId,omitempty"`
|
||||
CountryCode string `json:"countryCode,omitempty"`
|
||||
CountryName string `json:"countryName,omitempty"`
|
||||
OriginSys string `json:"originSys,omitempty"`
|
||||
@ -196,6 +210,16 @@ type UnbanUserResponse struct {
|
||||
AccountStatus string `json:"accountStatus"`
|
||||
}
|
||||
|
||||
type ChangeUserCountryRequest struct {
|
||||
UserID ID `json:"userId"`
|
||||
CountryID ID `json:"countryId"`
|
||||
}
|
||||
|
||||
type ChangeUserCountryResponse struct {
|
||||
Success bool `json:"success"`
|
||||
User UserView `json:"user"`
|
||||
}
|
||||
|
||||
type BDLeaderListResponse struct {
|
||||
Count int `json:"count"`
|
||||
Records []BDLeaderView `json:"records"`
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user