package authser import ( "context" "strings" "time" "hkdj-web-server/pub/common/log" "hkdj-web-server/pub/common/srvdef" "hkdj-web-server/pub/common/useragent" "hkdj-web-server/pub/common/utils" "hkdj-web-server/pub/models/usermod" "hkdj-web-server/pub/pubdef" "go.mongodb.org/mongo-driver/bson" ) var defaultAvatars = []string{ "v3/image/bo/ty/1016/girl1.jpeg", "v3/image/re/9y/1016/girl2.jpeg", "v3/image/wr/1t/1016/girl3.jpeg", "v3/image/8l/26/1016/girl4.jpeg", "v3/image/22/6l/1016/girl5.jpeg", "v3/image/8h/16/1016/girl6.jpeg", "v3/image/wj/15/1016/girl7.jpeg", "v3/image/t2/13/1016/girl8.jpeg", "v3/image/4r/j/1016/girl9.jpeg", "v3/image/16c/9/1016/girl10.jpeg", } func randomAvatar() string { idx := time.Now().UnixNano() % int64(len(defaultAvatars)) return defaultAvatars[idx] } // generateUniqueInviteCode 生成不与已有用户冲突的 12 位邀请码(简化实现) func generateUniqueInviteCode(ctx context.Context) string { return strings.ToUpper(utils.GetRandomLetters(12)) } // LoginResp 用户信息 type LoginResp struct { UserId int64 `json:"userId"` AccountNo string `json:"accountNo"` Email string `json:"email"` NickName string `json:"nickName"` Avatar string `json:"avatar"` Introduction string `json:"introduction"` DevID string `json:"devID"` Mac string `json:"mac"` DeviceId string `json:"deviceId"` InviteCode string `json:"inviteCode"` AgentInviteCode string `json:"agentInviteCode"` Invites int64 `json:"invites"` Status pubdef.UserStatus `json:"status"` Type pubdef.UserType `json:"type"` // 身份类型:0游客 1普通用户 LoginType pubdef.LoginType `json:"loginType"` // 登陆方式 IsRegister bool `json:"isRegister"` // 是否已注册 PrivacyMode bool `json:"privacyMode"` // 隐私模式 Score int64 `json:"score"` // 积分 Recharge int64 `json:"recharge"` // 金币余额 } // CrawlerLoginResp 爬虫虚拟游客资料,不对应任何数据库用户。 func CrawlerLoginResp() *LoginResp { return &LoginResp{ UserId: pubdef.CrawlerUserId, NickName: "游客", Status: pubdef.UserStatusNormal, Type: pubdef.UserTypeGuest, LoginType: pubdef.LoginTypeDevice, IsRegister: false, } } // GetInfo 获取当前用户的最新信息 func GetInfo(ctx context.Context, userId int64, ua useragent.UA) (*LoginResp, *srvdef.SrvErr) { if pubdef.IsCrawlerUser(userId) { return CrawlerLoginResp(), nil } user, _ := usermod.FindOneUser(ctx, bson.M{usermod.FN.User.Id: userId}) if user == nil { return nil, srvdef.New(srvdef.ErrUserNotExsit, srvdef.ErrUserNotExsit.Msg(), "") } now := time.Now() setDoc := bson.M{} if v := strings.TrimSpace(ua.DevID); v != "" && v != user.DevID { setDoc[usermod.FN.User.DevID] = v user.DevID = v } if v := strings.TrimSpace(ua.DevType); v != "" && v != user.Device { setDoc[usermod.FN.User.Device] = v user.Device = v } if v := strings.TrimSpace(ua.SysType); v != "" && v != user.SysType { setDoc[usermod.FN.User.SysType] = v user.SysType = v } if v := strings.TrimSpace(ua.Ver); v != "" && v != user.AppVer { setDoc[usermod.FN.User.AppVer] = v user.AppVer = v } mergeUAExtFieldsToSet(setDoc, user, ua) if len(setDoc) > 0 { setDoc[usermod.FN.User.UpdatedAt] = now _ = usermod.UpdateOneUser(ctx, bson.M{usermod.FN.User.Id: user.Id}, bson.M{"$set": setDoc}) } return toLoginResp(ctx, user, true), nil } func mergeUAExtFieldsToSet(setDoc bson.M, user *usermod.User, ua useragent.UA) { if v := strings.TrimSpace(ua.SessionID); v != "" && v != user.SessionID { setDoc[usermod.FN.User.SessionID] = v } if v := strings.TrimSpace(ua.DeviceBrand); v != "" && v != user.DeviceBrand { setDoc[usermod.FN.User.DeviceBrand] = v } if v := strings.TrimSpace(ua.DeviceModel); v != "" && v != user.DeviceModel { setDoc[usermod.FN.User.DeviceModel] = v } if v := strings.TrimSpace(ua.SystemName); v != "" && v != user.SystemName { setDoc[usermod.FN.User.SystemName] = v } if v := strings.TrimSpace(ua.SystemVersion); v != "" && v != user.SystemVersion { setDoc[usermod.FN.User.SystemVersion] = v } if v := strings.TrimSpace(ua.Ver); v != "" && user.OriVer == "" { setDoc[usermod.FN.User.OriVer] = v } } // UpdateProfileReq 修改用户资料的参数(所有字段均为可选) type UpdateProfileReq struct { UserId int64 // 用户ID(按设备ID识别) NickName *string // 新昵称(可选) Avatar *string // 新头像 URL(可选) Introduction *string // 简介(可选) PrivacyMode *bool // 隐私模式:true-开启,false-关闭(可选) } // UpdateProfile 修改用户资料:支持修改昵称、头像、简介、隐私模式,或组合修改 func UpdateProfile(ctx context.Context, req *UpdateProfileReq) *srvdef.SrvErr { user, _ := usermod.FindOneUser(ctx, bson.M{usermod.FN.User.Id: req.UserId}) if user == nil { return srvdef.New(srvdef.ErrUserNotExsit, srvdef.ErrUserNotExsit.Msg(), "") } setDoc := bson.M{usermod.FN.User.UpdatedAt: time.Now()} if req.NickName != nil { nick := strings.TrimSpace(*req.NickName) if nick == "" { return srvdef.New(srvdef.ErrParamError, "昵称不能为空", "") } setDoc[usermod.FN.User.NickName] = nick } if req.Avatar != nil { setDoc[usermod.FN.User.Avatar] = strings.TrimSpace(*req.Avatar) } if req.Introduction != nil { setDoc[usermod.FN.User.Introduction] = strings.TrimSpace(*req.Introduction) } if req.PrivacyMode != nil { setDoc[usermod.FN.User.PrivacyMode] = *req.PrivacyMode } // 没有任何需要更新的字段 if len(setDoc) == 1 { return srvdef.New(srvdef.ErrParamError, "至少需要修改一项资料", "") } if serr := usermod.UpdateOneUser(ctx, bson.M{usermod.FN.User.Id: user.Id}, bson.M{"$set": setDoc}, ); serr != nil { log.Error("UpdateProfile UpdateOneUser failed", log.Any("userId", user.Id), log.E(serr)) return serr } return nil }