/// <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); }
/// <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))); }
/// <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()); }