/// <summary>
        /// 创建 <see cref="DossierPage"/>
        /// </summary>
        /// <param name="user">用户对象</param>
        /// <param name="currentUserId">当前登录用户 ID</param>
        /// <param name="dbContext"><see cref="KeylolDbContext"/></param>
        /// <param name="cachedData"><see cref="CachedDataProvider"/></param>
        /// <param name="userManager"><see cref="KeylolUserManager"/></param>
        /// <returns><see cref="DossierPage"/></returns>
        public static async Task <DossierPage> CreateAsync(KeylolUser user, string currentUserId,
                                                           KeylolDbContext dbContext, CachedDataProvider cachedData, KeylolUserManager userManager)
        {
            var subscribedPoints =
                await SubscribedPointList.CreateAsync(currentUserId, user.Id, 1, 3, true, dbContext, cachedData);

            var selectedArticles =
                await SelectedArticleList.CreateAsync(user.Id, 1, 8, true, currentUserId, dbContext, cachedData);

            var dossierPage = new DossierPage
            {
                Coupon          = user.Coupon,
                LikeCount       = await cachedData.Likes.GetUserLikeCountAsync(user.Id),
                GameCount       = await dbContext.UserSteamGameRecords.CountAsync(r => r.UserId == user.Id),
                PlayedGameCount =
                    await dbContext.UserSteamGameRecords.CountAsync(r => r.UserId == user.Id && r.TotalPlayedTime > 0),
                SpotlightCount       = await dbContext.Articles.CountAsync(a => a.AuthorId == user.Id && a.Spotlighted),
                IsOperator           = await userManager.IsInRoleAsync(user.Id, KeylolRoles.Operator),
                SubscribedPointCount = subscribedPoints.Item2,
                SubscribedPoints     = subscribedPoints.Item1,
                ArticleCount         = selectedArticles.Item2,
                SelectedArticles     = selectedArticles.Item1
            };

            return(dossierPage);
        }
        /// <summary>
        /// 创建 <see cref="EditPage"/>
        /// </summary>
        /// <param name="user">用户对象</param>
        /// <param name="currentUserId">当前登录用户 ID</param>
        /// <param name="dbContext"><see cref="KeylolDbContext"/></param>
        /// <param name="userManager"><see cref="KeylolUserManager"/></param>
        /// <returns><see cref="EditPage"/></returns>
        public static async Task <EditPage> CreateAsync(KeylolUser user, string currentUserId, KeylolDbContext dbContext,
                                                        KeylolUserManager userManager)
        {
            if (currentUserId != user.Id && !await userManager.IsInRoleAsync(currentUserId, KeylolRoles.Operator))
            {
                return(new EditPage());
            }

            var editPage = new EditPage
            {
                Email                        = user.Email,
                LockoutEnabled               = user.LockoutEnabled,
                OpenInNewWindow              = user.OpenInNewWindow,
                UseEnglishPointName          = user.PreferredPointName == PreferredPointName.English,
                NotifyOnArticleReplied       = user.NotifyOnArticleReplied,
                NotifyOnCommentReplied       = user.NotifyOnCommentReplied,
                NotifyOnActivityReplied      = user.NotifyOnActivityReplied,
                NotifyOnArticleLiked         = user.NotifyOnArticleLiked,
                NotifyOnCommentLiked         = user.NotifyOnCommentLiked,
                NotifyOnActivityLiked        = user.NotifyOnActivityLiked,
                NotifyOnSubscribed           = user.NotifyOnSubscribed,
                SteamNotifyOnArticleReplied  = user.SteamNotifyOnArticleReplied,
                SteamNotifyOnCommentReplied  = user.SteamNotifyOnCommentReplied,
                SteamNotifyOnActivityReplied = user.SteamNotifyOnActivityReplied,
                SteamNotifyOnArticleLiked    = user.SteamNotifyOnArticleLiked,
                SteamNotifyOnCommentLiked    = user.SteamNotifyOnCommentLiked,
                SteamNotifyOnActivityLiked   = user.SteamNotifyOnActivityLiked,
                SteamNotifyOnSubscribed      = user.SteamNotifyOnSubscribed,
                SteamNotifyOnSpotlighted     = user.SteamNotifyOnSpotlighted,
                SteamNotifyOnMissive         = user.SteamNotifyOnMissive
            };

            if (user.SteamBotId == null)
            {
                editPage.SteamBotLost    = true;
                editPage.SteamBotSteamId = (await SteamBindingHub.GetNextBotAsync(dbContext)).SteamId;
            }
            else
            {
                editPage.SteamBotName    = $"其乐机器人 Keylol.com #{user.SteamBot.Sid}";
                editPage.SteamBotSteamId = user.SteamBot.SteamId;
            }
            return(editPage);
        }
Exemple #3
0
        /// <summary>
        /// 创建 <see cref="UserBasicInfo"/>
        /// </summary>
        /// <param name="currentUserId">当前登录用户 ID</param>
        /// <param name="user">用户对象</param>
        /// <param name="dbContext"><see cref="KeylolDbContext"/></param>
        /// <param name="cachedData"><see cref="CachedDataProvider"/></param>
        /// <param name="userManager"><see cref="KeylolUserManager"/></param>
        /// <returns><see cref="UserBasicInfo"/></returns>
        public static async Task <UserBasicInfo> CreateAsync(string currentUserId, KeylolUser user,
                                                             KeylolDbContext dbContext, CachedDataProvider cachedData, KeylolUserManager userManager)
        {
            var basicInfo = new UserBasicInfo
            {
                Id           = user.Id,
                IdCode       = user.IdCode,
                HeaderImage  = user.HeaderImage,
                AvatarImage  = user.AvatarImage,
                UserName     = user.UserName,
                GamerTag     = user.GamerTag,
                RegisterTime = user.RegisterTime,
                IsFriend     = string.IsNullOrWhiteSpace(currentUserId)
                    ? (bool?)null
                    : await cachedData.Users.IsFriendAsync(currentUserId, user.Id),
                Subscribed = string.IsNullOrWhiteSpace(currentUserId)
                    ? (bool?)null
                    : await cachedData.Subscriptions.IsSubscribedAsync(currentUserId, user.Id,
                                                                       SubscriptionTargetType.User),
                FriendCount         = await cachedData.Subscriptions.GetFriendCountAsync(user.Id),
                SubscribedUserCount = await cachedData.Subscriptions.GetSubscribedUserCountAsync(user.Id),
                SubscriberCount     =
                    await cachedData.Subscriptions.GetSubscriberCountAsync(user.Id, SubscriptionTargetType.User),
                ThemeColor      = user.ThemeColor,
                LightThemeColor = user.LightThemeColor,
                SteamId         = await userManager.GetSteamIdAsync(user.Id)
            };

            if (!string.IsNullOrWhiteSpace(basicInfo.SteamId))
            {
                basicInfo.SteamProfileName = user.SteamProfileName;
            }
            int steamCnUid;

            if (int.TryParse(await userManager.GetSteamCnUidAsync(user.Id), out steamCnUid))
            {
                basicInfo.SteamCnUid      = steamCnUid;
                basicInfo.SteamCnUserName = user.SteamCnUserName;
            }
            return(basicInfo);
        }
        /// <summary>
        ///     增减用户的文券数量
        /// </summary>
        /// <param name="user">用户对象</param>
        /// <param name="event">文券事件</param>
        /// <param name="change">文券数量变化,正数为增加,负数为减少</param>
        /// <param name="description">文券记录描述</param>
        /// <param name="logTime">文券日志记录时间,如果为 null 则使用当前时间</param>
        /// <exception cref="ArgumentNullException">user 参数为 null</exception>
        public async Task UpdateAsync(KeylolUser user, CouponEvent @event, int change, object description = null,
                                      DateTime?logTime = null)
        {
            if (user == null)
            {
                throw new ArgumentNullException(nameof(user));
            }

            var log = new CouponLog
            {
                Change      = change,
                Event       = @event,
                UserId      = user.Id,
                Description = JsonConvert.SerializeObject(description)
            };

            _dbContext.CouponLogs.Add(log);

            bool saveFailed;

            do
            {
                try
                {
                    saveFailed     = false;
                    user.Coupon   += log.Change;
                    log.Balance    = user.Coupon;
                    log.CreateTime = logTime ?? DateTime.Now;
                    await _dbContext.SaveChangesAsync();

                    NotificationProvider.Hub <CouponHub, ICouponHubClient>().User(user.Id)?
                    .OnCouponChanged(log.Event.ToString(), log.Change, log.Balance);
                }
                catch (DbUpdateConcurrencyException e)
                {
                    saveFailed = true;
                    await e.Entries.Single().ReloadAsync();
                }
            } while (saveFailed);
        }
        /// <summary>
        /// 创建 <see cref="CurrentUser"/>
        /// </summary>
        /// <param name="user">用户对象</param>
        /// <param name="userManager"><see cref="KeylolUserManager"/></param>
        /// <param name="dbContext"><see cref="KeylolDbContext"/></param>
        /// <param name="coupon"><see cref="CouponProvider"/></param>
        /// <param name="cachedData"><see cref="CachedDataProvider"/></param>
        /// <returns><see cref="CurrentUser"/></returns>
        public static async Task <CurrentUser> CreateAsync(KeylolUser user, KeylolUserManager userManager,
                                                           KeylolDbContext dbContext, CouponProvider coupon, CachedDataProvider cachedData)
        {
            // 每日访问奖励
            if (DateTime.Now.Date > user.LastDailyRewardTime.Date)
            {
                user.LastDailyRewardTime = DateTime.Now;
                user.FreeLike            = 5; // 免费认可重置
                try
                {
                    await dbContext.SaveChangesAsync();

                    await coupon.UpdateAsync(user, CouponEvent.每日访问);
                }
                catch (DbUpdateConcurrencyException)
                {
                }
            }

            // Steam 游戏记录更新
            SteamCrawlerProvider.UpdateUserSteamGameRecords(user.Id);

            // Steam 好友列表更新
            SteamCrawlerProvider.UpdateUserSteamFrineds(user.Id);

            return(new CurrentUser
            {
                Id = user.Id,
                UserName = user.UserName,
                IdCode = user.IdCode,
                Roles = (await userManager.GetRolesAsync(user.Id)).ToList(),
                AvatarImage = user.AvatarImage,
                MessageCount = await cachedData.Messages.GetUserUnreadMessageCountAsync(user.Id),
                Coupon = user.Coupon,
                PreferredPointName = user.PreferredPointName,
                OpenInNewWindow = user.OpenInNewWindow
            });
        }
 /// <summary>
 ///     根据文券事件更新用户的文券数量
 /// </summary>
 /// <param name="user">用户对象</param>
 /// <param name="event">文券事件</param>
 /// <param name="description">文券记录描述,会被序列化成 JSON 存储到数据库</param>
 /// <param name="logTime">文券日志记录时间,如果为 null 则使用当前时间</param>
 /// <exception cref="ArgumentNullException">user 参数为 null</exception>
 public async Task UpdateAsync(KeylolUser user, CouponEvent @event, object description = null,
                               DateTime?logTime = null)
 {
     await UpdateAsync(user, @event, @event.ToCouponChange(), description, logTime);
 }
        public async Task <IHttpActionResult> CreateOneBySms([NotNull] UserCreateOneBySmsRequestDto bySmsRequestDto)
        {
            // 检查手机是否合法
            if (string.IsNullOrWhiteSpace(bySmsRequestDto.PhoneNumber) || !Regex.IsMatch(bySmsRequestDto.PhoneNumber, Constants.ChinesePhoneNumberConstraint))
            {
                return(this.BadRequest(nameof(bySmsRequestDto.PhoneNumber), Errors.InvalidPhoneNumber));
            }

            // 检查手机是否已经注册
            if (bySmsRequestDto.PhoneNumber != null &&
                await _userManager.FindByPhoneNumberAsync(bySmsRequestDto.PhoneNumber) != null)
            {
                return(this.BadRequest(nameof(bySmsRequestDto.PhoneNumber), Errors.PhoneNumberUsed));
            }

            if (bySmsRequestDto.Email != null && (!new EmailAddressAttribute().IsValid(bySmsRequestDto.Email) ||
                                                  await _userManager.FindByEmailAsync(bySmsRequestDto.Email) != null))
            {
                bySmsRequestDto.Email = null;
            }

            var user = new KeylolUser
            {
                IdCode           = bySmsRequestDto.IdCode,
                UserName         = bySmsRequestDto.UserName,
                Email            = bySmsRequestDto.Email,
                PhoneNumber      = bySmsRequestDto.PhoneNumber,
                RegisterIp       = _owinContext.Request.RemoteIpAddress,
                SteamBindingTime = DateTime.Now
            };

            if (bySmsRequestDto.AvatarImage != null)
            {
                user.AvatarImage = bySmsRequestDto.AvatarImage;
            }

            if (bySmsRequestDto.SteamProfileName != null)
            {
                user.SteamProfileName = bySmsRequestDto.SteamProfileName;
            }

            var result = await _userManager.CreateAsync(user, bySmsRequestDto.Password);

            if (!result.Succeeded)
            {
                var    error = result.Errors.First();
                string propertyName;
                switch (error)
                {
                case Errors.InvalidIdCode:
                case Errors.IdCodeReserved:
                case Errors.IdCodeUsed:
                    propertyName = nameof(bySmsRequestDto.IdCode);
                    break;

                case Errors.UserNameInvalidCharacter:
                case Errors.UserNameInvalidLength:
                case Errors.UserNameUsed:
                    propertyName = nameof(bySmsRequestDto.UserName);
                    break;

                case Errors.InvalidEmail:
                    propertyName = nameof(bySmsRequestDto.Email);
                    break;

                case Errors.AvatarImageUntrusted:
                    propertyName = nameof(bySmsRequestDto.AvatarImage);
                    break;

                case Errors.PasswordAllWhitespace:
                case Errors.PasswordTooShort:
                    propertyName = nameof(bySmsRequestDto.Password);
                    break;

                default:
                    return(this.BadRequest(nameof(bySmsRequestDto), error));
                }
                return(this.BadRequest(nameof(bySmsRequestDto), propertyName, error));
            }

            // 检查 SMS Code
            if (bySmsRequestDto.SmsCode == null || bySmsRequestDto.PhoneNumber !=
                await _oneTimeToken.Consume <string>(bySmsRequestDto.SmsCode, OneTimeTokenPurpose.UserRegister))
            {
                return(this.BadRequest(nameof(bySmsRequestDto.SmsCode), Errors.InvalidToken));
            }

            await _userManager.AddLoginAsync(user.Id,
                                             new UserLoginInfo(KeylolLoginProviders.Sms, user.PhoneNumber));

            await _dbContext.SaveChangesAsync();

            if (bySmsRequestDto.SteamCnUserName != null)
            {
                var steamCnUser =
                    await SteamCnProvider.UserLoginAsync(bySmsRequestDto.SteamCnUserName, bySmsRequestDto.SteamCnPassword, false);

                if (steamCnUser != null && steamCnUser.Uid > 0 &&
                    await _userManager.FindAsync(new UserLoginInfo(KeylolLoginProviders.SteamCn,
                                                                   steamCnUser.Uid.ToString())) == null)
                {
                    await _userManager.AddLoginAsync(user.Id, new UserLoginInfo(KeylolLoginProviders.SteamCn,
                                                                                steamCnUser.Uid.ToString()));

                    user.SteamCnUserName    = steamCnUser.UserName;
                    user.SteamCnBindingTime = DateTime.Now;
                    await _dbContext.SaveChangesAsync();
                }
            }

            await _coupon.UpdateAsync(user, CouponEvent.新注册);

            var inviterText = string.Empty;

            if (bySmsRequestDto.InviterIdCode != null)
            {
                var inviter = await _userManager.FindByIdCodeAsync(bySmsRequestDto.InviterIdCode);

                if (inviter != null)
                {
                    user.InviterId = inviter.Id;
                    await _dbContext.SaveChangesAsync();

                    await _coupon.UpdateAsync(inviter, CouponEvent.邀请注册, new { UserId = user.Id });

                    await _coupon.UpdateAsync(user, CouponEvent.应邀注册, new { InviterId = user.Id });

                    inviterText = $"邀请人:{inviter.UserName} ({inviter.IdCode})\n";
                }
            }

            AutoSubscribe(user.Id);

            var operatorRoleId = (await _roleManager.FindByNameAsync(KeylolRoles.Operator)).Id;

            foreach (var @operator in await _dbContext.Users
                     .Where(u => u.Roles.Any(r => r.RoleId == operatorRoleId)).ToListAsync())
            {
                await _userManager.SendSteamChatMessageAsync(@operator,
                                                             $"[新用户注册 {user.RegisterTime}]\n#{user.Sid} {user.UserName}\nSteam 昵称:{user.SteamProfileName}\nIP:{user.RegisterIp}\n{inviterText}https://www.keylol.com/user/{user.IdCode}");
            }

            return(Ok(await _oneTimeToken.Generate(user.Id, TimeSpan.FromMinutes(1), OneTimeTokenPurpose.UserLogin)));
        }
Exemple #8
0
 /// <summary>
 /// 初始化属性
 /// </summary>
 /// <param name="user">要兑换的用户</param>
 /// <param name="gift">文券商品</param>
 public virtual void Initialize(KeylolUser user, Models.CouponGift gift)
 {
     User = user;
     Gift = gift;
 }
        public async Task <IHttpActionResult> CreateOne(string targetId, SubscriptionTargetType targetType)
        {
            var        subscriberId = User.Identity.GetUserId();
            bool       existed;
            KeylolUser targetUser = null;

            switch (targetType)
            {
            case SubscriptionTargetType.Point:
                existed = await _dbContext.Points.AnyAsync(p => p.Id == targetId);

                break;

            case SubscriptionTargetType.User:
                if (subscriberId.Equals(targetId, StringComparison.OrdinalIgnoreCase))
                {
                    return(this.BadRequest(nameof(targetId), Errors.Invalid));
                }
                targetUser = await _userManager.FindByIdAsync(targetId);

                existed = targetUser != null;
                break;

            case SubscriptionTargetType.Conference:
                existed = await _dbContext.Conferences.AnyAsync(c => c.Id == targetId);

                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(targetType), targetType, null);
            }
            if (!existed)
            {
                return(this.BadRequest(nameof(targetId), Errors.NonExistent));
            }
            var succeed = await _cachedData.Subscriptions.AddAsync(subscriberId, targetId, targetType);

            if (targetType == SubscriptionTargetType.User && succeed)
            {
                Debug.Assert(targetUser != null, "targetUser != null");
                var subscriberCount =
                    (int)await _cachedData.Subscriptions.GetSubscriberCountAsync(targetId, targetType);

                if (targetUser.NotifyOnSubscribed)
                {
                    await _cachedData.Messages.AddAsync(new Message
                    {
                        Type       = MessageType.NewSubscriber,
                        OperatorId = subscriberId,
                        ReceiverId = targetId,
                        Count      = subscriberCount
                    });
                }
                if (targetUser.SteamNotifyOnSubscribed)
                {
                    var subscriber = await _userManager.FindByIdAsync(subscriberId);

                    await _userManager.SendSteamChatMessageAsync(targetUser,
                                                                 await _cachedData.Users.IsFriendAsync(subscriberId, targetId)
                                                                 ?$"用户 {subscriber.UserName} 成为了你的第 {subscriberCount} 位听众,并开始与你互相关注。换句话说,你们已经成为好友啦!"
                                                                 : $"用户 {subscriber.UserName} 关注了你并成为你的第 {subscriberCount} 位听众,你们之间互相关注后会成为好友。");
                }
            }
            return(Ok());
        }