即构游戏
This commit is contained in:
parent
785058a189
commit
55bd030585
@ -10,21 +10,25 @@ import (
|
||||
"hyapp-admin-server/internal/integration/userclient"
|
||||
"hyapp-admin-server/internal/integration/walletclient"
|
||||
walletv1 "hyapp.local/api/proto/wallet/v1"
|
||||
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
const (
|
||||
coinSellerMerchantAssetType = "COIN_SELLER_COIN"
|
||||
coinSellerStockTypePurchase = "usdt_purchase"
|
||||
coinSellerStockTypeDeduction = "usdt_deduction"
|
||||
coinSellerStockTypeCompensate = "coin_compensation"
|
||||
agencyStatusDeleted = "deleted"
|
||||
membershipStatusActive = "active"
|
||||
paidCurrencyUSDT = "USDT"
|
||||
sortByDiamond = "diamond"
|
||||
sortByMerchantBalance = "merchant_balance"
|
||||
sortBySalaryWallet = "salary_wallet"
|
||||
sortByTotalRechargeUSDT = "total_recharge_usdt"
|
||||
bdLeaderPositionAliasMaxRunes = 64
|
||||
coinSellerMerchantAssetType = "COIN_SELLER_COIN"
|
||||
coinSellerStockTypePurchase = "usdt_purchase"
|
||||
coinSellerStockTypeDeduction = "usdt_deduction"
|
||||
coinSellerStockTypeCompensate = "coin_compensation"
|
||||
agencyStatusDeleted = "deleted"
|
||||
membershipStatusActive = "active"
|
||||
paidCurrencyUSDT = "USDT"
|
||||
sortByDiamond = "diamond"
|
||||
sortByMerchantBalance = "merchant_balance"
|
||||
sortBySalaryWallet = "salary_wallet"
|
||||
sortByTotalRechargeUSDT = "total_recharge_usdt"
|
||||
bdLeaderPositionAliasMaxRunes = 64
|
||||
hostOrgInternalUserIDMinDigits = 15
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
@ -481,18 +485,62 @@ func (s *Service) resolveDisplayUserID(ctx context.Context, requestID string, di
|
||||
if displayUserID <= 0 {
|
||||
return 0, fmt.Errorf("display_user_id is required")
|
||||
}
|
||||
rawID := strconv.FormatInt(displayUserID, 10)
|
||||
userIDChecked := false
|
||||
if len(strings.TrimLeft(rawID, "0")) >= hostOrgInternalUserIDMinDigits {
|
||||
// 团队后台新合约的 targetUserId 可能是内部雪花 user_id;长数字先按 user_id 确认,避免把内部 ID 误送到短号解析。
|
||||
userIDChecked = true
|
||||
found, err := s.userIDExists(ctx, requestID, displayUserID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if found {
|
||||
return displayUserID, nil
|
||||
}
|
||||
}
|
||||
identity, err := s.userClient.ResolveDisplayUserID(ctx, userclient.ResolveDisplayUserIDRequest{
|
||||
RequestID: requestID,
|
||||
Caller: "hyapp-admin-server",
|
||||
DisplayUserID: strconv.FormatInt(displayUserID, 10),
|
||||
DisplayUserID: rawID,
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
if !isGRPCNotFound(err) {
|
||||
return 0, err
|
||||
}
|
||||
} else if identity != nil && identity.UserID > 0 {
|
||||
return identity.UserID, nil
|
||||
}
|
||||
if identity == nil || identity.UserID <= 0 {
|
||||
return 0, fmt.Errorf("display_user_id %d not found", displayUserID)
|
||||
|
||||
if !userIDChecked {
|
||||
// 当前 active 短号解析失败后,短数字仍可能是本地/旧后台直接填写的真实 user_id 或 held 默认短号;只读 GetUser 做存在性确认,不改变 user-service 的 active 短号协议。
|
||||
found, err := s.userIDExists(ctx, requestID, displayUserID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if found {
|
||||
return displayUserID, nil
|
||||
}
|
||||
}
|
||||
return identity.UserID, nil
|
||||
return 0, fmt.Errorf("display_user_id %d not found", displayUserID)
|
||||
}
|
||||
|
||||
func (s *Service) userIDExists(ctx context.Context, requestID string, userID int64) (bool, error) {
|
||||
user, err := s.userClient.GetUser(ctx, userclient.GetUserRequest{
|
||||
RequestID: requestID,
|
||||
Caller: "hyapp-admin-server",
|
||||
UserID: userID,
|
||||
})
|
||||
if err != nil {
|
||||
if isGRPCNotFound(err) {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
return user != nil && user.UserID > 0, nil
|
||||
}
|
||||
|
||||
func isGRPCNotFound(err error) bool {
|
||||
return status.Code(err) == codes.NotFound
|
||||
}
|
||||
|
||||
func normalizeBDLeaderPositionAlias(value string) (string, error) {
|
||||
|
||||
@ -1,13 +1,86 @@
|
||||
package hostorg
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"hyapp-admin-server/internal/integration/userclient"
|
||||
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
type fakeHostOrgUserClient struct {
|
||||
userclient.Client
|
||||
users map[int64]*userclient.User
|
||||
displays map[string]*userclient.UserIdentity
|
||||
calls []string
|
||||
}
|
||||
|
||||
func (f *fakeHostOrgUserClient) GetUser(_ context.Context, req userclient.GetUserRequest) (*userclient.User, error) {
|
||||
f.calls = append(f.calls, "get:"+strconv.FormatInt(req.UserID, 10))
|
||||
if user := f.users[req.UserID]; user != nil {
|
||||
return user, nil
|
||||
}
|
||||
return nil, status.Error(codes.NotFound, "user not found")
|
||||
}
|
||||
|
||||
func (f *fakeHostOrgUserClient) ResolveDisplayUserID(_ context.Context, req userclient.ResolveDisplayUserIDRequest) (*userclient.UserIdentity, error) {
|
||||
f.calls = append(f.calls, "resolve:"+req.DisplayUserID)
|
||||
if identity := f.displays[req.DisplayUserID]; identity != nil {
|
||||
return identity, nil
|
||||
}
|
||||
return nil, status.Error(codes.NotFound, "display_user_id not found")
|
||||
}
|
||||
|
||||
func TestResolveDisplayUserIDFallsBackToNumericUserID(t *testing.T) {
|
||||
client := &fakeHostOrgUserClient{
|
||||
users: map[int64]*userclient.User{
|
||||
123456: {UserID: 123456, DisplayUserID: "9999", DefaultDisplayUserID: "123456"},
|
||||
},
|
||||
displays: map[string]*userclient.UserIdentity{},
|
||||
}
|
||||
service := NewService(client, nil, nil)
|
||||
|
||||
userID, err := service.resolveDisplayUserID(context.Background(), "req-held-default", 123456)
|
||||
if err != nil {
|
||||
t.Fatalf("resolveDisplayUserID returned error: %v", err)
|
||||
}
|
||||
if userID != 123456 {
|
||||
t.Fatalf("fallback user id mismatch: got %d", userID)
|
||||
}
|
||||
if want := []string{"resolve:123456", "get:123456"}; !reflect.DeepEqual(client.calls, want) {
|
||||
t.Fatalf("calls mismatch: got %v want %v", client.calls, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveDisplayUserIDKeepsActiveDisplayPriority(t *testing.T) {
|
||||
client := &fakeHostOrgUserClient{
|
||||
users: map[int64]*userclient.User{
|
||||
123456: {UserID: 123456, DisplayUserID: "9999", DefaultDisplayUserID: "123456"},
|
||||
},
|
||||
displays: map[string]*userclient.UserIdentity{
|
||||
"123456": {UserID: 88, DisplayUserID: "123456"},
|
||||
},
|
||||
}
|
||||
service := NewService(client, nil, nil)
|
||||
|
||||
userID, err := service.resolveDisplayUserID(context.Background(), "req-active-display", 123456)
|
||||
if err != nil {
|
||||
t.Fatalf("resolveDisplayUserID returned error: %v", err)
|
||||
}
|
||||
if userID != 88 {
|
||||
t.Fatalf("active display user id mismatch: got %d", userID)
|
||||
}
|
||||
if want := []string{"resolve:123456"}; !reflect.DeepEqual(client.calls, want) {
|
||||
t.Fatalf("calls mismatch: got %v want %v", client.calls, want)
|
||||
}
|
||||
}
|
||||
|
||||
// TestNormalizeListQueryAllowsComputedSorts 锁定后台列表支持的计算排序字段不会在查询归一化时被清掉。
|
||||
func TestNormalizeListQueryAllowsComputedSorts(t *testing.T) {
|
||||
for _, sortBy := range []string{sortByMerchantBalance, sortBySalaryWallet, sortByTotalRechargeUSDT} {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user