增加用户的manager身份
This commit is contained in:
parent
245412ae95
commit
ad4a755998
@ -442,7 +442,7 @@ func (x *CoinSellerProfile) GetUpdatedAtMs() int64 {
|
||||
}
|
||||
|
||||
// UserRoleSummary 是 App 我的页和入口显隐使用的轻量角色摘要。
|
||||
// 它把 host、Agency、BD 和币商身份收敛到一次 user-service RPC,避免 gateway 随角色扩张继续 fanout。
|
||||
// 它把 host、Agency、manager、BD 和币商身份收敛到一次 user-service RPC,避免 gateway 随角色扩张继续 fanout。
|
||||
type UserRoleSummary struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
UserId int64 `protobuf:"varint,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
|
||||
@ -457,6 +457,7 @@ type UserRoleSummary struct {
|
||||
BdStatus string `protobuf:"bytes,10,opt,name=bd_status,json=bdStatus,proto3" json:"bd_status,omitempty"`
|
||||
CoinSellerStatus string `protobuf:"bytes,11,opt,name=coin_seller_status,json=coinSellerStatus,proto3" json:"coin_seller_status,omitempty"`
|
||||
PendingRoleInvitations int64 `protobuf:"varint,12,opt,name=pending_role_invitations,json=pendingRoleInvitations,proto3" json:"pending_role_invitations,omitempty"`
|
||||
IsManager bool `protobuf:"varint,13,opt,name=is_manager,json=isManager,proto3" json:"is_manager,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
@ -575,6 +576,13 @@ func (x *UserRoleSummary) GetPendingRoleInvitations() int64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *UserRoleSummary) GetIsManager() bool {
|
||||
if x != nil {
|
||||
return x.IsManager
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// AgencyMembership 是 host 与 Agency 的有时效关系事实。
|
||||
type AgencyMembership struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
@ -3689,7 +3697,7 @@ const file_proto_user_v1_host_proto_rawDesc = "" +
|
||||
"\x13merchant_asset_type\x18\x03 \x01(\tR\x11merchantAssetType\x12+\n" +
|
||||
"\x12created_by_user_id\x18\x04 \x01(\x03R\x0fcreatedByUserId\x12\"\n" +
|
||||
"\rcreated_at_ms\x18\x05 \x01(\x03R\vcreatedAtMs\x12\"\n" +
|
||||
"\rupdated_at_ms\x18\x06 \x01(\x03R\vupdatedAtMs\"\x95\x03\n" +
|
||||
"\rupdated_at_ms\x18\x06 \x01(\x03R\vupdatedAtMs\"\xb4\x03\n" +
|
||||
"\x0fUserRoleSummary\x12\x17\n" +
|
||||
"\auser_id\x18\x01 \x01(\x03R\x06userId\x12\x17\n" +
|
||||
"\ais_host\x18\x02 \x01(\bR\x06isHost\x12\x1b\n" +
|
||||
@ -3705,7 +3713,9 @@ const file_proto_user_v1_host_proto_rawDesc = "" +
|
||||
"\tbd_status\x18\n" +
|
||||
" \x01(\tR\bbdStatus\x12,\n" +
|
||||
"\x12coin_seller_status\x18\v \x01(\tR\x10coinSellerStatus\x128\n" +
|
||||
"\x18pending_role_invitations\x18\f \x01(\x03R\x16pendingRoleInvitations\"\xaa\x03\n" +
|
||||
"\x18pending_role_invitations\x18\f \x01(\x03R\x16pendingRoleInvitations\x12\x1d\n" +
|
||||
"\n" +
|
||||
"is_manager\x18\r \x01(\bR\tisManager\"\xaa\x03\n" +
|
||||
"\x10AgencyMembership\x12#\n" +
|
||||
"\rmembership_id\x18\x01 \x01(\x03R\fmembershipId\x12\x1b\n" +
|
||||
"\tagency_id\x18\x02 \x01(\x03R\bagencyId\x12 \n" +
|
||||
|
||||
@ -57,7 +57,7 @@ message CoinSellerProfile {
|
||||
}
|
||||
|
||||
// UserRoleSummary 是 App 我的页和入口显隐使用的轻量角色摘要。
|
||||
// 它把 host、Agency、BD 和币商身份收敛到一次 user-service RPC,避免 gateway 随角色扩张继续 fanout。
|
||||
// 它把 host、Agency、manager、BD 和币商身份收敛到一次 user-service RPC,避免 gateway 随角色扩张继续 fanout。
|
||||
message UserRoleSummary {
|
||||
int64 user_id = 1;
|
||||
bool is_host = 2;
|
||||
@ -71,6 +71,7 @@ message UserRoleSummary {
|
||||
string bd_status = 10;
|
||||
string coin_seller_status = 11;
|
||||
int64 pending_role_invitations = 12;
|
||||
bool is_manager = 13;
|
||||
}
|
||||
|
||||
// AgencyMembership 是 host 与 Agency 的有时效关系事实。
|
||||
|
||||
@ -2717,7 +2717,10 @@ definitions:
|
||||
description: 用户是否拥有 active host profile。
|
||||
is_agent:
|
||||
type: boolean
|
||||
description: 用户是否拥有 active agency owner 身份。
|
||||
description: 用户是否拥有 Agency 入口身份;active Agency owner 或 Agency 来源主播都可能为 true。
|
||||
is_manager:
|
||||
type: boolean
|
||||
description: 用户是否拥有经理中心身份;首版等价于 active Agency owner。
|
||||
is_bd:
|
||||
type: boolean
|
||||
description: 用户是否拥有 active BD 或 BD Leader 身份。
|
||||
@ -2732,6 +2735,7 @@ definitions:
|
||||
required:
|
||||
- is_host
|
||||
- is_agency
|
||||
- is_manager
|
||||
- is_bd
|
||||
- is_bd_leader
|
||||
- is_coin_seller
|
||||
@ -2741,6 +2745,8 @@ definitions:
|
||||
type: boolean
|
||||
is_agency:
|
||||
type: boolean
|
||||
is_manager:
|
||||
type: boolean
|
||||
is_bd:
|
||||
type: boolean
|
||||
is_bd_leader:
|
||||
@ -3170,6 +3176,7 @@ definitions:
|
||||
type: string
|
||||
enum:
|
||||
- host-center
|
||||
- manager-center
|
||||
- bd-center
|
||||
- bd-leader-center
|
||||
- agency-center
|
||||
|
||||
@ -49,6 +49,7 @@ Authorization: Bearer <access_token>
|
||||
"roles": {
|
||||
"is_host": true,
|
||||
"is_agency": false,
|
||||
"is_manager": false,
|
||||
"is_bd": false,
|
||||
"is_bd_leader": false,
|
||||
"is_coin_seller": false,
|
||||
@ -116,6 +117,7 @@ Authorization: Bearer <access_token>
|
||||
| `apply_host` | `roles.is_host == false` |
|
||||
| `host_center` | `roles.is_host == true` |
|
||||
| `agency_center` | `roles.is_agency == true` |
|
||||
| `manager_center` | `roles.is_manager == true` |
|
||||
| `bd_center` | `roles.is_bd == true` |
|
||||
| `bd_leader_center` | `roles.is_bd_leader == true` |
|
||||
| `coin_seller_center` | `roles.is_coin_seller == true` |
|
||||
|
||||
@ -247,12 +247,12 @@ func (s *Store) seedMenus() error {
|
||||
{ParentID: &gameID, Title: "游戏列表", Code: "game-list", Path: "/games", Icon: "sports_esports", PermissionCode: "game:view", Sort: 70, Visible: true},
|
||||
{ParentID: &geoID, Title: "国家管理", Code: "host-org-countries", Path: "/host/countries", Icon: "public", PermissionCode: "country:view", Sort: 70, Visible: true},
|
||||
{ParentID: &geoID, Title: "区域管理", Code: "host-org-regions", Path: "/host/regions", Icon: "map", PermissionCode: "region:view", Sort: 71, Visible: true},
|
||||
{ParentID: &hostOrgID, Title: "经理列表", Code: "host-org-managers", Path: "/host/managers", Icon: "users", PermissionCode: "agency:view", Sort: 80, Visible: true},
|
||||
{ParentID: &hostOrgID, Title: "Manager列表", Code: "host-org-managers", Path: "/host/managers", Icon: "users", PermissionCode: "agency:view", Sort: 80, Visible: true},
|
||||
{ParentID: &hostOrgID, Title: "Agency 列表", Code: "host-org-agencies", Path: "/host/agencies", Icon: "apartment", PermissionCode: "agency:view", Sort: 81, Visible: true},
|
||||
{ParentID: &hostOrgID, Title: "BD Leader 列表", Code: "host-org-bd-leaders", Path: "/host/bd-leaders", Icon: "shield", PermissionCode: "bd:view", Sort: 82, Visible: true},
|
||||
{ParentID: &hostOrgID, Title: "BD 列表", Code: "host-org-bds", Path: "/host/bds", Icon: "team", PermissionCode: "bd:view", Sort: 83, Visible: true},
|
||||
{ParentID: &hostOrgID, Title: "主播列表", Code: "host-org-hosts", Path: "/host/hosts", Icon: "users", PermissionCode: "host:view", Sort: 84, Visible: true},
|
||||
{ParentID: &hostOrgID, Title: "币商列表", Code: "host-org-coin-sellers", Path: "/host/coin-sellers", Icon: "wallet", PermissionCode: "coin-seller:view", Sort: 85, Visible: true},
|
||||
{ParentID: &hostOrgID, Title: "Host 列表", Code: "host-org-hosts", Path: "/host/hosts", Icon: "users", PermissionCode: "host:view", Sort: 84, Visible: true},
|
||||
{ParentID: &hostOrgID, Title: "Coin Saller列表", Code: "host-org-coin-sellers", Path: "/host/coin-sellers", Icon: "wallet", PermissionCode: "coin-seller:view", Sort: 85, Visible: true},
|
||||
}
|
||||
for _, menu := range children {
|
||||
if _, err := s.syncDefaultMenu(s.db, menu); err != nil {
|
||||
|
||||
@ -34,6 +34,7 @@ func TestGetMyOverviewComposesProfileWalletVIPStatsRolesAndEntries(t *testing.T)
|
||||
UserId: 42,
|
||||
IsHost: true,
|
||||
IsAgency: true,
|
||||
IsManager: true,
|
||||
IsBd: true,
|
||||
IsBdLeader: true,
|
||||
IsCoinSeller: true,
|
||||
@ -81,7 +82,7 @@ func TestGetMyOverviewComposesProfileWalletVIPStatsRolesAndEntries(t *testing.T)
|
||||
t.Fatalf("profile stats mismatch: %+v", stats)
|
||||
}
|
||||
roles := data["roles"].(map[string]any)
|
||||
if roles["is_host"] != true || roles["is_agency"] != true || roles["is_bd"] != true || roles["is_bd_leader"] != true || roles["is_coin_seller"] != true || roles["agency_id"] != float64(7001) {
|
||||
if roles["is_host"] != true || roles["is_agency"] != true || roles["is_manager"] != true || roles["is_bd"] != true || roles["is_bd_leader"] != true || roles["is_coin_seller"] != true || roles["agency_id"] != float64(7001) {
|
||||
t.Fatalf("roles data mismatch: %+v", roles)
|
||||
}
|
||||
wallet := data["wallet"].(map[string]any)
|
||||
@ -106,6 +107,7 @@ func TestGetMyOverviewComposesProfileWalletVIPStatsRolesAndEntries(t *testing.T)
|
||||
!overviewEntryVisible(entries, "task") ||
|
||||
!overviewEntryVisible(entries, "host_center") ||
|
||||
!overviewEntryVisible(entries, "agency_center") ||
|
||||
!overviewEntryVisible(entries, "manager_center") ||
|
||||
!overviewEntryVisible(entries, "bd_center") ||
|
||||
!overviewEntryVisible(entries, "bd_leader_center") ||
|
||||
!overviewEntryVisible(entries, "coin_seller_center") ||
|
||||
@ -136,7 +138,7 @@ func TestGetMyOverviewProjectsOrdinaryUserEntriesAndZeroWallet(t *testing.T) {
|
||||
t.Fatalf("missing stats should be zero projection: %+v", stats)
|
||||
}
|
||||
roles := data["roles"].(map[string]any)
|
||||
if roles["is_host"] != false || roles["is_bd"] != false || roles["is_coin_seller"] != false {
|
||||
if roles["is_host"] != false || roles["is_manager"] != false || roles["is_bd"] != false || roles["is_coin_seller"] != false {
|
||||
t.Fatalf("ordinary roles mismatch: %+v", roles)
|
||||
}
|
||||
entries := data["entries"].([]any)
|
||||
@ -162,11 +164,11 @@ func TestGetMyOverviewDegradesOptionalUpstreamFailures(t *testing.T) {
|
||||
t.Fatalf("profile stats degradation mismatch: %+v", stats)
|
||||
}
|
||||
roles := data["roles"].(map[string]any)
|
||||
if roles["unavailable"] != true || roles["is_host"] != false || roles["is_bd"] != false || roles["is_coin_seller"] != false {
|
||||
if roles["unavailable"] != true || roles["is_host"] != false || roles["is_manager"] != false || roles["is_bd"] != false || roles["is_coin_seller"] != false {
|
||||
t.Fatalf("roles degradation mismatch: %+v", roles)
|
||||
}
|
||||
entries := data["entries"].([]any)
|
||||
if overviewEntryVisible(entries, "host_center") || overviewEntryVisible(entries, "bd_center") || overviewEntryVisible(entries, "coin_seller_center") {
|
||||
if overviewEntryVisible(entries, "host_center") || overviewEntryVisible(entries, "manager_center") || overviewEntryVisible(entries, "bd_center") || overviewEntryVisible(entries, "coin_seller_center") {
|
||||
t.Fatalf("degraded roles must not expose privileged entries: %+v", entries)
|
||||
}
|
||||
}
|
||||
|
||||
@ -2427,20 +2427,14 @@ func TestGetAppVersionReturnsLatestVersionAndUpdateDecision(t *testing.T) {
|
||||
|
||||
func TestGetMyHostIdentityCombinesActiveHostAndBDProfiles(t *testing.T) {
|
||||
hostClient := &fakeUserHostClient{
|
||||
hostProfile: &userv1.HostProfile{
|
||||
UserId: 42,
|
||||
Status: "active",
|
||||
Source: "admin_create_agency",
|
||||
},
|
||||
bdProfile: &userv1.BDProfile{
|
||||
UserId: 42,
|
||||
Status: "active",
|
||||
Role: "bd_leader",
|
||||
},
|
||||
profile: &userv1.CoinSellerProfile{
|
||||
UserId: 42,
|
||||
Status: "active",
|
||||
MerchantAssetType: "COIN_SELLER_COIN",
|
||||
roleSummary: &userv1.UserRoleSummary{
|
||||
UserId: 42,
|
||||
IsHost: true,
|
||||
IsAgency: true,
|
||||
IsManager: true,
|
||||
IsBd: true,
|
||||
IsBdLeader: true,
|
||||
IsCoinSeller: true,
|
||||
},
|
||||
}
|
||||
handler := NewHandlerWithClients(&fakeRoomClient{}, nil, nil, &fakeUserProfileClient{})
|
||||
@ -2456,14 +2450,8 @@ func TestGetMyHostIdentityCombinesActiveHostAndBDProfiles(t *testing.T) {
|
||||
if recorder.Code != http.StatusOK {
|
||||
t.Fatalf("status mismatch: got %d body=%s", recorder.Code, recorder.Body.String())
|
||||
}
|
||||
if hostClient.lastHost == nil || hostClient.lastHost.GetUserId() != 42 || hostClient.lastHost.GetMeta().GetRequestId() != assertGeneratedRequestID(t, recorder, "req-host-identity") {
|
||||
t.Fatalf("host identity host request mismatch: %+v", hostClient.lastHost)
|
||||
}
|
||||
if hostClient.lastBD == nil || hostClient.lastBD.GetUserId() != 42 {
|
||||
t.Fatalf("host identity bd request mismatch: %+v", hostClient.lastBD)
|
||||
}
|
||||
if hostClient.last == nil || hostClient.last.GetUserId() != 42 {
|
||||
t.Fatalf("host identity coin seller request mismatch: %+v", hostClient.last)
|
||||
if hostClient.lastRoleSummary == nil || hostClient.lastRoleSummary.GetUserId() != 42 || hostClient.lastRoleSummary.GetMeta().GetRequestId() != assertGeneratedRequestID(t, recorder, "req-host-identity") {
|
||||
t.Fatalf("host identity role summary request mismatch: %+v", hostClient.lastRoleSummary)
|
||||
}
|
||||
var response httpkit.ResponseEnvelope
|
||||
if err := json.NewDecoder(recorder.Body).Decode(&response); err != nil {
|
||||
@ -2473,6 +2461,7 @@ func TestGetMyHostIdentityCombinesActiveHostAndBDProfiles(t *testing.T) {
|
||||
if response.Code != httpkit.CodeOK || !ok ||
|
||||
data["is_host"] != true ||
|
||||
data["is_agent"] != true ||
|
||||
data["is_manager"] != true ||
|
||||
data["is_bd"] != true ||
|
||||
data["is_bd_leader"] != true ||
|
||||
data["is_coin_seller"] != true {
|
||||
@ -2481,11 +2470,7 @@ func TestGetMyHostIdentityCombinesActiveHostAndBDProfiles(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetMyHostIdentityTreatsMissingProfilesAsFalse(t *testing.T) {
|
||||
hostClient := &fakeUserHostClient{
|
||||
hostErr: xerr.ToGRPCError(xerr.New(xerr.NotFound, "host profile not found")),
|
||||
bdErr: xerr.ToGRPCError(xerr.New(xerr.NotFound, "bd profile not found")),
|
||||
err: xerr.ToGRPCError(xerr.New(xerr.NotFound, "coin seller profile not found")),
|
||||
}
|
||||
hostClient := &fakeUserHostClient{}
|
||||
handler := NewHandlerWithClients(&fakeRoomClient{}, nil, nil, &fakeUserProfileClient{})
|
||||
handler.SetUserHostClient(hostClient)
|
||||
router := handler.Routes(auth.NewVerifier("secret"))
|
||||
@ -2507,6 +2492,7 @@ func TestGetMyHostIdentityTreatsMissingProfilesAsFalse(t *testing.T) {
|
||||
if response.Code != httpkit.CodeOK || !ok ||
|
||||
data["is_host"] != false ||
|
||||
data["is_agent"] != false ||
|
||||
data["is_manager"] != false ||
|
||||
data["is_bd"] != false ||
|
||||
data["is_bd_leader"] != false ||
|
||||
data["is_coin_seller"] != false {
|
||||
|
||||
@ -1,26 +1,17 @@
|
||||
package userapi
|
||||
|
||||
import (
|
||||
"hyapp/services/gateway-service/internal/transport/http/httpkit"
|
||||
"net/http"
|
||||
|
||||
userv1 "hyapp.local/api/proto/user/v1"
|
||||
"hyapp/pkg/xerr"
|
||||
"hyapp/services/gateway-service/internal/auth"
|
||||
)
|
||||
|
||||
const (
|
||||
hostIdentityActiveStatus = "active"
|
||||
hostIdentityAgencyInvitation = "agency_invitation"
|
||||
hostIdentityAdminCreateAgency = "admin_create_agency"
|
||||
hostIdentityBDRole = "bd"
|
||||
hostIdentityBDLeaderRole = "bd_leader"
|
||||
hostIdentityCoinSellerAsset = "COIN_SELLER_COIN"
|
||||
"hyapp/services/gateway-service/internal/transport/http/httpkit"
|
||||
)
|
||||
|
||||
type userHostIdentityData struct {
|
||||
IsHost bool `json:"is_host"`
|
||||
IsAgent bool `json:"is_agent"`
|
||||
IsManager bool `json:"is_manager"`
|
||||
IsBD bool `json:"is_bd"`
|
||||
IsBDLeader bool `json:"is_bd_leader"`
|
||||
IsCoinSeller bool `json:"is_coin_seller"`
|
||||
@ -32,50 +23,24 @@ func (h *Handler) getMyHostIdentity(writer http.ResponseWriter, request *http.Re
|
||||
httpkit.WriteError(writer, request, http.StatusBadGateway, httpkit.CodeUpstreamError, "upstream service error")
|
||||
return
|
||||
}
|
||||
|
||||
userID := auth.UserIDFromContext(request.Context())
|
||||
identity := userHostIdentityData{}
|
||||
|
||||
hostResp, err := h.userHostClient.GetHostProfile(request.Context(), &userv1.GetHostProfileRequest{
|
||||
resp, err := h.userHostClient.GetUserRoleSummary(request.Context(), &userv1.GetUserRoleSummaryRequest{
|
||||
Meta: httpkit.UserMeta(request, ""),
|
||||
UserId: userID,
|
||||
UserId: auth.UserIDFromContext(request.Context()),
|
||||
})
|
||||
if err != nil {
|
||||
if xerr.ReasonFromGRPC(err) != xerr.NotFound {
|
||||
httpkit.WriteRPCError(writer, request, err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
applyHostIdentity(&identity, hostResp.GetHostProfile())
|
||||
httpkit.WriteRPCError(writer, request, err)
|
||||
return
|
||||
}
|
||||
|
||||
bdResp, err := h.userHostClient.GetBDProfile(request.Context(), &userv1.GetBDProfileRequest{
|
||||
Meta: httpkit.UserMeta(request, ""),
|
||||
UserId: userID,
|
||||
summary := resp.GetSummary()
|
||||
httpkit.WriteOK(writer, request, userHostIdentityData{
|
||||
IsHost: summary.GetIsHost(),
|
||||
IsAgent: summary.GetIsAgency(),
|
||||
IsManager: summary.GetIsManager(),
|
||||
IsBD: summary.GetIsBd(),
|
||||
IsBDLeader: summary.GetIsBdLeader(),
|
||||
IsCoinSeller: summary.GetIsCoinSeller(),
|
||||
})
|
||||
if err != nil {
|
||||
if xerr.ReasonFromGRPC(err) != xerr.NotFound {
|
||||
httpkit.WriteRPCError(writer, request, err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
applyBDIdentity(&identity, bdResp.GetBdProfile())
|
||||
}
|
||||
|
||||
coinSellerResp, err := h.userHostClient.GetCoinSellerProfile(request.Context(), &userv1.GetCoinSellerProfileRequest{
|
||||
Meta: httpkit.UserMeta(request, ""),
|
||||
UserId: userID,
|
||||
})
|
||||
if err != nil {
|
||||
if xerr.ReasonFromGRPC(err) != xerr.NotFound {
|
||||
httpkit.WriteRPCError(writer, request, err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
applyCoinSellerIdentity(&identity, coinSellerResp.GetCoinSellerProfile())
|
||||
}
|
||||
|
||||
httpkit.WriteOK(writer, request, identity)
|
||||
}
|
||||
|
||||
// getMyRoleSummary 返回我的页入口显隐所需的完整角色摘要。
|
||||
@ -96,6 +61,7 @@ func (h *Handler) getMyRoleSummary(writer http.ResponseWriter, request *http.Req
|
||||
httpkit.WriteOK(writer, request, overviewRolesData{
|
||||
IsHost: summary.GetIsHost(),
|
||||
IsAgency: summary.GetIsAgency(),
|
||||
IsManager: summary.GetIsManager(),
|
||||
IsBD: summary.GetIsBd(),
|
||||
IsBDLeader: summary.GetIsBdLeader(),
|
||||
IsCoinSeller: summary.GetIsCoinSeller(),
|
||||
@ -107,39 +73,3 @@ func (h *Handler) getMyRoleSummary(writer http.ResponseWriter, request *http.Req
|
||||
PendingRoleInvitations: summary.GetPendingRoleInvitations(),
|
||||
})
|
||||
}
|
||||
|
||||
func applyHostIdentity(identity *userHostIdentityData, profile *userv1.HostProfile) {
|
||||
if profile == nil || profile.GetStatus() != hostIdentityActiveStatus {
|
||||
return
|
||||
}
|
||||
|
||||
identity.IsHost = true
|
||||
switch profile.GetSource() {
|
||||
case hostIdentityAgencyInvitation, hostIdentityAdminCreateAgency:
|
||||
identity.IsAgent = true
|
||||
}
|
||||
}
|
||||
|
||||
func applyBDIdentity(identity *userHostIdentityData, profile *userv1.BDProfile) {
|
||||
if profile == nil || profile.GetStatus() != hostIdentityActiveStatus {
|
||||
return
|
||||
}
|
||||
|
||||
switch profile.GetRole() {
|
||||
case hostIdentityBDLeaderRole:
|
||||
identity.IsBD = true
|
||||
identity.IsBDLeader = true
|
||||
case hostIdentityBDRole:
|
||||
identity.IsBD = true
|
||||
}
|
||||
}
|
||||
|
||||
func applyCoinSellerIdentity(identity *userHostIdentityData, profile *userv1.CoinSellerProfile) {
|
||||
if profile == nil ||
|
||||
profile.GetStatus() != hostIdentityActiveStatus ||
|
||||
profile.GetMerchantAssetType() != hostIdentityCoinSellerAsset {
|
||||
return
|
||||
}
|
||||
|
||||
identity.IsCoinSeller = true
|
||||
}
|
||||
|
||||
@ -35,6 +35,7 @@ type overviewWalletData struct {
|
||||
type overviewRolesData struct {
|
||||
IsHost bool `json:"is_host"`
|
||||
IsAgency bool `json:"is_agency"`
|
||||
IsManager bool `json:"is_manager"`
|
||||
IsBD bool `json:"is_bd"`
|
||||
IsBDLeader bool `json:"is_bd_leader"`
|
||||
IsCoinSeller bool `json:"is_coin_seller"`
|
||||
@ -183,6 +184,7 @@ func (h *Handler) getOverviewRoles(ctx context.Context, request *http.Request, u
|
||||
return overviewRolesData{
|
||||
IsHost: summary.GetIsHost(),
|
||||
IsAgency: summary.GetIsAgency(),
|
||||
IsManager: summary.GetIsManager(),
|
||||
IsBD: summary.GetIsBd(),
|
||||
IsBDLeader: summary.GetIsBdLeader(),
|
||||
IsCoinSeller: summary.GetIsCoinSeller(),
|
||||
@ -245,10 +247,11 @@ func overviewEntries(roles overviewRolesData) []overviewEntryData {
|
||||
{Key: "apply_host", Visible: !roles.IsHost, Enabled: true, Route: "/host/apply", IconKey: "host_apply", Order: 50},
|
||||
{Key: "host_center", Visible: roles.IsHost, Enabled: roles.IsHost, Route: "/host", IconKey: "host_center", Order: 60},
|
||||
{Key: "agency_center", Visible: roles.IsAgency, Enabled: roles.IsAgency, Route: "/agency", IconKey: "agency", Order: 70},
|
||||
{Key: "bd_center", Visible: roles.IsBD, Enabled: roles.IsBD, Route: "/bd", IconKey: "bd", Order: 80},
|
||||
{Key: "bd_leader_center", Visible: roles.IsBDLeader, Enabled: roles.IsBDLeader, Route: "/bd-leader", IconKey: "bd_leader", Order: 90},
|
||||
{Key: "coin_seller_center", Visible: roles.IsCoinSeller, Enabled: roles.IsCoinSeller, Route: "/coin-seller", IconKey: "coin_seller", Order: 100},
|
||||
{Key: "settings", Visible: true, Enabled: true, Route: "/settings", IconKey: "settings", Order: 110},
|
||||
{Key: "language", Visible: true, Enabled: true, Route: "/language", IconKey: "language", Order: 120},
|
||||
{Key: "manager_center", Visible: roles.IsManager, Enabled: roles.IsManager, Route: "/manager-center", IconKey: "manager_center", Order: 80},
|
||||
{Key: "bd_center", Visible: roles.IsBD, Enabled: roles.IsBD, Route: "/bd", IconKey: "bd", Order: 90},
|
||||
{Key: "bd_leader_center", Visible: roles.IsBDLeader, Enabled: roles.IsBDLeader, Route: "/bd-leader", IconKey: "bd_leader", Order: 100},
|
||||
{Key: "coin_seller_center", Visible: roles.IsCoinSeller, Enabled: roles.IsCoinSeller, Route: "/coin-seller", IconKey: "coin_seller", Order: 110},
|
||||
{Key: "settings", Visible: true, Enabled: true, Route: "/settings", IconKey: "settings", Order: 120},
|
||||
{Key: "language", Visible: true, Enabled: true, Route: "/language", IconKey: "language", Order: 130},
|
||||
}
|
||||
}
|
||||
|
||||
@ -184,6 +184,7 @@ type UserRoleSummary struct {
|
||||
UserID int64
|
||||
IsHost bool
|
||||
IsAgency bool
|
||||
IsManager bool
|
||||
IsBD bool
|
||||
IsBDLeader bool
|
||||
IsCoinSeller bool
|
||||
|
||||
@ -579,7 +579,7 @@ func TestGetUserRoleSummaryAggregatesRolesAndPendingInvitations(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("GetUserRoleSummary failed: %v", err)
|
||||
}
|
||||
if !summary.IsHost || !summary.IsAgency || !summary.IsBD || !summary.IsBDLeader || !summary.IsCoinSeller || summary.AgencyID != 933 || summary.BDID != 931 {
|
||||
if !summary.IsHost || !summary.IsAgency || !summary.IsManager || !summary.IsBD || !summary.IsBDLeader || !summary.IsCoinSeller || summary.AgencyID != 933 || summary.BDID != 931 {
|
||||
t.Fatalf("role summary mismatch: %+v", summary)
|
||||
}
|
||||
pending, err := svc.GetUserRoleSummary(ctx, 932)
|
||||
|
||||
@ -118,6 +118,8 @@ func (r *Repository) GetUserRoleSummary(ctx context.Context, userID int64) (host
|
||||
summary.IsHost = hostStatus == hostdomain.HostStatusActive
|
||||
if ownerAgencyID > 0 {
|
||||
summary.AgencyID = ownerAgencyID
|
||||
// 经理中心首版授权边界是 active Agency owner;普通 Agency 成员只展示 Agency 入口,不具备 manager 身份。
|
||||
summary.IsManager = true
|
||||
} else {
|
||||
summary.AgencyID = hostAgencyID
|
||||
}
|
||||
|
||||
@ -351,6 +351,7 @@ func toProtoUserRoleSummary(summary hostdomain.UserRoleSummary) *userv1.UserRole
|
||||
UserId: summary.UserID,
|
||||
IsHost: summary.IsHost,
|
||||
IsAgency: summary.IsAgency,
|
||||
IsManager: summary.IsManager,
|
||||
IsBd: summary.IsBD,
|
||||
IsBdLeader: summary.IsBDLeader,
|
||||
IsCoinSeller: summary.IsCoinSeller,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user