package grpc import ( "context" userv1 "hyapp.local/api/proto/user/v1" "hyapp/pkg/xerr" hostservice "hyapp/services/user-service/internal/service/host" ) // CreateBDLeader 处理 BD Leader/Admin 身份创建。 // 后台 admin 入口和经理中心入口复用同一个事实写入 RPC,具体入口权限在调用方进入该 RPC 前完成。 func (s *Server) CreateBDLeader(ctx context.Context, req *userv1.CreateBDLeaderRequest) (*userv1.CreateBDLeaderResponse, error) { if s.hostSvc == nil { return nil, xerr.ToGRPCError(xerr.New(xerr.Unavailable, "host service is not configured")) } ctx = contextWithApp(ctx, req.GetMeta()) profile, err := s.hostSvc.CreateBDLeader(ctx, hostservice.CreateBDLeaderInput{ CommandID: req.GetCommandId(), AdminUserID: req.GetAdminUserId(), TargetUserID: req.GetTargetUserId(), Reason: req.GetReason(), RequestID: requestIDFromMeta(req.GetMeta()), }) if err != nil { return nil, xerr.ToGRPCError(err) } return &userv1.CreateBDLeaderResponse{BdProfile: toProtoBDProfile(profile)}, nil } // CreateBD 处理后台创建普通 BD,并绑定有效 BD Leader。 func (s *Server) CreateBD(ctx context.Context, req *userv1.CreateBDRequest) (*userv1.CreateBDResponse, error) { if s.hostSvc == nil { return nil, xerr.ToGRPCError(xerr.New(xerr.Unavailable, "host service is not configured")) } ctx = contextWithApp(ctx, req.GetMeta()) profile, err := s.hostSvc.CreateBD(ctx, hostservice.CreateBDInput{ CommandID: req.GetCommandId(), AdminUserID: req.GetAdminUserId(), TargetUserID: req.GetTargetUserId(), ParentLeaderUserID: req.GetParentLeaderUserId(), Reason: req.GetReason(), RequestID: req.GetMeta().GetRequestId(), }) if err != nil { return nil, xerr.ToGRPCError(err) } return &userv1.CreateBDResponse{BdProfile: toProtoBDProfile(profile)}, nil } // SetBDStatus 处理后台停用或恢复 BD/BD Leader。 func (s *Server) SetBDStatus(ctx context.Context, req *userv1.SetBDStatusRequest) (*userv1.SetBDStatusResponse, error) { if s.hostSvc == nil { return nil, xerr.ToGRPCError(xerr.New(xerr.Unavailable, "host service is not configured")) } ctx = contextWithApp(ctx, req.GetMeta()) profile, err := s.hostSvc.SetBDStatus(ctx, hostservice.SetBDStatusInput{ CommandID: req.GetCommandId(), AdminUserID: req.GetAdminUserId(), TargetUserID: req.GetTargetUserId(), Role: req.GetRole(), Status: req.GetStatus(), Reason: req.GetReason(), RequestID: req.GetMeta().GetRequestId(), }) if err != nil { return nil, xerr.ToGRPCError(err) } return &userv1.SetBDStatusResponse{BdProfile: toProtoBDProfile(profile)}, nil } // CreateCoinSeller 处理后台创建币商身份;权限和操作审计在 admin-server。 func (s *Server) CreateCoinSeller(ctx context.Context, req *userv1.CreateCoinSellerRequest) (*userv1.CreateCoinSellerResponse, error) { if s.hostSvc == nil { return nil, xerr.ToGRPCError(xerr.New(xerr.Unavailable, "host service is not configured")) } ctx = contextWithApp(ctx, req.GetMeta()) profile, err := s.hostSvc.CreateCoinSeller(ctx, hostservice.CreateCoinSellerInput{ CommandID: req.GetCommandId(), AdminUserID: req.GetAdminUserId(), TargetUserID: req.GetTargetUserId(), Reason: req.GetReason(), RequestID: req.GetMeta().GetRequestId(), CanManageSubCoinSellers: req.CanManageSubCoinSellers, }) if err != nil { return nil, xerr.ToGRPCError(err) } return &userv1.CreateCoinSellerResponse{CoinSellerProfile: toProtoCoinSellerProfile(profile)}, nil } // SetCoinSellerStatus 处理后台启用或停用币商身份。 func (s *Server) SetCoinSellerStatus(ctx context.Context, req *userv1.SetCoinSellerStatusRequest) (*userv1.SetCoinSellerStatusResponse, error) { if s.hostSvc == nil { return nil, xerr.ToGRPCError(xerr.New(xerr.Unavailable, "host service is not configured")) } ctx = contextWithApp(ctx, req.GetMeta()) profile, err := s.hostSvc.SetCoinSellerStatus(ctx, hostservice.SetCoinSellerStatusInput{ CommandID: req.GetCommandId(), AdminUserID: req.GetAdminUserId(), TargetUserID: req.GetTargetUserId(), Status: req.GetStatus(), Reason: req.GetReason(), RequestID: req.GetMeta().GetRequestId(), CanManageSubCoinSellers: req.CanManageSubCoinSellers, }) if err != nil { return nil, xerr.ToGRPCError(err) } return &userv1.SetCoinSellerStatusResponse{CoinSellerProfile: toProtoCoinSellerProfile(profile)}, nil } // ReviewSubCoinSellerApplication 处理后台对子币商邀请申请的通过或拒绝。 func (s *Server) ReviewSubCoinSellerApplication(ctx context.Context, req *userv1.ReviewSubCoinSellerApplicationRequest) (*userv1.ReviewSubCoinSellerApplicationResponse, error) { if s.hostSvc == nil { return nil, xerr.ToGRPCError(xerr.New(xerr.Unavailable, "host service is not configured")) } ctx = contextWithApp(ctx, req.GetMeta()) result, err := s.hostSvc.ReviewSubCoinSellerApplication(ctx, hostservice.ReviewSubCoinSellerApplicationInput{ CommandID: req.GetCommandId(), AdminUserID: req.GetAdminUserId(), ApplicationID: req.GetApplicationId(), Decision: req.GetDecision(), Reason: req.GetReason(), RequestID: req.GetMeta().GetRequestId(), }) if err != nil { return nil, xerr.ToGRPCError(err) } return &userv1.ReviewSubCoinSellerApplicationResponse{ Application: toProtoCoinSellerSubApplication(result.Application), Relation: toProtoCoinSellerSubRelation(result.Relation), Child: toProtoCoinSellerListItem(result.Child), }, nil } // CreateAgency 处理后台直接创建 Agency,并返回 owner host/membership 事实。 func (s *Server) CreateAgency(ctx context.Context, req *userv1.CreateAgencyRequest) (*userv1.CreateAgencyResponse, error) { if s.hostSvc == nil { return nil, xerr.ToGRPCError(xerr.New(xerr.Unavailable, "host service is not configured")) } ctx = contextWithApp(ctx, req.GetMeta()) result, err := s.hostSvc.CreateAgency(ctx, hostservice.CreateAgencyInput{ CommandID: req.GetCommandId(), AdminUserID: req.GetAdminUserId(), OwnerUserID: req.GetOwnerUserId(), ParentBDUserID: req.GetParentBdUserId(), Name: req.GetName(), JoinEnabled: req.GetJoinEnabled(), Reason: req.GetReason(), RequestID: req.GetMeta().GetRequestId(), }) if err != nil { return nil, xerr.ToGRPCError(err) } return &userv1.CreateAgencyResponse{ Agency: toProtoAgency(result.Agency), HostProfile: toProtoHostProfile(result.HostProfile), Membership: toProtoAgencyMembership(result.Membership), }, nil } // AdminAddAgencyHost 处理后台直接把用户加入指定 Agency;admin 鉴权和审计仍在 admin-server。 func (s *Server) AdminAddAgencyHost(ctx context.Context, req *userv1.AdminAddAgencyHostRequest) (*userv1.AdminAddAgencyHostResponse, error) { if s.hostSvc == nil { return nil, xerr.ToGRPCError(xerr.New(xerr.Unavailable, "host service is not configured")) } ctx = contextWithApp(ctx, req.GetMeta()) result, err := s.hostSvc.AdminAddAgencyHost(ctx, hostservice.AdminAddAgencyHostInput{ CommandID: req.GetCommandId(), AdminUserID: req.GetAdminUserId(), AgencyID: req.GetAgencyId(), TargetUserID: req.GetTargetUserId(), Reason: req.GetReason(), RequestID: req.GetMeta().GetRequestId(), }) if err != nil { return nil, xerr.ToGRPCError(err) } return &userv1.AdminAddAgencyHostResponse{ Agency: toProtoAgency(result.Agency), HostProfile: toProtoHostProfile(result.HostProfile), Membership: toProtoAgencyMembership(result.Membership), }, nil } // CloseAgency 处理后台关闭 Agency;关闭后 App 搜索不会再返回该 Agency。 func (s *Server) CloseAgency(ctx context.Context, req *userv1.CloseAgencyRequest) (*userv1.CloseAgencyResponse, error) { if s.hostSvc == nil { return nil, xerr.ToGRPCError(xerr.New(xerr.Unavailable, "host service is not configured")) } ctx = contextWithApp(ctx, req.GetMeta()) agency, err := s.hostSvc.CloseAgency(ctx, hostservice.CloseAgencyInput{ CommandID: req.GetCommandId(), AdminUserID: req.GetAdminUserId(), AgencyID: req.GetAgencyId(), Reason: req.GetReason(), RequestID: req.GetMeta().GetRequestId(), }) if err != nil { return nil, xerr.ToGRPCError(err) } return &userv1.CloseAgencyResponse{Agency: toProtoAgency(agency)}, nil } // DeleteAgency 处理后台删除 Agency 身份;主播身份不删除,只解除当前 Agency 归属。 func (s *Server) DeleteAgency(ctx context.Context, req *userv1.DeleteAgencyRequest) (*userv1.DeleteAgencyResponse, error) { if s.hostSvc == nil { return nil, xerr.ToGRPCError(xerr.New(xerr.Unavailable, "host service is not configured")) } ctx = contextWithApp(ctx, req.GetMeta()) agency, err := s.hostSvc.DeleteAgency(ctx, hostservice.DeleteAgencyInput{ CommandID: req.GetCommandId(), AdminUserID: req.GetAdminUserId(), AgencyID: req.GetAgencyId(), Reason: req.GetReason(), RequestID: req.GetMeta().GetRequestId(), }) if err != nil { return nil, xerr.ToGRPCError(err) } return &userv1.DeleteAgencyResponse{Agency: toProtoAgency(agency)}, nil } // SetAgencyStatus 处理后台显式切换 Agency 状态;恢复 closed 不自动开放 join_enabled。 func (s *Server) SetAgencyStatus(ctx context.Context, req *userv1.SetAgencyStatusRequest) (*userv1.SetAgencyStatusResponse, error) { if s.hostSvc == nil { return nil, xerr.ToGRPCError(xerr.New(xerr.Unavailable, "host service is not configured")) } ctx = contextWithApp(ctx, req.GetMeta()) agency, err := s.hostSvc.SetAgencyStatus(ctx, hostservice.SetAgencyStatusInput{ CommandID: req.GetCommandId(), AdminUserID: req.GetAdminUserId(), AgencyID: req.GetAgencyId(), Status: req.GetStatus(), Reason: req.GetReason(), RequestID: req.GetMeta().GetRequestId(), }) if err != nil { return nil, xerr.ToGRPCError(err) } return &userv1.SetAgencyStatusResponse{Agency: toProtoAgency(agency)}, nil } // SetAgencyJoinEnabled 处理后台设置 Agency 入会开关。 func (s *Server) SetAgencyJoinEnabled(ctx context.Context, req *userv1.SetAgencyJoinEnabledRequest) (*userv1.SetAgencyJoinEnabledResponse, error) { if s.hostSvc == nil { return nil, xerr.ToGRPCError(xerr.New(xerr.Unavailable, "host service is not configured")) } ctx = contextWithApp(ctx, req.GetMeta()) agency, err := s.hostSvc.SetAgencyJoinEnabled(ctx, hostservice.SetAgencyJoinEnabledInput{ CommandID: req.GetCommandId(), AdminUserID: req.GetAdminUserId(), AgencyID: req.GetAgencyId(), JoinEnabled: req.GetJoinEnabled(), Reason: req.GetReason(), RequestID: req.GetMeta().GetRequestId(), }) if err != nil { return nil, xerr.ToGRPCError(err) } return &userv1.SetAgencyJoinEnabledResponse{Agency: toProtoAgency(agency)}, nil }