2026-06-08 19:00:23 +08:00

186 lines
7.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package grpc
import (
"context"
userv1 "hyapp.local/api/proto/user/v1"
"hyapp/pkg/xerr"
cpdomain "hyapp/services/user-service/internal/domain/cp"
)
// ListCPApplications 返回当前用户收到或发出的 CP/兄弟/姐妹申请。
func (s *Server) ListCPApplications(ctx context.Context, req *userv1.ListCPApplicationsRequest) (*userv1.ListCPApplicationsResponse, error) {
ctx = contextWithApp(ctx, req.GetMeta())
if s.cpSvc == nil {
return nil, xerr.ToGRPCError(xerr.New(xerr.Unavailable, "cp service is not configured"))
}
// gRPC 层只透传分页、方向和状态pending 过期固化由 service/repository 统一处理。
applications, total, serverTimeMS, err := s.cpSvc.ListApplications(ctx, req.GetUserId(), req.GetDirection(), req.GetStatus(), req.GetPage(), req.GetPageSize())
if err != nil {
return nil, xerr.ToGRPCError(err)
}
resp := &userv1.ListCPApplicationsResponse{
Applications: make([]*userv1.CPApplication, 0, len(applications)),
Total: total,
ServerTimeMs: serverTimeMS,
}
for _, application := range applications {
resp.Applications = append(resp.Applications, toProtoCPApplication(application))
}
return resp, nil
}
// AcceptCPApplication 同意申请并返回建立后的关系。
func (s *Server) AcceptCPApplication(ctx context.Context, req *userv1.AcceptCPApplicationRequest) (*userv1.AcceptCPApplicationResponse, error) {
ctx = contextWithApp(ctx, req.GetMeta())
if s.cpSvc == nil {
return nil, xerr.ToGRPCError(xerr.New(xerr.Unavailable, "cp service is not configured"))
}
application, relationship, err := s.cpSvc.AcceptApplication(ctx, req.GetUserId(), req.GetApplicationId())
if err != nil {
return nil, xerr.ToGRPCError(err)
}
return &userv1.AcceptCPApplicationResponse{
Application: toProtoCPApplication(application),
Relationship: toProtoCPRelationship(relationship),
}, nil
}
// RejectCPApplication 拒绝申请;拒绝原因只进入 outbox payload不改变关系主事实。
func (s *Server) RejectCPApplication(ctx context.Context, req *userv1.RejectCPApplicationRequest) (*userv1.RejectCPApplicationResponse, error) {
ctx = contextWithApp(ctx, req.GetMeta())
if s.cpSvc == nil {
return nil, xerr.ToGRPCError(xerr.New(xerr.Unavailable, "cp service is not configured"))
}
application, err := s.cpSvc.RejectApplication(ctx, req.GetUserId(), req.GetApplicationId(), req.GetReason())
if err != nil {
return nil, xerr.ToGRPCError(err)
}
return &userv1.RejectCPApplicationResponse{Application: toProtoCPApplication(application)}, nil
}
// ListCPRelationships 返回用户 active 关系;当前每个用户最多同时拥有一条关系。
func (s *Server) ListCPRelationships(ctx context.Context, req *userv1.ListCPRelationshipsRequest) (*userv1.ListCPRelationshipsResponse, error) {
ctx = contextWithApp(ctx, req.GetMeta())
if s.cpSvc == nil {
return nil, xerr.ToGRPCError(xerr.New(xerr.Unavailable, "cp service is not configured"))
}
relationships, total, err := s.cpSvc.ListRelationships(ctx, req.GetUserId(), req.GetRelationType(), req.GetPage(), req.GetPageSize())
if err != nil {
return nil, xerr.ToGRPCError(err)
}
resp := &userv1.ListCPRelationshipsResponse{
Relationships: make([]*userv1.CPRelationship, 0, len(relationships)),
Total: total,
}
for _, relationship := range relationships {
resp.Relationships = append(resp.Relationships, toProtoCPRelationship(relationship))
}
return resp, nil
}
// ConsumeRoomGiftCPEvent 由 user-service 内部 MQ worker 调用,把 RoomGiftSent 转为 CP 申请或亲密值增长。
func (s *Server) ConsumeRoomGiftCPEvent(ctx context.Context, req *userv1.ConsumeRoomGiftCPEventRequest) (*userv1.ConsumeRoomGiftCPEventResponse, error) {
ctx = contextWithApp(ctx, req.GetMeta())
if s.cpSvc == nil {
return nil, xerr.ToGRPCError(xerr.New(xerr.Unavailable, "cp service is not configured"))
}
event := req.GetEvent()
result, err := s.cpSvc.ConsumeGiftEvent(ctx, cpdomain.GiftEvent{
EventID: event.GetEventId(),
RoomID: event.GetRoomId(),
RoomVersion: event.GetRoomVersion(),
OccurredAtMS: event.GetOccurredAtMs(),
SenderUserID: event.GetSenderUserId(),
TargetUserID: event.GetTargetUserId(),
GiftID: event.GetGiftId(),
GiftCount: event.GetGiftCount(),
GiftValue: event.GetGiftValue(),
BillingReceiptID: event.GetBillingReceiptId(),
VisibleRegionID: event.GetVisibleRegionId(),
CommandID: event.GetCommandId(),
GiftTypeCode: event.GetGiftTypeCode(),
CPRelationType: event.GetCpRelationType(),
GiftName: event.GetGiftName(),
GiftIconURL: event.GetGiftIconUrl(),
GiftAnimationURL: event.GetGiftAnimationUrl(),
})
if err != nil {
return nil, xerr.ToGRPCError(err)
}
return &userv1.ConsumeRoomGiftCPEventResponse{
Consumed: result.Consumed,
Application: toProtoCPApplication(result.Application),
Relationship: toProtoCPRelationship(result.Relationship),
}, nil
}
func toProtoCPApplication(application cpdomain.Application) *userv1.CPApplication {
if application.ApplicationID == "" {
return nil
}
return &userv1.CPApplication{
ApplicationId: application.ApplicationID,
RelationType: application.RelationType,
Status: application.Status,
Requester: toProtoCPUserProfile(application.Requester),
Target: toProtoCPUserProfile(application.Target),
RoomId: application.RoomID,
RoomRegionId: application.RoomRegionID,
Gift: toProtoCPGiftSnapshot(application.Gift),
CreatedAtMs: application.CreatedAtMS,
UpdatedAtMs: application.UpdatedAtMS,
ExpiresAtMs: application.ExpiresAtMS,
DecidedAtMs: application.DecidedAtMS,
}
}
func toProtoCPRelationship(relationship cpdomain.Relationship) *userv1.CPRelationship {
if relationship.RelationshipID == "" {
return nil
}
return &userv1.CPRelationship{
RelationshipId: relationship.RelationshipID,
RelationType: relationship.RelationType,
Status: relationship.Status,
Me: toProtoCPUserProfile(relationship.Me),
Partner: toProtoCPUserProfile(relationship.Partner),
IntimacyValue: relationship.IntimacyValue,
Level: relationship.Level,
FormedAtMs: relationship.FormedAtMS,
UpdatedAtMs: relationship.UpdatedAtMS,
CurrentLevelThreshold: relationship.CurrentLevelThreshold,
NextLevelThreshold: relationship.NextLevelThreshold,
NeededForNextLevel: relationship.NeededForNextLevel,
LevelProgressPercent: relationship.LevelProgressPercent,
MaxLevel: relationship.MaxLevel,
}
}
func toProtoCPUserProfile(profile cpdomain.UserProfile) *userv1.CPUserProfile {
if profile.UserID <= 0 {
return nil
}
return &userv1.CPUserProfile{
UserId: profile.UserID,
DisplayUserId: profile.DisplayUserID,
Username: profile.Username,
Avatar: profile.Avatar,
}
}
func toProtoCPGiftSnapshot(gift cpdomain.GiftSnapshot) *userv1.CPGiftSnapshot {
if gift.GiftID == "" && gift.GiftName == "" {
return nil
}
return &userv1.CPGiftSnapshot{
GiftId: gift.GiftID,
GiftName: gift.GiftName,
GiftIconUrl: gift.GiftIconURL,
GiftAnimationUrl: gift.GiftAnimationURL,
GiftCount: gift.GiftCount,
GiftValue: gift.GiftValue,
BillingReceiptId: gift.BillingReceiptID,
}
}