854 lines
22 KiB
Go
854 lines
22 KiB
Go
package provider
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
|
||
"dubbo.apache.org/dubbo-go/v3/common/constant"
|
||
appErrors "github.com/topfans/backend/pkg/errors"
|
||
"github.com/topfans/backend/pkg/logger"
|
||
pbCommon "github.com/topfans/backend/pkg/proto/common"
|
||
pb "github.com/topfans/backend/pkg/proto/user"
|
||
"github.com/topfans/backend/services/userService/service"
|
||
"go.uber.org/zap"
|
||
)
|
||
|
||
// UserProvider 用户信息Provider实现
|
||
type UserProvider struct {
|
||
userService service.UserService
|
||
identityService service.IdentityService
|
||
}
|
||
|
||
// NewUserProvider 创建用户信息Provider实例
|
||
func NewUserProvider(userService service.UserService, identityService service.IdentityService) *UserProvider {
|
||
return &UserProvider{
|
||
userService: userService,
|
||
identityService: identityService,
|
||
}
|
||
}
|
||
|
||
// GetUser 获取用户信息
|
||
func (p *UserProvider) GetUser(ctx context.Context, req *pb.GetUserRequest) (*pb.GetUserResponse, error) {
|
||
// 记录请求日志
|
||
logger.Logger.Info("Received GetUser request",
|
||
zap.Int64("user_id", req.UserId),
|
||
)
|
||
|
||
// 调用Service层
|
||
resp, err := p.userService.GetUser(req)
|
||
if err != nil {
|
||
logger.Logger.Error("GetUser failed",
|
||
zap.Int64("user_id", req.UserId),
|
||
zap.Error(err),
|
||
)
|
||
|
||
// 如果响应为空,构建错误响应
|
||
if resp == nil {
|
||
resp = &pb.GetUserResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: appErrors.ToStatusCode(err),
|
||
Message: err.Error(),
|
||
Timestamp: 0,
|
||
},
|
||
}
|
||
}
|
||
|
||
return resp, err
|
||
}
|
||
|
||
logger.Logger.Debug("GetUser successful",
|
||
zap.Int64("user_id", req.UserId),
|
||
)
|
||
|
||
return resp, nil
|
||
}
|
||
|
||
// GetFanProfile 获取粉丝档案
|
||
func (p *UserProvider) GetFanProfile(ctx context.Context, req *pb.GetFanProfileRequest) (*pb.GetFanProfileResponse, error) {
|
||
// 记录请求日志
|
||
logger.Logger.Info("Received GetFanProfile request",
|
||
zap.Int64("user_id", req.UserId),
|
||
zap.Int64("star_id", req.StarId),
|
||
)
|
||
|
||
// 调用Service层
|
||
resp, err := p.userService.GetFanProfile(req)
|
||
if err != nil {
|
||
logger.Logger.Error("GetFanProfile failed",
|
||
zap.Int64("user_id", req.UserId),
|
||
zap.Int64("star_id", req.StarId),
|
||
zap.Error(err),
|
||
)
|
||
|
||
// 如果响应为空,构建错误响应
|
||
if resp == nil {
|
||
resp = &pb.GetFanProfileResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: appErrors.ToStatusCode(err),
|
||
Message: err.Error(),
|
||
Timestamp: 0,
|
||
},
|
||
}
|
||
}
|
||
|
||
return resp, err
|
||
}
|
||
|
||
logger.Logger.Debug("GetFanProfile successful",
|
||
zap.Int64("user_id", req.UserId),
|
||
zap.Int64("star_id", req.StarId),
|
||
)
|
||
|
||
return resp, nil
|
||
}
|
||
|
||
// GetCurrentUser 获取当前登录用户信息
|
||
// 假设:Gin 网关已经验证 Token,并通过 Dubbo attachments 传递 user_id 和 star_id
|
||
func (p *UserProvider) GetCurrentUser(ctx context.Context, req *pb.GetCurrentUserRequest) (*pb.GetCurrentUserResponse, error) {
|
||
// 记录请求日志
|
||
logger.Logger.Info("Received GetCurrentUser request")
|
||
|
||
// 从 Dubbo attachments 获取用户信息(网关已验证并传递)
|
||
userID, starID, err := extractUserInfoFromDubboAttachments(ctx)
|
||
if err != nil {
|
||
logger.Logger.Error("Failed to extract user info from attachments",
|
||
zap.Error(err),
|
||
)
|
||
return &pb.GetCurrentUserResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: pbCommon.StatusCode_STATUS_UNAUTHORIZED,
|
||
Message: "user authentication required",
|
||
Timestamp: 0,
|
||
},
|
||
}, err
|
||
}
|
||
|
||
logger.Logger.Debug("User info extracted from Dubbo attachments",
|
||
zap.Int64("user_id", userID),
|
||
zap.Int64("star_id", starID),
|
||
)
|
||
|
||
// 调用Service层的GetMyProfile(使用GetMyProfileRequest)
|
||
myProfileReq := &pb.GetMyProfileRequest{}
|
||
resp, err := p.userService.GetMyProfile(myProfileReq, userID, starID)
|
||
if err != nil {
|
||
logger.Logger.Error("GetCurrentUser failed",
|
||
zap.Int64("user_id", userID),
|
||
zap.Error(err),
|
||
)
|
||
|
||
return &pb.GetCurrentUserResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: appErrors.ToStatusCode(err),
|
||
Message: err.Error(),
|
||
Timestamp: 0,
|
||
},
|
||
}, err
|
||
}
|
||
|
||
// 转换为GetCurrentUserResponse格式
|
||
currentUserResp := &pb.GetCurrentUserResponse{
|
||
Base: resp.Base,
|
||
User: resp.User,
|
||
FanProfile: resp.FanProfile,
|
||
FanProfiles: resp.FanProfiles,
|
||
}
|
||
|
||
logger.Logger.Debug("GetCurrentUser successful",
|
||
zap.Int64("user_id", userID),
|
||
)
|
||
|
||
return currentUserResp, nil
|
||
}
|
||
|
||
// GetMyProfile 获取个人信息页
|
||
func (p *UserProvider) GetMyProfile(ctx context.Context, req *pb.GetMyProfileRequest) (*pb.GetMyProfileResponse, error) {
|
||
// 记录请求日志
|
||
logger.Logger.Info("Received GetMyProfile request")
|
||
|
||
// 从 Dubbo attachments 获取用户信息(网关已验证并传递)
|
||
userID, starID, err := extractUserInfoFromDubboAttachments(ctx)
|
||
if err != nil {
|
||
logger.Logger.Error("Failed to extract user info from attachments",
|
||
zap.Error(err),
|
||
)
|
||
return &pb.GetMyProfileResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: pbCommon.StatusCode_STATUS_UNAUTHORIZED,
|
||
Message: "user authentication required",
|
||
Timestamp: 0,
|
||
},
|
||
}, err
|
||
}
|
||
|
||
// 调用Service层
|
||
resp, err := p.userService.GetMyProfile(req, userID, starID)
|
||
if err != nil {
|
||
logger.Logger.Error("GetMyProfile failed",
|
||
zap.Int64("user_id", userID),
|
||
zap.Int64("star_id", starID),
|
||
zap.Error(err),
|
||
)
|
||
|
||
// 如果响应为空,构建错误响应
|
||
if resp == nil {
|
||
resp = &pb.GetMyProfileResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: appErrors.ToStatusCode(err),
|
||
Message: err.Error(),
|
||
Timestamp: 0,
|
||
},
|
||
}
|
||
}
|
||
|
||
return resp, err
|
||
}
|
||
|
||
logger.Logger.Debug("GetMyProfile successful",
|
||
zap.Int64("user_id", userID),
|
||
zap.Int64("star_id", starID),
|
||
)
|
||
|
||
return resp, nil
|
||
}
|
||
|
||
// CheckNickname 检查昵称是否已被注册
|
||
func (p *UserProvider) CheckNickname(ctx context.Context, req *pb.CheckNicknameRequest) (*pb.CheckNicknameResponse, error) {
|
||
// 记录请求日志
|
||
logger.Logger.Info("Received CheckNickname request",
|
||
zap.String("nickname", req.Nickname),
|
||
)
|
||
|
||
// 调用Service层
|
||
resp, err := p.userService.CheckNickname(req)
|
||
if err != nil {
|
||
logger.Logger.Error("CheckNickname failed",
|
||
zap.String("nickname", req.Nickname),
|
||
zap.Error(err),
|
||
)
|
||
|
||
// 如果响应为空,构建错误响应
|
||
if resp == nil {
|
||
resp = &pb.CheckNicknameResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: appErrors.ToStatusCode(err),
|
||
Message: err.Error(),
|
||
Timestamp: 0,
|
||
},
|
||
}
|
||
}
|
||
|
||
return resp, err
|
||
}
|
||
|
||
logger.Logger.Info("CheckNickname successful",
|
||
zap.String("nickname", req.Nickname),
|
||
zap.Bool("exists", resp.Exists),
|
||
)
|
||
|
||
return resp, nil
|
||
}
|
||
|
||
// CheckMobile 检查手机号是否已被注册
|
||
func (p *UserProvider) CheckMobile(ctx context.Context, req *pb.CheckMobileRequest) (*pb.CheckMobileResponse, error) {
|
||
// 记录请求日志
|
||
logger.Logger.Info("Received CheckMobile request",
|
||
zap.String("mobile", req.Mobile),
|
||
)
|
||
|
||
// 调用Service层
|
||
resp, err := p.userService.CheckMobile(req)
|
||
if err != nil {
|
||
logger.Logger.Error("CheckMobile failed",
|
||
zap.String("mobile", req.Mobile),
|
||
zap.Error(err),
|
||
)
|
||
|
||
// 如果响应为空,构建错误响应
|
||
if resp == nil {
|
||
resp = &pb.CheckMobileResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: appErrors.ToStatusCode(err),
|
||
Message: err.Error(),
|
||
Timestamp: 0,
|
||
},
|
||
}
|
||
}
|
||
|
||
return resp, err
|
||
}
|
||
|
||
logger.Logger.Info("CheckMobile successful",
|
||
zap.String("mobile", req.Mobile),
|
||
zap.Bool("exists", resp.Exists),
|
||
)
|
||
|
||
return resp, nil
|
||
}
|
||
|
||
// UpdateNickname 修改昵称
|
||
func (p *UserProvider) UpdateNickname(ctx context.Context, req *pb.UpdateNicknameRequest) (*pb.UpdateNicknameResponse, error) {
|
||
// 记录请求日志
|
||
logger.Logger.Info("Received UpdateNickname request")
|
||
|
||
// 从 Dubbo attachments 获取用户信息(网关已验证并传递)
|
||
userID, starID, err := extractUserInfoFromDubboAttachments(ctx)
|
||
if err != nil {
|
||
logger.Logger.Error("Failed to extract user info from attachments",
|
||
zap.Error(err),
|
||
)
|
||
return &pb.UpdateNicknameResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: pbCommon.StatusCode_STATUS_UNAUTHORIZED,
|
||
Message: "user authentication required",
|
||
Timestamp: 0,
|
||
},
|
||
}, err
|
||
}
|
||
|
||
// 调用Service层
|
||
resp, err := p.userService.UpdateNickname(req, userID, starID)
|
||
if err != nil {
|
||
logger.Logger.Error("UpdateNickname failed",
|
||
zap.Int64("user_id", userID),
|
||
zap.Int64("star_id", starID),
|
||
zap.Error(err),
|
||
)
|
||
|
||
// 如果响应为空,构建错误响应
|
||
if resp == nil {
|
||
resp = &pb.UpdateNicknameResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: appErrors.ToStatusCode(err),
|
||
Message: err.Error(),
|
||
Timestamp: 0,
|
||
},
|
||
}
|
||
}
|
||
|
||
return resp, err
|
||
}
|
||
|
||
logger.Logger.Info("UpdateNickname successful",
|
||
zap.Int64("user_id", userID),
|
||
zap.Int64("star_id", starID),
|
||
zap.String("new_nickname", req.Nickname),
|
||
)
|
||
|
||
return resp, nil
|
||
}
|
||
|
||
// UpdatePassword 修改密码
|
||
func (p *UserProvider) UpdatePassword(ctx context.Context, req *pb.UpdatePasswordRequest) (*pb.UpdatePasswordResponse, error) {
|
||
// 记录请求日志
|
||
logger.Logger.Info("Received UpdatePassword request")
|
||
|
||
// 从 Dubbo attachments 获取用户信息(网关已验证并传递)
|
||
userID, _, err := extractUserInfoFromDubboAttachments(ctx)
|
||
if err != nil {
|
||
logger.Logger.Error("Failed to extract user info from attachments",
|
||
zap.Error(err),
|
||
)
|
||
return &pb.UpdatePasswordResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: pbCommon.StatusCode_STATUS_UNAUTHORIZED,
|
||
Message: "user authentication required",
|
||
Timestamp: 0,
|
||
},
|
||
}, err
|
||
}
|
||
|
||
// 调用Service层
|
||
resp, err := p.userService.UpdatePassword(req, userID)
|
||
if err != nil {
|
||
logger.Logger.Error("UpdatePassword failed",
|
||
zap.Int64("user_id", userID),
|
||
zap.Error(err),
|
||
)
|
||
|
||
// 如果响应为空,构建错误响应
|
||
if resp == nil {
|
||
resp = &pb.UpdatePasswordResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: appErrors.ToStatusCode(err),
|
||
Message: err.Error(),
|
||
Timestamp: 0,
|
||
},
|
||
}
|
||
}
|
||
|
||
return resp, err
|
||
}
|
||
|
||
logger.Logger.Info("UpdatePassword successful",
|
||
zap.Int64("user_id", userID),
|
||
)
|
||
|
||
return resp, nil
|
||
}
|
||
|
||
// UpdateAvatar 更新用户头像
|
||
func (p *UserProvider) UpdateAvatar(ctx context.Context, req *pb.UpdateAvatarRequest) (*pb.UpdateAvatarResponse, error) {
|
||
// 记录请求日志
|
||
logger.Logger.Info("Received UpdateAvatar request")
|
||
|
||
// 从 Dubbo attachments 获取用户信息(网关已验证并传递)
|
||
userID, starID, err := extractUserInfoFromDubboAttachments(ctx)
|
||
if err != nil {
|
||
logger.Logger.Error("Failed to extract user info from attachments",
|
||
zap.Error(err),
|
||
)
|
||
return &pb.UpdateAvatarResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: pbCommon.StatusCode_STATUS_UNAUTHORIZED,
|
||
Message: "user authentication required",
|
||
Timestamp: 0,
|
||
},
|
||
}, err
|
||
}
|
||
|
||
// 调用Service层
|
||
resp, err := p.userService.UpdateAvatar(req, userID, starID)
|
||
if err != nil {
|
||
logger.Logger.Error("UpdateAvatar failed",
|
||
zap.Int64("user_id", userID),
|
||
zap.Error(err),
|
||
)
|
||
|
||
// 如果响应为空,构建错误响应
|
||
if resp == nil {
|
||
resp = &pb.UpdateAvatarResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: appErrors.ToStatusCode(err),
|
||
Message: err.Error(),
|
||
Timestamp: 0,
|
||
},
|
||
}
|
||
}
|
||
|
||
return resp, err
|
||
}
|
||
|
||
logger.Logger.Info("UpdateAvatar successful",
|
||
zap.Int64("user_id", userID),
|
||
zap.String("avatar_url", req.AvatarUrl),
|
||
)
|
||
|
||
return resp, nil
|
||
}
|
||
|
||
// GetFanIdentities 获取可选粉丝身份列表
|
||
func (p *UserProvider) GetFanIdentities(ctx context.Context, req *pb.GetFanIdentitiesRequest) (*pb.GetFanIdentitiesResponse, error) {
|
||
// 记录请求日志
|
||
logger.Logger.Info("Received GetFanIdentities request",
|
||
zap.String("keyword", req.Keyword),
|
||
)
|
||
|
||
// 调用Service层
|
||
resp, err := p.identityService.GetFanIdentities(req)
|
||
if err != nil {
|
||
logger.Logger.Error("GetFanIdentities failed",
|
||
zap.String("keyword", req.Keyword),
|
||
zap.Error(err),
|
||
)
|
||
|
||
// 如果响应为空,构建错误响应
|
||
if resp == nil {
|
||
resp = &pb.GetFanIdentitiesResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: appErrors.ToStatusCode(err),
|
||
Message: err.Error(),
|
||
Timestamp: 0,
|
||
},
|
||
}
|
||
}
|
||
|
||
return resp, err
|
||
}
|
||
|
||
logger.Logger.Debug("GetFanIdentities successful",
|
||
zap.String("keyword", req.Keyword),
|
||
zap.Int("count", len(resp.Stars)),
|
||
)
|
||
|
||
return resp, nil
|
||
}
|
||
|
||
// GetMyFanIdentities 获取我的粉丝身份列表
|
||
func (p *UserProvider) GetMyFanIdentities(ctx context.Context, req *pb.GetMyFanIdentitiesRequest) (*pb.GetMyFanIdentitiesResponse, error) {
|
||
// 从 Dubbo attachments 获取用户信息(网关已验证并传递)
|
||
userID, starID, err := extractUserInfoFromDubboAttachments(ctx)
|
||
if err != nil {
|
||
logger.Logger.Error("Failed to extract user info from attachments",
|
||
zap.Error(err),
|
||
)
|
||
return &pb.GetMyFanIdentitiesResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: pbCommon.StatusCode_STATUS_UNAUTHORIZED,
|
||
Message: "user authentication required",
|
||
Timestamp: 0,
|
||
},
|
||
}, err
|
||
}
|
||
|
||
// 记录请求日志
|
||
logger.Logger.Info("Received GetMyFanIdentities request",
|
||
zap.Int64("user_id", userID),
|
||
zap.Int64("star_id", starID),
|
||
)
|
||
|
||
// 调用Service层
|
||
resp, err := p.identityService.GetMyFanIdentities(userID, starID)
|
||
if err != nil {
|
||
logger.Logger.Error("GetMyFanIdentities failed",
|
||
zap.Int64("user_id", userID),
|
||
zap.Int64("star_id", starID),
|
||
zap.Error(err),
|
||
)
|
||
|
||
// 如果响应为空,构建错误响应
|
||
if resp == nil {
|
||
resp = &pb.GetMyFanIdentitiesResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: appErrors.ToStatusCode(err),
|
||
Message: err.Error(),
|
||
Timestamp: 0,
|
||
},
|
||
}
|
||
}
|
||
|
||
return resp, err
|
||
}
|
||
|
||
logger.Logger.Debug("GetMyFanIdentities successful",
|
||
zap.Int64("user_id", userID),
|
||
zap.Int64("star_id", starID),
|
||
zap.Int("count", len(resp.Items)),
|
||
)
|
||
|
||
return resp, nil
|
||
}
|
||
|
||
// AddIdentity 新增粉丝身份
|
||
func (p *UserProvider) AddIdentity(ctx context.Context, req *pb.AddIdentityRequest) (*pb.AddIdentityResponse, error) {
|
||
// 记录请求日志
|
||
logger.Logger.Info("Received AddIdentity request",
|
||
zap.Int64("star_id", req.StarId),
|
||
zap.String("nickname", req.Nickname),
|
||
)
|
||
|
||
// 从 Dubbo attachments 获取用户信息(网关已验证并传递)
|
||
userID, _, err := extractUserInfoFromDubboAttachments(ctx)
|
||
if err != nil {
|
||
logger.Logger.Error("Failed to extract user info from attachments",
|
||
zap.Error(err),
|
||
)
|
||
return &pb.AddIdentityResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: pbCommon.StatusCode_STATUS_UNAUTHORIZED,
|
||
Message: "user authentication required",
|
||
Timestamp: 0,
|
||
},
|
||
}, err
|
||
}
|
||
|
||
// 调用Service层
|
||
resp, err := p.identityService.AddIdentity(req, userID)
|
||
if err != nil {
|
||
logger.Logger.Error("AddIdentity failed",
|
||
zap.Int64("user_id", userID),
|
||
zap.Int64("star_id", req.StarId),
|
||
zap.Error(err),
|
||
)
|
||
|
||
// 如果响应为空,构建错误响应
|
||
if resp == nil {
|
||
resp = &pb.AddIdentityResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: appErrors.ToStatusCode(err),
|
||
Message: err.Error(),
|
||
Timestamp: 0,
|
||
},
|
||
}
|
||
}
|
||
|
||
return resp, err
|
||
}
|
||
|
||
logger.Logger.Info("AddIdentity successful",
|
||
zap.Int64("user_id", userID),
|
||
zap.Int64("star_id", req.StarId),
|
||
)
|
||
|
||
return resp, nil
|
||
}
|
||
|
||
// SwitchIdentity 切换粉丝身份
|
||
func (p *UserProvider) SwitchIdentity(ctx context.Context, req *pb.SwitchIdentityRequest) (*pb.SwitchIdentityResponse, error) {
|
||
// 记录请求日志
|
||
logger.Logger.Info("Received SwitchIdentity request",
|
||
zap.Int64("new_star_id", req.NewStarId),
|
||
)
|
||
|
||
// 从 Dubbo attachments 获取用户信息(网关已验证并传递)
|
||
userID, currentStarID, err := extractUserInfoFromDubboAttachments(ctx)
|
||
if err != nil {
|
||
logger.Logger.Error("Failed to extract user info from attachments",
|
||
zap.Error(err),
|
||
)
|
||
return &pb.SwitchIdentityResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: pbCommon.StatusCode_STATUS_UNAUTHORIZED,
|
||
Message: "user authentication required",
|
||
Timestamp: 0,
|
||
},
|
||
}, err
|
||
}
|
||
|
||
// 调用Service层
|
||
resp, err := p.identityService.SwitchIdentity(req, userID, currentStarID)
|
||
if err != nil {
|
||
logger.Logger.Error("SwitchIdentity failed",
|
||
zap.Int64("user_id", userID),
|
||
zap.Int64("current_star_id", currentStarID),
|
||
zap.Int64("new_star_id", req.NewStarId),
|
||
zap.Error(err),
|
||
)
|
||
|
||
// 如果响应为空,构建错误响应
|
||
if resp == nil {
|
||
resp = &pb.SwitchIdentityResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: appErrors.ToStatusCode(err),
|
||
Message: err.Error(),
|
||
Timestamp: 0,
|
||
},
|
||
}
|
||
}
|
||
|
||
return resp, err
|
||
}
|
||
|
||
logger.Logger.Info("SwitchIdentity successful",
|
||
zap.Int64("user_id", userID),
|
||
zap.Int64("current_star_id", currentStarID),
|
||
zap.Int64("new_star_id", req.NewStarId),
|
||
)
|
||
|
||
return resp, nil
|
||
}
|
||
|
||
// extractUserInfoFromDubboAttachments 从 Dubbo attachments 中提取用户信息
|
||
// 网关调用:网关已验证 Token 并将 user_id 和 star_id 通过 attachments 传递
|
||
// 直接调用:可以通过 grpcurl -rpc-header 传递 user_id 和 star_id 进行测试
|
||
func extractUserInfoFromDubboAttachments(ctx context.Context) (int64, int64, error) {
|
||
logger.Logger.Info("Extracting user info from Dubbo attachments")
|
||
|
||
// 使用正确的 constant.AttachmentKey 获取 Dubbo attachments
|
||
if attachments := ctx.Value(constant.AttachmentKey); attachments != nil {
|
||
logger.Logger.Info("Found attachments in context",
|
||
zap.Any("attachments", attachments),
|
||
zap.String("key", fmt.Sprintf("%v", constant.AttachmentKey)),
|
||
)
|
||
|
||
if attMap, ok := attachments.(map[string]interface{}); ok {
|
||
logger.Logger.Info("Attachments is a map", zap.Any("map", attMap))
|
||
userID, starID := extractUserInfoFromMap(attMap)
|
||
if userID > 0 && starID > 0 {
|
||
logger.Logger.Info("Successfully extracted user info",
|
||
zap.Int64("user_id", userID),
|
||
zap.Int64("star_id", starID),
|
||
)
|
||
return userID, starID, nil
|
||
} else {
|
||
logger.Logger.Warn("Extracted zero user_id or star_id",
|
||
zap.Int64("user_id", userID),
|
||
zap.Int64("star_id", starID),
|
||
)
|
||
}
|
||
} else {
|
||
logger.Logger.Warn("Attachments is not a map[string]interface{}",
|
||
zap.String("type", fmt.Sprintf("%T", attachments)),
|
||
)
|
||
}
|
||
} else {
|
||
logger.Logger.Warn("No attachments found in context",
|
||
zap.String("key", fmt.Sprintf("%v", constant.AttachmentKey)),
|
||
)
|
||
}
|
||
|
||
logger.Logger.Error("Failed to extract user info from Dubbo attachments")
|
||
return 0, 0, fmt.Errorf("user info not found in Dubbo attachments (expected user_id and star_id from gateway)")
|
||
}
|
||
|
||
// extractUserInfoFromMap 从 map 中提取 user_id 和 star_id
|
||
// 支持多种类型:int64, float64, string, []string, []interface{}
|
||
func extractUserInfoFromMap(attMap map[string]interface{}) (int64, int64) {
|
||
var userID, starID int64
|
||
|
||
// 提取 user_id
|
||
if v, ok := attMap["user_id"]; ok {
|
||
userID = parseIntValue(v)
|
||
}
|
||
|
||
// 提取 star_id
|
||
if v, ok := attMap["star_id"]; ok {
|
||
starID = parseIntValue(v)
|
||
}
|
||
|
||
return userID, starID
|
||
}
|
||
|
||
// parseIntValue 解析各种类型的值为 int64
|
||
func parseIntValue(v interface{}) int64 {
|
||
switch val := v.(type) {
|
||
case int64:
|
||
return val
|
||
case int:
|
||
return int64(val)
|
||
case float64:
|
||
return int64(val)
|
||
case string:
|
||
var result int64
|
||
fmt.Sscanf(val, "%d", &result)
|
||
return result
|
||
case []string:
|
||
if len(val) > 0 {
|
||
var result int64
|
||
fmt.Sscanf(val[0], "%d", &result)
|
||
return result
|
||
}
|
||
case []interface{}:
|
||
if len(val) > 0 {
|
||
return parseIntValue(val[0])
|
||
}
|
||
}
|
||
return 0
|
||
}
|
||
|
||
// UpdateFanProfileSocial 更新粉丝档案的好友数量(内部RPC调用)
|
||
func (p *UserProvider) UpdateFanProfileSocial(ctx context.Context, req *pb.UpdateFanProfileSocialRequest) (*pb.UpdateFanProfileSocialResponse, error) {
|
||
logger.Logger.Info("Received UpdateFanProfileSocial request",
|
||
zap.Int64("user_id", req.UserId),
|
||
zap.Int64("star_id", req.StarId),
|
||
zap.Int32("delta", req.Delta),
|
||
)
|
||
|
||
// 调用Service层
|
||
resp, err := p.userService.UpdateFanProfileSocial(req)
|
||
if err != nil {
|
||
logger.Logger.Error("UpdateFanProfileSocial failed",
|
||
zap.Int64("user_id", req.UserId),
|
||
zap.Int64("star_id", req.StarId),
|
||
zap.Int32("delta", req.Delta),
|
||
zap.Error(err),
|
||
)
|
||
|
||
// 如果响应为空,构建错误响应
|
||
if resp == nil {
|
||
resp = &pb.UpdateFanProfileSocialResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: appErrors.ToStatusCode(err),
|
||
Message: err.Error(),
|
||
Timestamp: 0,
|
||
},
|
||
}
|
||
}
|
||
|
||
return resp, err
|
||
}
|
||
|
||
logger.Logger.Info("UpdateFanProfileSocial successful",
|
||
zap.Int64("user_id", req.UserId),
|
||
zap.Int64("star_id", req.StarId),
|
||
zap.Int32("delta", req.Delta),
|
||
zap.Int32("new_social", resp.NewSocial),
|
||
)
|
||
|
||
return resp, nil
|
||
}
|
||
|
||
// UpdateCrystalBalance 更新水晶余额(内部RPC调用)
|
||
func (p *UserProvider) UpdateCrystalBalance(ctx context.Context, req *pb.UpdateCrystalBalanceRequest) (*pb.UpdateCrystalBalanceResponse, error) {
|
||
logger.Logger.Info("Received UpdateCrystalBalance request",
|
||
zap.Int64("user_id", req.UserId),
|
||
zap.Int64("star_id", req.StarId),
|
||
zap.Int64("delta", req.Delta),
|
||
)
|
||
|
||
// 调用Service层
|
||
resp, err := p.userService.UpdateCrystalBalance(req)
|
||
if err != nil {
|
||
logger.Logger.Error("UpdateCrystalBalance failed",
|
||
zap.Int64("user_id", req.UserId),
|
||
zap.Int64("star_id", req.StarId),
|
||
zap.Int64("delta", req.Delta),
|
||
zap.Error(err),
|
||
)
|
||
|
||
// 如果响应为空,构建错误响应
|
||
if resp == nil {
|
||
resp = &pb.UpdateCrystalBalanceResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: appErrors.ToStatusCode(err),
|
||
Message: err.Error(),
|
||
Timestamp: 0,
|
||
},
|
||
}
|
||
}
|
||
|
||
return resp, err
|
||
}
|
||
|
||
logger.Logger.Info("UpdateCrystalBalance successful",
|
||
zap.Int64("user_id", req.UserId),
|
||
zap.Int64("star_id", req.StarId),
|
||
zap.Int64("delta", req.Delta),
|
||
zap.Int64("new_balance", resp.NewBalance),
|
||
)
|
||
|
||
return resp, nil
|
||
}
|
||
|
||
// UpdateAssetsCount 更新资产数量(内部RPC调用)
|
||
func (p *UserProvider) UpdateAssetsCount(ctx context.Context, req *pb.UpdateAssetsCountRequest) (*pb.UpdateAssetsCountResponse, error) {
|
||
logger.Logger.Info("Received UpdateAssetsCount request",
|
||
zap.Int64("user_id", req.UserId),
|
||
zap.Int64("star_id", req.StarId),
|
||
zap.Int32("delta", req.Delta),
|
||
)
|
||
|
||
// 调用Service层
|
||
resp, err := p.userService.UpdateAssetsCount(req)
|
||
if err != nil {
|
||
logger.Logger.Error("UpdateAssetsCount failed",
|
||
zap.Int64("user_id", req.UserId),
|
||
zap.Int64("star_id", req.StarId),
|
||
zap.Int32("delta", req.Delta),
|
||
zap.Error(err),
|
||
)
|
||
|
||
// 如果响应为空,构建错误响应
|
||
if resp == nil {
|
||
resp = &pb.UpdateAssetsCountResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: appErrors.ToStatusCode(err),
|
||
Message: err.Error(),
|
||
Timestamp: 0,
|
||
},
|
||
}
|
||
}
|
||
|
||
return resp, err
|
||
}
|
||
|
||
logger.Logger.Info("UpdateAssetsCount successful",
|
||
zap.Int64("user_id", req.UserId),
|
||
zap.Int64("star_id", req.StarId),
|
||
zap.Int32("delta", req.Delta),
|
||
zap.Int32("new_count", resp.NewCount),
|
||
)
|
||
|
||
return resp, nil
|
||
}
|