/// <summary> /// 创建 <see cref="RankingUserList"/> /// </summary> /// <param name="currentUserId">当前登录用户 ID</param> /// <param name="page">分页页码</param> /// <param name="dbContext"><see cref="KeylolDbContext"/></param> /// <param name="cachedData"><see cref="CachedDataProvider"/></param> /// <returns><see cref="RankingUserList"/></returns> public static async Task <RankingUserList> CreateAsync(string currentUserId, int page, KeylolDbContext dbContext, CachedDataProvider cachedData) { if (page > 7) { page = 7; } var queryResult = await dbContext.Users.OrderByDescending(u => u.SeasonLikeCount) .ThenByDescending(u => u.Coupon) .Select(u => new { u.Id, u.IdCode, u.UserName, u.AvatarImage, u.GamerTag, u.SeasonLikeCount, u.Coupon }).Take(100).ToListAsync(); var actualResult = queryResult.Select((u, i) => new { Ranking = i, User = u }).Skip(RecordsPerPage * (page - 1)).Take(RecordsPerPage).ToList(); var result = new RankingUserList(actualResult.Count); foreach (var g in actualResult) { result.Add(new RankingUser { Ranking = g.Ranking, UserBasicInfo = new UserBasicInfo { IdCode = g.User.IdCode, AvatarImage = g.User.AvatarImage, UserName = g.User.UserName, GamerTag = g.User.GamerTag, IsFriend = string.IsNullOrWhiteSpace(currentUserId) ? (bool?)null : await cachedData.Users.IsFriendAsync(currentUserId, g.User.Id) }, Coupon = g.User.Coupon, SeasonLikeCount = g.User.SeasonLikeCount }); } return(result); }
/// <summary> /// 创建 <see cref="ActivityCommentList"/> /// </summary> /// <param name="activityId">动态 ID</param> /// <param name="currentUserId">当前登录用户 ID</param> /// <param name="before">起始位置</param> /// <param name="take">获取数量</param> /// <param name="isOperator">当前登录用户是否为运维职员</param> /// <param name="dbContext"><see cref="KeylolDbContext"/></param> /// <param name="cachedData"><see cref="CachedDataProvider"/></param> /// <returns><see cref="ActivityCommentList"/></returns> public static async Task <ActivityCommentList> CreateAsync(string activityId, string currentUserId, int before, int take, bool isOperator, KeylolDbContext dbContext, CachedDataProvider cachedData) { var activity = await dbContext.Activities.FindAsync(activityId); if (activity == null || (activity.Archived != ArchivedState.None && currentUserId != activity.AuthorId && !isOperator)) { return(new ActivityCommentList(0)); } var queryResult = await(from comment in dbContext.ActivityComments where comment.ActivityId == activity.Id && comment.Sid < before orderby comment.Sid descending select new { AuthorIdCode = comment.Commentator.IdCode, AuthorAvatarImage = comment.Commentator.AvatarImage, AuthorUserName = comment.Commentator.UserName, AuthorId = comment.CommentatorId, comment.Id, comment.PublishTime, comment.SidForActivity, comment.Content, comment.Archived, comment.Warned }).Take(take).ToListAsync(); var result = new ActivityCommentList(queryResult.Count); foreach (var c in queryResult) { var activityComment = new ActivityComment { Id = c.Id, SidForActivity = c.SidForActivity, Archived = c.Archived != ArchivedState.None }; // ReSharper disable once PossibleInvalidOperationException if (!activityComment.Archived.Value || currentUserId == c.AuthorId || isOperator) { activityComment.AuthorIdCode = c.AuthorIdCode; activityComment.AuthorAvatarImage = c.AuthorAvatarImage; activityComment.AuthorUserName = c.AuthorUserName; activityComment.LikeCount = await cachedData.Likes.GetTargetLikeCountAsync(c.Id, LikeTargetType.ActivityComment); activityComment.Liked = string.IsNullOrWhiteSpace(currentUserId) ? (bool?)null : await cachedData.Likes.IsLikedAsync(currentUserId, c.Id, LikeTargetType.ActivityComment); activityComment.PublishTime = c.PublishTime; activityComment.Content = c.Content; activityComment.Warned = c.Warned; } result.Add(activityComment); } result.Reverse(); return(result); }
/// <summary> /// 获取指定页码的最近有动态的据点列表 /// </summary> /// <param name="page">分页页码</param> /// <param name="dbContext"><see cref="KeylolDbContext"/></param> /// <param name="cachedData"><see cref="CachedDataProvider"/></param> /// <returns>最新文章列表</returns> public static async Task <RecentPointList> Get(int page, [Injected] KeylolDbContext dbContext, [Injected] CachedDataProvider cachedData) { return((await CreateAsync(StateTreeHelper.GetCurrentUserId(), page, false, dbContext, cachedData)).Item1); }
/// <summary> /// 获取时间轴卡片列表 /// </summary> /// <param name="pointId">据点 ID</param> /// <param name="before">起始位置</param> /// <param name="take">获取数量</param> /// <param name="dbContext"><see cref="KeylolDbContext"/></param> /// <param name="cachedData"><see cref="CachedDataProvider"/></param> /// <returns><see cref="TimelineCardList"/></returns> public static async Task <TimelineCardList> GetCards(string pointId, int before, int take, [Injected] KeylolDbContext dbContext, [Injected] CachedDataProvider cachedData) { return(await TimelineCardList.CreateAsync(PointStream.Name(pointId), StateTreeHelper.GetCurrentUserId(), take, false, dbContext, cachedData, before)); }
/// <summary> /// 创建 <see cref="SelectedArticleList"/> /// </summary> /// <param name="pointId">据点 ID</param> /// <param name="page">分页页码</param> /// <param name="recordsPerPage">每页数量</param> /// <param name="currentUserId">当前登录用户 ID</param> /// <param name="dbContext"><see cref="KeylolDbContext"/></param> /// <param name="cachedData"><see cref="CachedDataProvider"/></param> /// <returns><see cref="SelectedArticleList"/></returns> public static async Task <SelectedArticleList> CreateAsync(string pointId, int page, int recordsPerPage, string currentUserId, KeylolDbContext dbContext, CachedDataProvider cachedData) { var queryResult = await(from article in dbContext.Articles where article.TargetPointId == pointId && article.Archived == ArchivedState.None && article.Rejected == false orderby dbContext.Likes .Count(l => l.TargetId == article.Id && l.TargetType == LikeTargetType.Article) descending select new { article.Id, article.Title, article.Subtitle, article.CoverImage, article.SidForAuthor, article.AuthorId, AuthorIdCode = article.Author.IdCode, AuthorAvatarImage = article.Author.AvatarImage, AuthorUserName = article.Author.UserName }).TakePage(page, recordsPerPage).ToListAsync(); var result = new SelectedArticleList(queryResult.Count); foreach (var a in queryResult) { result.Add(new SelectedArticle { Title = a.Title, Subtitle = a.Subtitle, CoverImage = a.CoverImage, SidForAuthor = a.SidForAuthor, AuthorIdCode = a.AuthorIdCode, AuthorAvatarImage = a.AuthorAvatarImage, AuthorUserName = a.AuthorUserName, AuthorIsFriend = string.IsNullOrWhiteSpace(currentUserId) ? (bool?)null : await cachedData.Users.IsFriendAsync(currentUserId, a.AuthorId), LikeCount = await cachedData.Likes.GetTargetLikeCountAsync(a.Id, LikeTargetType.Article), CommentCount = await cachedData.ArticleComments.GetArticleCommentCountAsync(a.Id) }); } return(result); }
/// <summary> /// 创建满足指定据点关系的 <see cref="ProductPointList"/> /// </summary> /// <param name="currentUserId">当前登录用户 ID</param> /// <param name="pointId">据点 ID</param> /// <param name="relationshipType">据点身份</param> /// <param name="take">获取数量,如果为 null 表示获取全部</param> /// <param name="dbContext"><see cref="KeylolDbContext"/></param> /// <param name="cachedData"><see cref="CachedDataProvider"/></param> /// <returns>Item1 表示 <see cref="ProductPointList"/>,Item2 表示总据点个数</returns> public static async Task <Tuple <ProductPointList, int> > CreateAsync(string currentUserId, string pointId, PointRelationshipType relationshipType, int?take, KeylolDbContext dbContext, CachedDataProvider cachedData) { var conditionQuery = from relationship in dbContext.PointRelationships where relationship.TargetPointId == pointId && relationship.Relationship == relationshipType select relationship; var query = conditionQuery.OrderByDescending(r => r.Sid).Select(r => new { Count = conditionQuery.Count(), r.SourcePoint.Id, r.SourcePoint.IdCode, r.SourcePoint.AvatarImage, r.SourcePoint.ChineseName, r.SourcePoint.EnglishName, r.SourcePoint.TitleCoverImage, r.SourcePoint.SteamAppId }); if (take != null) { query = query.Take(() => take.Value); } var queryResult = await query.ToListAsync(); var result = new ProductPointList(queryResult.Count); foreach (var p in queryResult) { result.Add(new ProductPoint { Id = p.Id, IdCode = p.IdCode, AvatarImage = p.AvatarImage, ChineseName = p.ChineseName, EnglishName = p.EnglishName, TitleCoverImage = p.TitleCoverImage, AverageRating = (await cachedData.Points.GetRatingsAsync(p.Id)).AverageRating, Subscribed = string.IsNullOrWhiteSpace(currentUserId) ? (bool?)null : await cachedData.Subscriptions.IsSubscribedAsync(currentUserId, p.Id, SubscriptionTargetType.Point), InLibrary = string.IsNullOrWhiteSpace(currentUserId) || p.SteamAppId == null ? (bool?)null : await cachedData.Users.IsSteamAppInLibraryAsync(currentUserId, p.SteamAppId.Value) }); } var firstRecord = queryResult.FirstOrDefault(); return(new Tuple <ProductPointList, int>(result, firstRecord?.Count ?? 0)); }
/// <summary> /// 获取据点层级状态树 /// </summary> /// <param name="entrance">要获取的页面</param> /// <param name="pointIdCode">据点识别码</param> /// <param name="dbContext"><see cref="KeylolDbContext"/></param> /// <param name="cachedData"><see cref="CachedDataProvider"/></param> /// <returns><see cref="PointLevel"/></returns> public static async Task <PointLevel> Get(string entrance, string pointIdCode, [Injected] KeylolDbContext dbContext, [Injected] CachedDataProvider cachedData) { return(await CreateAsync(StateTreeHelper.GetCurrentUserId(), pointIdCode, entrance.ToEnum <EntrancePage>(), dbContext, cachedData)); }
/// <summary> /// 创建 <see cref="CouponGiftList"/> /// </summary> /// <param name="dbContext"><see cref="KeylolDbContext"/></param> /// <param name="cachedData"><see cref="CachedDataProvider"/></param> /// <param name="userManager"><see cref="KeylolUserManager"/></param> /// <param name="coupon"><see cref="CouponProvider"/></param> /// <returns><see cref="CouponGiftList"/></returns> public static async Task <CouponGiftList> Get([Injected] KeylolDbContext dbContext, [Injected] CachedDataProvider cachedData, [Injected] KeylolUserManager userManager, [Injected] CouponProvider coupon) { return(await CreateAsync(StateTreeHelper.GetCurrentUserId(), dbContext, cachedData, userManager, coupon)); }
/// <summary> /// 创建 <see cref="ArticleCommentList"/> /// </summary> /// <param name="article">文章对象</param> /// <param name="page">分页页码</param> /// <param name="currentUserId">当前登录用户 ID</param> /// <param name="isOperator">当前登录用户是否为运维职员</param> /// <param name="returnMeta">是否返回元数据(总页数、总评论数、最新评论时间)</param> /// <param name="dbContext"><see cref="KeylolDbContext"/></param> /// <param name="cachedData"><see cref="CachedDataProvider"/></param> /// <returns>Item1 表示 <see cref="ArticleCommentList"/>, Item2 表示总评论数,Item3 表示最新评论时间,Item4 表示总页数</returns> public static async Task <Tuple <ArticleCommentList, int, DateTime?, int> > CreateAsync(Models.Article article, int page, string currentUserId, bool isOperator, bool returnMeta, KeylolDbContext dbContext, CachedDataProvider cachedData) { if (article.Archived != ArchivedState.None && currentUserId != article.AuthorId && !isOperator) { return(new Tuple <ArticleCommentList, int, DateTime?, int>(new ArticleCommentList(0), 0, null, 0)); } var queryResult = await(from comment in dbContext.ArticleComments where comment.ArticleId == article.Id orderby comment.Sid select new { Author = comment.Commentator, comment.Id, comment.PublishTime, comment.SidForArticle, comment.Content, comment.ReplyToComment, ReplyToCommentAuthor = comment.ReplyToComment.Commentator, comment.Archived, comment.Warned }).TakePage(page, RecordsPerPage).ToListAsync(); var result = new ArticleCommentList(queryResult.Count); foreach (var c in queryResult) { var articleComment = new ArticleComment { Id = c.Id, SidForArticle = c.SidForArticle, Archived = c.Archived != ArchivedState.None }; // ReSharper disable once PossibleInvalidOperationException if (!articleComment.Archived.Value || currentUserId == c.Author.Id || isOperator) { articleComment.AuthorIdCode = c.Author.IdCode; articleComment.AuthorAvatarImage = c.Author.AvatarImage; articleComment.AuthorUserName = c.Author.UserName; articleComment.AuthorPlayedTime = article.TargetPoint.SteamAppId == null ? null : (await dbContext.UserSteamGameRecords .Where(r => r.UserId == c.Author.Id && r.SteamAppId == article.TargetPoint.SteamAppId) .SingleOrDefaultAsync())?.TotalPlayedTime; articleComment.LikeCount = await cachedData.Likes.GetTargetLikeCountAsync(c.Id, LikeTargetType.ArticleComment); articleComment.Liked = string.IsNullOrWhiteSpace(currentUserId) ? (bool?)null : await cachedData.Likes.IsLikedAsync(currentUserId, c.Id, LikeTargetType.ArticleComment); articleComment.PublishTime = c.PublishTime; articleComment.Content = c.Content; if (c.ReplyToComment != null) { articleComment.ReplyToComment = new ArticleComment { SidForArticle = c.ReplyToComment.SidForArticle, AuthorAvatarImage = c.ReplyToCommentAuthor.AvatarImage, AuthorUserName = c.ReplyToCommentAuthor.UserName, AuthorIdCode = c.ReplyToCommentAuthor.IdCode, Content = c.ReplyToComment.UnstyledContent.Length > 150 ? c.ReplyToComment.UnstyledContent.Substring(0, 150) : c.ReplyToComment.UnstyledContent }; } articleComment.Warned = c.Warned; } result.Add(articleComment); } var latestCommentTime = returnMeta ? await(from comment in dbContext.ArticleComments where comment.ArticleId == article.Id orderby comment.Sid descending select comment.PublishTime).FirstOrDefaultAsync() : default(DateTime); var count = await cachedData.ArticleComments.GetArticleCommentCountAsync(article.Id); return(new Tuple <ArticleCommentList, int, DateTime?, int>(result, count, latestCommentTime == default(DateTime) ? (DateTime?)null : latestCommentTime, count > 0 ? (int)Math.Ceiling(count / (double)RecordsPerPage) : 1)); }
/// <summary> /// 创建 <see cref="PointBasicInfo"/> /// </summary> /// <param name="currentUserId">当前登录用户 ID</param> /// <param name="point">据点对象</param> /// <param name="dbContext"><see cref="KeylolDbContext"/></param> /// <param name="cachedData"><see cref="CachedDataProvider"/></param> /// <returns><see cref="PointBasicInfo"/></returns> public static async Task <PointBasicInfo> CreateAsync(string currentUserId, Point point, KeylolDbContext dbContext, CachedDataProvider cachedData) { var basicInfo = new PointBasicInfo { Id = point.Id, IdCode = point.IdCode, Logo = point.Logo, ThemeColor = point.ThemeColor, LightThemeColor = point.LightThemeColor, Type = point.Type, HeaderImage = point.HeaderImage, AvatarImage = point.AvatarImage, ChineseName = point.ChineseName, EnglishName = point.EnglishName, Subscribed = string.IsNullOrWhiteSpace(currentUserId) ? (bool?)null : await cachedData.Subscriptions.IsSubscribedAsync(currentUserId, point.Id, SubscriptionTargetType.Point) }; if (point.Type == PointType.Game || point.Type == PointType.Hardware) { var rating = await cachedData.Points.GetRatingsAsync(point.Id); basicInfo.OneStarCount = rating.OneStarCount; basicInfo.TwoStarCount = rating.TwoStarCount; basicInfo.ThreeStarCount = rating.ThreeStarCount; basicInfo.FourStarCount = rating.FourStarCount; basicInfo.FiveStarCount = rating.FiveStarCount; basicInfo.AverageRating = rating.AverageRating; basicInfo.Categories = (await(from relationship in dbContext.PointRelationships where relationship.SourcePointId == point.Id && relationship.Relationship == PointRelationshipType.Tag select new { relationship.TargetPoint.IdCode, relationship.TargetPoint.ChineseName, relationship.TargetPoint.EnglishName }) .ToListAsync()) .Select(p => new PointBasicInfo { IdCode = p.IdCode, ChineseName = string.IsNullOrWhiteSpace(p.ChineseName) ? p.EnglishName : p.ChineseName }) .ToList(); basicInfo.Vendors = (await(from relationship in dbContext.PointRelationships where relationship.SourcePointId == point.Id && relationship.Relationship == PointRelationshipType.Developer || relationship.Relationship == PointRelationshipType.Manufacturer select new { relationship.TargetPoint.IdCode, relationship.TargetPoint.ChineseName, relationship.TargetPoint.EnglishName }) .ToListAsync()) .Select(p => new PointBasicInfo { IdCode = p.IdCode, ChineseName = p.ChineseName, EnglishName = p.EnglishName }) .ToList(); basicInfo.TitleCoverImage = point.TitleCoverImage; #region 商店信息 basicInfo.SteamAppId = point.SteamAppId; basicInfo.SteamPrice = point.SteamPrice; basicInfo.SteamDiscountedPrice = point.SteamDiscountedPrice; basicInfo.SonkwoProductId = point.SonkwoProductId; basicInfo.SonkwoPrice = point.SonkwoPrice; basicInfo.SonkwoDiscountedPrice = point.SonkwoDiscountedPrice; basicInfo.UplayLink = EmptyToNull(point.UplayLink); basicInfo.UplayPrice = EmptyToNull(point.UplayPrice); basicInfo.XboxLink = EmptyToNull(point.XboxLink); basicInfo.XboxPrice = EmptyToNull(point.XboxPrice); basicInfo.PlayStationLink = EmptyToNull(point.PlayStationLink); basicInfo.PlayStationPrice = EmptyToNull(point.PlayStationPrice); basicInfo.OriginLink = EmptyToNull(point.OriginLink); basicInfo.OriginPrice = EmptyToNull(point.OriginPrice); basicInfo.WindowsStoreLink = EmptyToNull(point.WindowsStoreLink); basicInfo.WindowsStorePrice = EmptyToNull(point.WindowsStorePrice); basicInfo.AppStoreLink = EmptyToNull(point.AppStoreLink); basicInfo.AppStorePrice = EmptyToNull(point.AppStorePrice); basicInfo.GooglePlayLink = EmptyToNull(point.GooglePlayLink); basicInfo.GooglePlayPrice = EmptyToNull(point.GooglePlayPrice); basicInfo.GogLink = EmptyToNull(point.GogLink); basicInfo.GogPrice = EmptyToNull(point.GogPrice); basicInfo.BattleNetLink = EmptyToNull(point.BattleNetLink); basicInfo.BattleNetPrice = EmptyToNull(point.BattleNetPrice); #endregion } else { var childPoints = await dbContext.PointRelationships .Where(r => r.TargetPointId == point.Id) .GroupBy(r => r.SourcePointId) .Select(g => g.Key) .ToListAsync(); basicInfo.ProductCount = childPoints.Count; double totalScore = 0; var validRatingCount = 0; foreach (var childPointId in childPoints) { var rating = (await cachedData.Points.GetRatingsAsync(childPointId)).AverageRating; if (rating == null) { continue; } totalScore += rating.Value; validRatingCount++; } if (validRatingCount > 0) { basicInfo.AverageRating = Math.Round(totalScore / validRatingCount, 1); } } if (point.Type == PointType.Game && point.SteamAppId != null) { SteamCrawlerProvider.UpdatePointPrice(point.Id); basicInfo.TotalPlayedTime = string.IsNullOrWhiteSpace(currentUserId) ? null : (await dbContext.UserSteamGameRecords .Where(r => r.UserId == currentUserId && r.SteamAppId == point.SteamAppId) .SingleOrDefaultAsync())?.TotalPlayedTime; basicInfo.KeylolAveragePlayedTime = Math.Round(await dbContext.UserSteamGameRecords .Where(r => r.SteamAppId == point.SteamAppId) .Select(r => r.TotalPlayedTime) .DefaultIfEmpty() .AverageAsync(), 1); basicInfo.InLibrary = string.IsNullOrWhiteSpace(currentUserId) ? (bool?)null : await cachedData.Users.IsSteamAppInLibraryAsync(currentUserId, point.SteamAppId.Value); } return(basicInfo); }
/// <summary> /// 获取指定文章的评论列表 /// </summary> /// <param name="articleId">文章 ID</param> /// <param name="page">分页页码</param> /// <param name="dbContext"><see cref="KeylolDbContext"/></param> /// <param name="cachedData"><see cref="CachedDataProvider"/></param> /// <returns><see cref="ArticleCommentList"/></returns> public static async Task <ArticleCommentList> Get(string articleId, int page, [Injected] KeylolDbContext dbContext, [Injected] CachedDataProvider cachedData) { var article = await dbContext.Articles .Include(a => a.Author) .Include(a => a.TargetPoint) .Where(a => a.Id == articleId) .SingleOrDefaultAsync(); if (article == null) { return(new ArticleCommentList(0)); } return((await CreateAsync(article, page, StateTreeHelper.GetCurrentUserId(), StateTreeHelper.GetCurrentUser().IsInRole(KeylolRoles.Operator), false, dbContext, cachedData)).Item1); }
/// <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> /// 创建 <see cref="ActivityCommentList"/> /// </summary> /// <param name="activity">动态对象</param> /// <param name="page">分页页码</param> /// <param name="currentUserId">当前登录用户 ID</param> /// <param name="isOperator">当前登录用户是否为运维职员</param> /// <param name="returnMeta">是否返回元数据(总页数、总评论数)</param> /// <param name="dbContext"><see cref="KeylolDbContext"/></param> /// <param name="cachedData"><see cref="CachedDataProvider"/></param> /// <returns>Item1 表示 <see cref="ActivityCommentList"/>, Item2 表示总评论数,Item3 表示总页数</returns> public static async Task <Tuple <ActivityCommentList, int, int> > CreateAsync(Models.Activity activity, int page, string currentUserId, bool isOperator, bool returnMeta, KeylolDbContext dbContext, CachedDataProvider cachedData) { if (activity.Archived != ArchivedState.None && currentUserId != activity.AuthorId && !isOperator) { return(new Tuple <ActivityCommentList, int, int>(new ActivityCommentList(0), 0, 0)); } var queryResult = await(from comment in dbContext.ActivityComments where comment.ActivityId == activity.Id orderby comment.Sid select new { AuthorIdCode = comment.Commentator.IdCode, AuthorAvatarImage = comment.Commentator.AvatarImage, AuthorUserName = comment.Commentator.UserName, AuthorId = comment.CommentatorId, comment.Id, comment.PublishTime, comment.SidForActivity, comment.Content, comment.Archived, comment.Warned }).TakePage(page, RecordsPerPage).ToListAsync(); var result = new ActivityCommentList(queryResult.Count); foreach (var c in queryResult) { var activityComment = new ActivityComment { Id = c.Id, SidForActivity = c.SidForActivity, Archived = c.Archived != ArchivedState.None }; // ReSharper disable once PossibleInvalidOperationException if (!activityComment.Archived.Value || currentUserId == c.AuthorId || isOperator) { activityComment.AuthorIdCode = c.AuthorIdCode; activityComment.AuthorAvatarImage = c.AuthorAvatarImage; activityComment.AuthorUserName = c.AuthorUserName; activityComment.AuthorPlayedTime = activity.TargetPoint.SteamAppId == null ? null : (await dbContext.UserSteamGameRecords .Where(r => r.UserId == c.AuthorId && r.SteamAppId == activity.TargetPoint.SteamAppId) .SingleOrDefaultAsync())?.TotalPlayedTime; activityComment.LikeCount = await cachedData.Likes.GetTargetLikeCountAsync(c.Id, LikeTargetType.ActivityComment); activityComment.Liked = string.IsNullOrWhiteSpace(currentUserId) ? (bool?)null : await cachedData.Likes.IsLikedAsync(currentUserId, c.Id, LikeTargetType.ActivityComment); activityComment.PublishTime = c.PublishTime; activityComment.Content = c.Content; activityComment.Warned = c.Warned; } result.Add(activityComment); } var count = await cachedData.ActivityComments.GetActivityCommentCountAsync(activity.Id); return(new Tuple <ActivityCommentList, int, int>(result, count, count > 0 ? (int)Math.Ceiling(count / (double)RecordsPerPage) : 1)); }
/// <summary> /// 通过关键字搜索据点列表 /// </summary> /// <param name="keyword">搜索关键字</param> /// <param name="dbContext"><see cref="KeylolDbContext"/></param> /// <param name="cachedData"><see cref="CachedDataProvider"/></param> /// <param name="page">分页页码</param> /// <param name="searchAll">是否全部查询</param> /// <returns><see cref="PointResultList"/></returns> public static async Task <PointResultList> Get(string keyword, [Injected] KeylolDbContext dbContext, [Injected] CachedDataProvider cachedData, int page, bool searchAll = true) { return (await CreateAsync(StateTreeHelper.GetCurrentUserId(), keyword, dbContext, cachedData, page, searchAll)); }
/// <summary> /// 创建 <see cref="PointLevel"/> /// </summary> /// <param name="currentUserId">当前登录用户 ID</param> /// <param name="pointIdCode">据点识别码</param> /// <param name="targetPage">要获取的页面</param> /// <param name="dbContext"><see cref="KeylolDbContext"/></param> /// <param name="cachedData"><see cref="CachedDataProvider"/></param> /// <returns></returns> /// <exception cref="ArgumentOutOfRangeException"><paramref name="targetPage"/> 超出范围</exception> public static async Task <PointLevel> CreateAsync(string currentUserId, string pointIdCode, EntrancePage targetPage, KeylolDbContext dbContext, CachedDataProvider cachedData) { var point = await dbContext.Points.Where(p => p.IdCode == pointIdCode).SingleOrDefaultAsync(); if (point == null) { return(new PointLevel()); } var result = new PointLevel { BasicInfo = await Shared.PointBasicInfo.CreateAsync(currentUserId, point, dbContext, cachedData) }; switch (targetPage) { case EntrancePage.Auto: // if (await cachedData.Subscriptions // .IsSubscribedAsync(currentUserId, point.Id, SubscriptionTargetType.Point)) // { // result.Current = EntrancePage.Timeline; // } // else // { // result.Frontpage = await FrontpagePage.CreateAsync(point, currentUserId, dbContext, cachedData); // result.Current = EntrancePage.Frontpage; // } result.Frontpage = await FrontpagePage.CreateAsync(point, currentUserId, dbContext, cachedData); result.Current = EntrancePage.Frontpage; break; case EntrancePage.Frontpage: result.Frontpage = await FrontpagePage.CreateAsync(point, currentUserId, dbContext, cachedData); break; case EntrancePage.Intel: result.Intel = await IntelPage.CreateAsync(point, currentUserId, dbContext, cachedData); break; case EntrancePage.Product: result.Product = await ProductPage.CreateAsync(point, currentUserId, dbContext, cachedData); break; case EntrancePage.Timeline: result.Timeline = await TimelinePage.CreateAsync(point.Id, currentUserId, dbContext, cachedData); break; case EntrancePage.EditInfo: if (await StateTreeHelper.CanAccessAsync <PointLevel>(nameof(Edit))) { result.Edit = new EditLevel { Info = await InfoPage.CreateAsync(point, dbContext) } } ; break; case EntrancePage.EditStyle: if (await StateTreeHelper.CanAccessAsync <PointLevel>(nameof(Edit))) { result.Edit = new EditLevel { Style = StylePage.Create(point) } } ; break; default: throw new ArgumentOutOfRangeException(nameof(targetPage), targetPage, null); } return(result); }
/// <summary> /// 创建 <see cref="PointResultList"/> /// </summary> /// <param name="currentUserId">当前用户 ID</param> /// <param name="keyword">搜索关键字</param> /// <param name="dbContext"><see cref="KeylolDbContext"/></param> /// <param name="cachedData"><see cref="CachedDataProvider"/></param> /// <param name="page">分页页码</param> /// <param name="searchAll">是否全部查询</param> public static async Task <PointResultList> CreateAsync(string currentUserId, string keyword, [Injected] KeylolDbContext dbContext, [Injected] CachedDataProvider cachedData, int page, bool searchAll = true) { var take = searchAll ? 10 : 5; var skip = (page - 1) * take; keyword = keyword.Replace('"', ' ').Replace('*', ' ').Replace('\'', ' '); var searchResult = await dbContext.Database.SqlQuery <PointResult>(@"SELECT *, (SELECT COUNT(1) FROM Articles WHERE TargetPointId = t4.Id) AS ArticleCount, (SELECT COUNT(1) FROM Activities WHERE TargetPointId = t4.Id) AS ActivityCount FROM (SELECT * FROM [dbo].[Points] AS [t1] INNER JOIN (SELECT [t2].[KEY], MAX([t2].[RANK]) AS RANK FROM (SELECT * FROM CONTAINSTABLE([dbo].[Points], ([EnglishName], [EnglishAliases]), {0}) UNION ALL SELECT * FROM CONTAINSTABLE([dbo].[Points], ([ChineseName], [ChineseAliases]), {0})) AS [t2] GROUP BY [t2].[KEY]) AS [t3] ON [t1].[Sid] = [t3].[KEY]) AS [t4] ORDER BY [t4].[RANK] DESC, [ArticleCount] DESC OFFSET {1} ROWS FETCH NEXT {2} ROWS ONLY", $"\"{keyword}\" OR \"{keyword}*\"", skip, take).ToListAsync(); var result = new PointResultList(searchResult.Count); foreach (var p in searchResult) { result.Add(new PointResult { Id = searchAll ? p.Id : null, IdCode = p.IdCode, ChineseName = p.ChineseName, EnglishName = p.EnglishName, AvatarImage = p.AvatarImage, SubscriberCount = searchAll ? await cachedData.Subscriptions.GetSubscriberCountAsync(p.Id, SubscriptionTargetType.Point) : (long?)null, ArticleCount = searchAll ? p.ArticleCount : null, ActivityCount = searchAll ? p.ActivityCount : null, Subscribed = searchAll && !string.IsNullOrWhiteSpace(currentUserId) ? await cachedData.Subscriptions.IsSubscribedAsync(currentUserId, p.Id, SubscriptionTargetType.Point) : (bool?)null, InLibrary = p.SteamAppId == null || string.IsNullOrWhiteSpace(currentUserId) ? (bool?)null : await cachedData.Users.IsSteamAppInLibraryAsync(currentUserId, p.SteamAppId.Value) }); } return(result); }
/// <summary> /// 创建 <see cref="AddictedUserList"/> /// </summary> /// <param name="currentUserId">当前登录用户 ID</param> /// <param name="steamAppId">Steam App ID</param> /// <param name="page">分页页码</param> /// <param name="dbContext"><see cref="KeylolDbContext"/></param> /// <param name="cachedData"><see cref="CachedDataProvider"/></param> /// <returns><see cref="AddictedUserList"/></returns> public static async Task <AddictedUserList> CreateAsync(string currentUserId, int?steamAppId, int page, KeylolDbContext dbContext, CachedDataProvider cachedData) { var queryResult = await(from record in dbContext.UserSteamGameRecords where record.SteamAppId == steamAppId && record.UserId != currentUserId let isFriend = dbContext.Subscriptions.Any( s => s.SubscriberId == currentUserId && s.TargetId == record.UserId && s.TargetType == SubscriptionTargetType.User) && dbContext.Subscriptions.Any( s => s.SubscriberId == record.UserId && s.TargetId == currentUserId && s.TargetType == SubscriptionTargetType.User) orderby isFriend descending, record.TotalPlayedTime descending select new { record.User.Id, record.User.HeaderImage, record.User.IdCode, record.User.AvatarImage, record.User.UserName, record.TotalPlayedTime, IsFriend = isFriend }).TakePage(page, 8).ToListAsync(); var result = new AddictedUserList(); foreach (var u in queryResult) { result.Add(new AddictedUser { Id = u.Id, HeaderImage = u.HeaderImage, IdCode = u.IdCode, AvatarImage = u.AvatarImage, UserName = u.UserName, TotalPlayedTime = u.TotalPlayedTime, IsFriend = string.IsNullOrWhiteSpace(currentUserId) ? (bool?)null : u.IsFriend, Subscribed = string.IsNullOrWhiteSpace(currentUserId) ? (bool?)null : await cachedData.Subscriptions.IsSubscribedAsync(currentUserId, u.Id, SubscriptionTargetType.User) }); } return(result); }
/// <summary> /// 获取指定据点的文集 /// </summary> /// <param name="pointId">据点 ID</param> /// <param name="page">分页页码</param> /// <param name="dbContext"><see cref="KeylolDbContext"/></param> /// <param name="cachedData"><see cref="CachedDataProvider"/></param> /// <returns></returns> public static async Task <SelectedArticleList> Get(string pointId, int page, [Injected] KeylolDbContext dbContext, [Injected] CachedDataProvider cachedData) { return(await CreateAsync(pointId, page, 12, StateTreeHelper.GetCurrentUserId(), dbContext, cachedData)); }
/// <summary> /// 创建 <see cref="TagPointList"/> /// </summary> /// <param name="pointId">据点 ID</param> /// <param name="currentUserId">当前登录用户 ID</param> /// <param name="dbContext"><see cref="KeylolDbContext"/></param> /// <param name="cachedData"><see cref="CachedDataProvider"/></param> /// <returns><see cref="TagPointList"/></returns> public static async Task <TagPointList> CreateAsync(string pointId, string currentUserId, KeylolDbContext dbContext, CachedDataProvider cachedData) { var queryResult = await(from relationship in dbContext.PointRelationships where relationship.SourcePointId == pointId && relationship.Relationship == PointRelationshipType.Tag select new { relationship.TargetPoint.Id, relationship.TargetPoint.IdCode, relationship.TargetPoint.AvatarImage, relationship.TargetPoint.ChineseName, relationship.TargetPoint.EnglishName, GameCount = dbContext.PointRelationships .Where(r => r.TargetPointId == relationship.TargetPointId) .GroupBy(r => r.SourcePointId) .Count() }).ToListAsync(); var result = new TagPointList(queryResult.Count); foreach (var p in queryResult) { result.Add(new TagPoint { Id = p.Id, IdCode = p.IdCode, AvatarImage = p.AvatarImage, ChineseName = p.ChineseName, EnglishName = p.EnglishName, GameCount = p.GameCount, Subscribed = string.IsNullOrWhiteSpace(currentUserId) ? (bool?)null : await cachedData.Subscriptions.IsSubscribedAsync(currentUserId, p.Id, SubscriptionTargetType.Point) }); } return(result); }
/// <summary> /// 创建 <see cref="TimelinePage"/> /// </summary> /// <param name="userId">用户 ID</param> /// <param name="currentUserId">当前登录用户 ID</param> /// <param name="dbContext"><see cref="KeylolDbContext"/></param> /// <param name="cachedData"><see cref="CachedDataProvider"/></param> /// <returns><see cref="TimelinePage"/></returns> public static async Task <TimelinePage> CreateAsync(string userId, string currentUserId, KeylolDbContext dbContext, CachedDataProvider cachedData) { return(new TimelinePage { Cards = await TimelineCardList.CreateAsync(UserStream.Name(userId), currentUserId, 18, true, dbContext, cachedData) }); }
/// <summary> /// 创建 <see cref="OnSalePointList"/> /// </summary> /// <param name="currentUserId">当前登录用户 ID</param> /// <param name="page">分页页码</param> /// <param name="returnPageCount">是否返回总页数</param> /// <param name="returnFirstHeaderImage">是否返回第一个据点头部图</param> /// <param name="dbContext"><see cref="KeylolDbContext"/></param> /// <param name="cachedData"><see cref="CachedDataProvider"/></param> /// <returns>Item1 表示 <see cref="OnSalePointList"/>,Item2 表示总页数,Item3 表示第一个据点头部图,Item4 表示第二个据点头部图</returns> public static async Task <Tuple <OnSalePointList, int, string, string> > CreateAsync(string currentUserId, int page, bool returnPageCount, bool returnFirstHeaderImage, KeylolDbContext dbContext, CachedDataProvider cachedData) { SteamCrawlerProvider.UpdateOnSalePoints(); var conditionQuery = from feed in dbContext.Feeds where feed.StreamName == OnSalePointStream.Name join point in dbContext.Points on feed.Entry equals point.Id orderby feed.Id descending select point; var queryResult = await conditionQuery.Select(p => new { Count = returnPageCount ? conditionQuery.Count() : 1, HeaderImage = returnFirstHeaderImage ? p.HeaderImage : null, p.Id, p.IdCode, p.ThumbnailImage, p.ChineseName, p.EnglishName, p.SteamPrice, p.SteamDiscountedPrice, p.SteamAppId }).TakePage(page, RecordsPerPage).ToListAsync(); var result = new OnSalePointList(queryResult.Count); foreach (var p in queryResult) { result.Add(new PointBasicInfo { IdCode = p.IdCode, ThumbnailImage = p.ThumbnailImage, ChineseName = p.ChineseName, EnglishName = p.EnglishName, AverageRating = (await cachedData.Points.GetRatingsAsync(p.Id)).AverageRating, SteamPrice = p.SteamPrice, SteamDiscountedPrice = p.SteamDiscountedPrice, InLibrary = string.IsNullOrWhiteSpace(currentUserId) || p.SteamAppId == null ? (bool?)null : await cachedData.Users.IsSteamAppInLibraryAsync(currentUserId, p.SteamAppId.Value) }); } var pointWithHeaders = queryResult.Where(r => !string.IsNullOrWhiteSpace(r.HeaderImage)).ToList(); var firstRecord = pointWithHeaders.FirstOrDefault(); var secondRecord = pointWithHeaders.Skip(1).FirstOrDefault(); return(new Tuple <OnSalePointList, int, string, string>( result, (int)Math.Ceiling(firstRecord?.Count / (double)RecordsPerPage ?? 1), firstRecord?.HeaderImage, secondRecord?.HeaderImage)); }
/// <summary> /// 创建 <see cref="ProductPointList"/> /// </summary> /// <param name="currentUserId">当前登录用户 ID</param> /// <param name="pointId">据点 ID</param> /// <param name="dbContext"><see cref="KeylolDbContext"/></param> /// <param name="cachedData"><see cref="CachedDataProvider"/></param> /// <returns><see cref="ProductPointList"/></returns> public static async Task <ProductPointList> CreateAsync(string currentUserId, string pointId, KeylolDbContext dbContext, CachedDataProvider cachedData) { var queryResult = await(from relationship in dbContext.PointRelationships where relationship.TargetPointId == pointId group relationship.Relationship by new { relationship.SourcePoint.Sid, relationship.SourcePoint.Id, relationship.SourcePoint.IdCode, relationship.SourcePoint.AvatarImage, relationship.SourcePoint.ChineseName, relationship.SourcePoint.EnglishName, relationship.SourcePoint.TitleCoverImage, relationship.SourcePoint.SteamAppId } into g orderby g.Key.Sid descending select g) .ToListAsync(); var result = new ProductPointList(queryResult.Count); foreach (var g in queryResult) { result.Add(new ProductPoint { Id = g.Key.Id, IdCode = g.Key.IdCode, AvatarImage = g.Key.AvatarImage, ChineseName = g.Key.ChineseName, EnglishName = g.Key.EnglishName, TitleCoverImage = g.Key.TitleCoverImage, AverageRating = (await cachedData.Points.GetRatingsAsync(g.Key.Id)).AverageRating, Subscribed = string.IsNullOrWhiteSpace(currentUserId) ? (bool?)null : await cachedData.Subscriptions.IsSubscribedAsync(currentUserId, g.Key.Id, SubscriptionTargetType.Point), InLibrary = string.IsNullOrWhiteSpace(currentUserId) || g.Key.SteamAppId == null ? (bool?)null : await cachedData.Users.IsSteamAppInLibraryAsync(currentUserId, g.Key.SteamAppId.Value), Roles = g.ToList() }); } return(result); }
/// <summary> /// 通过关键字搜索文章列表 /// </summary> /// <param name="keyword">搜索关键字</param> /// <param name="dbContext"><see cref="KeylolDbContext"/></param> /// <param name="cachedData"><see cref="CachedDataProvider"/></param> /// <param name="page">分页页码</param> /// <param name="searchAll">是否查询全部</param> public static async Task <ArticleResultList> Get(string keyword, [Injected] KeylolDbContext dbContext, [Injected] CachedDataProvider cachedData, int page, bool searchAll = true) { return(await CreateAsync(keyword, dbContext, cachedData, page, searchAll)); }
/// <summary> /// 创建 <see cref="RecentPointList"/> /// </summary> /// <param name="currentUserId">当前登录用户 ID</param> /// <param name="page">分页页码</param> /// <param name="returnPageCount">是否返回总页数</param> /// <param name="dbContext"><see cref="KeylolDbContext"/></param> /// <param name="cachedData"><see cref="CachedDataProvider"/></param> /// <returns>Item1 表示 <see cref="RecentPointList"/>,Item2 表示总页数</returns> public static async Task <Tuple <RecentPointList, int> > CreateAsync(string currentUserId, int page, bool returnPageCount, KeylolDbContext dbContext, CachedDataProvider cachedData) { var conditionQuery = from point in dbContext.Points where point.Type == PointType.Game || point.Type == PointType.Hardware orderby point.LastActivityTime descending select point; var queryResult = await conditionQuery.Select(p => new { Count = returnPageCount ? conditionQuery.Count() : 1, p.Id, p.Type, p.IdCode, p.AvatarImage, p.ChineseName, p.EnglishName, p.TitleCoverImage, p.SteamAppId }).TakePage(page, RecordsPerPage).ToListAsync(); var result = new RecentPointList(queryResult.Count); foreach (var p in queryResult) { result.Add(new PointBasicInfo { Id = p.Id, Type = p.Type, IdCode = p.IdCode, AvatarImage = p.AvatarImage, ChineseName = p.ChineseName, EnglishName = p.EnglishName, TitleCoverImage = p.TitleCoverImage, AverageRating = (await cachedData.Points.GetRatingsAsync(p.Id)).AverageRating, Subscribed = string.IsNullOrWhiteSpace(currentUserId) ? (bool?)null : await cachedData.Subscriptions.IsSubscribedAsync(currentUserId, p.Id, SubscriptionTargetType.Point), InLibrary = string.IsNullOrWhiteSpace(currentUserId) || p.SteamAppId == null ? (bool?)null : await cachedData.Users.IsSteamAppInLibraryAsync(currentUserId, p.SteamAppId.Value) }); } var firstRecord = queryResult.FirstOrDefault(); return(new Tuple <RecentPointList, int>( result, (int)Math.Ceiling(firstRecord?.Count / (double)RecordsPerPage ?? 1))); }
/// <summary> /// 创建 <see cref="PointResultList"/> /// </summary> /// <param name="currentUserId">当前登录用户 ID</param> /// <param name="keyword">搜索关键字</param> /// <param name="dbContext"><see cref="KeylolDbContext"/></param> /// <param name="cachedData"><see cref="CachedDataProvider"/></param> /// <param name="searchAll">是否全部查询</param> public static async Task <PointPage> CreateAsync(string currentUserId, string keyword, [Injected] KeylolDbContext dbContext, [Injected] CachedDataProvider cachedData, bool searchAll = true) { return(new PointPage { Results = await PointResultList.CreateAsync(currentUserId, keyword, dbContext, cachedData, 1, searchAll) }); }
/// <summary> /// 获取文券上榜用户列表 /// </summary> /// <param name="page">分页页码</param> /// <param name="dbContext"><see cref="KeylolDbContext"/></param> /// <param name="cachedData"><see cref="CachedDataProvider"/></param> /// <returns><see cref="RankingUserList"/></returns> public static async Task <RankingUserList> Get(int page, [Injected] KeylolDbContext dbContext, [Injected] CachedDataProvider cachedData) { return(await CreateAsync(StateTreeHelper.GetCurrentUserId(), page, dbContext, cachedData)); }
/// <summary> /// 创建 <see cref="SpotlightPointList"/> /// </summary> /// <param name="currentUserId">当前登录用户 ID</param> /// <param name="page">分页页码</param> /// <param name="recordPerPage">每页个数</param> /// <param name="dbContext"><see cref="KeylolDbContext"/></param> /// <param name="cachedData"><see cref="CachedDataProvider"/></param> /// <returns><see cref="SpotlightPointList"/></returns> public static async Task <SpotlightPointList> CreateAsync(string currentUserId, int page, int recordPerPage, KeylolDbContext dbContext, CachedDataProvider cachedData) { var queryResult = await(from feed in dbContext.Feeds where feed.StreamName == SpotlightPointStream.Name join point in dbContext.Points on feed.Entry equals point.Id orderby feed.Id descending select new { FeedId = feed.Id, point.Id, point.Type, point.IdCode, point.AvatarImage, point.EnglishName, point.ChineseName, point.SteamAppId, point.SteamPrice, point.SteamDiscountedPrice, point.SonkwoProductId, point.SonkwoPrice, point.SonkwoDiscountedPrice, point.UplayLink, point.UplayPrice, point.XboxLink, point.XboxPrice, point.PlayStationLink, point.PlayStationPrice, point.OriginLink, point.OriginPrice, point.WindowsStoreLink, point.WindowsStorePrice, point.AppStoreLink, point.AppStorePrice, point.GooglePlayLink, point.GooglePlayPrice, point.GogLink, point.GogPrice, point.BattleNetLink, point.BattleNetPrice }).TakePage(page, recordPerPage).ToListAsync(); var result = new SpotlightPointList(queryResult.Count); foreach (var p in queryResult) { result.Add(new PointBasicInfo { FeedId = p.FeedId, Id = p.Id, Type = p.Type, IdCode = p.IdCode, AvatarImage = p.AvatarImage, EnglishName = p.EnglishName, ChineseName = p.ChineseName, AverageRating = (await cachedData.Points.GetRatingsAsync(p.Id)).AverageRating, SteamAppId = p.SteamAppId, SteamPrice = p.SteamPrice, SteamDiscountedPrice = p.SteamDiscountedPrice, SonkwoProductId = p.SonkwoProductId, SonkwoPrice = p.SonkwoPrice, SonkwoDiscountedPrice = p.SonkwoDiscountedPrice, UplayLink = p.UplayLink, UplayPrice = p.UplayPrice, XboxLink = p.XboxLink, XboxPrice = p.XboxPrice, PlayStationLink = p.PlayStationLink, PlayStationPrice = p.PlayStationPrice, OriginLink = p.OriginLink, OriginPrice = p.OriginPrice, WindowsStoreLink = p.WindowsStoreLink, WindowsStorePrice = p.WindowsStorePrice, AppStoreLink = p.AppStoreLink, AppStorePrice = p.AppStorePrice, GooglePlayLink = p.GooglePlayLink, GooglePlayPrice = p.GooglePlayPrice, GogLink = p.GogLink, GogPrice = p.GogPrice, BattleNetLink = p.BattleNetLink, BattleNetPrice = p.BattleNetPrice, Subscribed = string.IsNullOrWhiteSpace(currentUserId) ? (bool?)null : await cachedData.Subscriptions.IsSubscribedAsync(currentUserId, p.Id, SubscriptionTargetType.Point), InLibrary = string.IsNullOrWhiteSpace(currentUserId) || p.SteamAppId == null ? (bool?)null : await cachedData.Users.IsSteamAppInLibraryAsync(currentUserId, p.SteamAppId.Value) }); } return(result); }
/// <summary> /// 创建 <see cref="RecentPlayedPointList"/> /// </summary> /// <param name="currentUserId">当前登录用户 ID</param> /// <param name="dbContext"><see cref="KeylolDbContext"/></param> /// <param name="cachedData"><see cref="CachedDataProvider"/></param> /// <returns>Item1 表示 <see cref="RecentPlayedPointList"/>,Item2 表示第一个据点头部图</returns> public static async Task <Tuple <RecentPlayedPointList, string> > CreateAsync(string currentUserId, KeylolDbContext dbContext, CachedDataProvider cachedData) { var queryResult = await(string.IsNullOrWhiteSpace(currentUserId) ? from point in dbContext.Points where DbFunctions.DiffMonths(point.CreateTime, DateTime.Now) <= 3 && (point.Type == PointType.Game || point.Type == PointType.Hardware) orderby dbContext.Subscriptions .Count(s => s.TargetId == point.Id && s.TargetType == SubscriptionTargetType.Point) descending, point.LastActivityTime descending select new { point.Id, point.IdCode, point.HeaderImage, point.ThumbnailImage, point.ChineseName, point.EnglishName, TwoWeekPlayedTime = (double?)null } : from record in dbContext.UserSteamGameRecords where record.UserId == currentUserId join point in dbContext.Points on record.SteamAppId equals point.SteamAppId where !dbContext.Subscriptions.Any(s => s.SubscriberId == currentUserId && s.TargetId == point.Id && s.TargetType == SubscriptionTargetType.Point) orderby record.TwoWeekPlayedTime descending, record.LastPlayTime descending select new { point.Id, point.IdCode, point.HeaderImage, point.ThumbnailImage, point.ChineseName, point.EnglishName, TwoWeekPlayedTime = (double?)record.TwoWeekPlayedTime } ).Take(5).ToListAsync(); var result = new RecentPlayedPointList(queryResult.Count); foreach (var p in queryResult) { result.Add(new RecentPlayedPoint { Id = p.Id, IdCode = p.IdCode, ThumbnailImage = p.ThumbnailImage, ChineseName = p.ChineseName, EnglishName = p.EnglishName, AverageRating = (await cachedData.Points.GetRatingsAsync(p.Id)).AverageRating, TwoWeekPlayedTime = p.TwoWeekPlayedTime }); } var firstRecord = queryResult.FirstOrDefault(p => !string.IsNullOrWhiteSpace(p.HeaderImage)); return(new Tuple <RecentPlayedPointList, string>( result, firstRecord?.HeaderImage)); }
/// <summary> /// 创建 <see cref="BriefReviewList"/> /// </summary> /// <param name="point">据点对象</param> /// <param name="currentUserId">当前登录用户 ID</param> /// <param name="page">分页页码</param> /// <param name="returnCount">是否返回总数</param> /// <param name="dbContext"><see cref="KeylolDbContext"/></param> /// <param name="cachedData"><see cref="CachedDataProvider"/></param> /// <returns>Item1 表示 <see cref="BriefReviewList"/>,Item2 表示总数,Item3 表示总页数</returns> public static async Task <Tuple <BriefReviewList, int, int> > CreateAsync(Models.Point point, string currentUserId, int page, bool returnCount, KeylolDbContext dbContext, CachedDataProvider cachedData) { var queryResult = await(from activity in dbContext.Activities where activity.TargetPointId == point.Id && activity.Rating != null && activity.Archived == ArchivedState.None && activity.Rejected == false orderby dbContext.Likes .Count(l => l.TargetId == activity.Id && l.TargetType == LikeTargetType.Activity) descending select new { Count = returnCount ? dbContext.Activities.Count( a => a.TargetPointId == point.Id && a.Rating != null && a.Archived == ArchivedState.None) : 1, activity.Id, activity.AuthorId, AuthorIdCode = activity.Author.IdCode, AuthorAvatarImage = activity.Author.AvatarImage, AuthorUserName = activity.Author.UserName, activity.SidForAuthor, activity.Rating, activity.Content }).TakePage(page, RecordsPerPage).ToListAsync(); var result = new BriefReviewList(queryResult.Count); foreach (var a in queryResult) { result.Add(new BriefReview { Id = a.Id, AuthorIdCode = a.AuthorIdCode, AuthorAvatarImage = a.AuthorAvatarImage, AuthorUserName = a.AuthorUserName, AuthorPlayedTime = point.SteamAppId == null ? null : (await dbContext.UserSteamGameRecords .Where(r => r.UserId == a.AuthorId && r.SteamAppId == point.SteamAppId) .SingleOrDefaultAsync())?.TotalPlayedTime, SidForAuthor = a.SidForAuthor, Rating = a.Rating, LikeCount = await cachedData.Likes.GetTargetLikeCountAsync(a.Id, LikeTargetType.Activity), Liked = string.IsNullOrWhiteSpace(currentUserId) ? (bool?)null : await cachedData.Likes.IsLikedAsync(currentUserId, a.Id, LikeTargetType.Activity), Content = a.Content }); } var firstRecord = queryResult.FirstOrDefault(); return(new Tuple <BriefReviewList, int, int>(result, firstRecord?.Count ?? 0, (int)Math.Ceiling(firstRecord?.Count / (double)RecordsPerPage ?? 1))); }