Esempio n. 1
0
        /// <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));
        }
Esempio n. 2
0
        /// <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
            });
        }
Esempio n. 3
0
        /// <summary>
        /// 创建 <see cref="IntelPage"/>
        /// </summary>
        /// <param name="point">据点对象</param>
        /// <param name="currentUserId">当前登录用户 ID</param>
        /// <param name="dbContext"><see cref="KeylolDbContext"/></param>
        /// <param name="cachedData"><see cref="CachedDataProvider"/></param>
        /// <returns><see cref="IntelPage"/></returns>
        public static async Task <IntelPage> CreateAsync(Models.Point point, string currentUserId,
                                                         KeylolDbContext dbContext, CachedDataProvider cachedData)
        {
            var intelPage = new IntelPage();

            if (point.Type == PointType.Game || point.Type == PointType.Hardware)
            {
                var vendorPointsGroup = await(from relationship in dbContext.PointRelationships
                                              where relationship.SourcePointId == point.Id &&
                                              (relationship.Relationship == PointRelationshipType.Developer ||
                                               relationship.Relationship == PointRelationshipType.Manufacturer ||
                                               relationship.Relationship == PointRelationshipType.Publisher ||
                                               relationship.Relationship == PointRelationshipType.Reseller)
                                              group relationship.Relationship by new
                {
                    relationship.TargetPoint.Id,
                    relationship.TargetPoint.IdCode,
                    relationship.TargetPoint.AvatarImage,
                    relationship.TargetPoint.ChineseName,
                    relationship.TargetPoint.EnglishName
                })
                                        .ToListAsync();
                intelPage.VendorPoints = vendorPointsGroup.Select(g => new VendorPoint
                {
                    IdCode      = g.Key.IdCode,
                    AvatarImage = g.Key.AvatarImage,
                    ChineseName = g.Key.ChineseName,
                    EnglishName = g.Key.EnglishName,
                    Roles       = string.Join("、", g.Select(r =>
                    {
                        switch (r)
                        {
                        case PointRelationshipType.Developer:
                            return("开发厂");

                        case PointRelationshipType.Publisher:
                            return("发行商");

                        case PointRelationshipType.Manufacturer:
                            return("制造厂");

                        case PointRelationshipType.Reseller:
                            return("代理商");

                        default:
                            return(r.ToString());
                        }
                    }))
                }).ToList();
                var vendorIds = vendorPointsGroup.Select(g => g.Key.Id).ToList();
                var vendorPointStaffQueryResult = await(from staff in dbContext.PointStaff
                                                        where vendorIds.Contains(staff.PointId)
                                                        select new
                {
                    staff.Staff.Id,
                    staff.Staff.HeaderImage,
                    staff.Staff.IdCode,
                    staff.Staff.AvatarImage,
                    staff.Staff.UserName,
                    PointChineseName = staff.Point.ChineseName,
                    PointEnglishName = staff.Point.EnglishName
                }).ToListAsync();
                intelPage.VenderPointStaff = new List <VendorPointStaff>(vendorPointStaffQueryResult.Count);
                foreach (var u in vendorPointStaffQueryResult)
                {
                    intelPage.VenderPointStaff.Add(new VendorPointStaff
                    {
                        Id               = u.Id,
                        HeaderImage      = u.HeaderImage,
                        IdCode           = u.IdCode,
                        AvatarImage      = u.AvatarImage,
                        UserName         = u.UserName,
                        PointChineseName = u.PointChineseName,
                        PointEnglishName = u.PointEnglishName,
                        IsFriend         = string.IsNullOrWhiteSpace(currentUserId)
                            ? (bool?)null
                            : await cachedData.Users.IsFriendAsync(currentUserId, u.Id),
                        Subscribed = string.IsNullOrWhiteSpace(currentUserId)
                            ? (bool?)null
                            : await cachedData.Subscriptions.IsSubscribedAsync(currentUserId, u.Id,
                                                                               SubscriptionTargetType.User)
                    });
                }
                intelPage.PointStaff = await PointStaffList.CreateAsync(point.Id, currentUserId, dbContext, cachedData);

                intelPage.GenrePoints = await GenrePointList.CreateAsync(point.Id, currentUserId, dbContext, cachedData);

                intelPage.TagPoints = await TagPointList.CreateAsync(point.Id, currentUserId, dbContext, cachedData);
            }
            if (point.Type == PointType.Game)
            {
                intelPage.Platforms = await(from relationship in dbContext.PointRelationships
                                            where relationship.SourcePointId == point.Id &&
                                            relationship.Relationship == PointRelationshipType.Platform
                                            orderby relationship.Sid descending
                                            select relationship.TargetPoint.IdCode)
                                      .ToListAsync();

                #region 特性属性

                intelPage.MultiPlayer         = point.MultiPlayer ? true : (bool?)null;
                intelPage.SinglePlayer        = point.SinglePlayer ? true : (bool?)null;
                intelPage.Coop                = point.Coop ? true : (bool?)null;
                intelPage.CaptionsAvailable   = point.CaptionsAvailable ? true : (bool?)null;
                intelPage.CommentaryAvailable = point.CommentaryAvailable ? true : (bool?)null;
                intelPage.IncludeLevelEditor  = point.IncludeLevelEditor ? true : (bool?)null;
                intelPage.Achievements        = point.Achievements ? true : (bool?)null;
                intelPage.Cloud               = point.Cloud ? true : (bool?)null;
                intelPage.LocalCoop           = point.LocalCoop ? true : (bool?)null;
                intelPage.SteamTradingCards   = point.SteamTradingCards ? true : (bool?)null;
                intelPage.SteamWorkshop       = point.SteamWorkshop ? true : (bool?)null;
                intelPage.InAppPurchases      = point.InAppPurchases ? true : (bool?)null;

                #endregion

                intelPage.ChineseAvailability = Helpers.SafeDeserialize <ChineseAvailability>(point.ChineseAvailability);

                SteamCrawlerProvider.UpdateSteamSpyData(point.Id);

                intelPage.PublishDate     = point.PublishDate;
                intelPage.PointCreateTime = point.CreateTime;
                intelPage.PreOrderDate    = point.PreOrderDate;
                intelPage.ReleaseDate     = point.ReleaseDate;

                if (point.SteamAppId != null)
                {
                    intelPage.OwnerCount                 = point.OwnerCount;
                    intelPage.OwnerCountVariance         = point.OwnerCountVariance;
                    intelPage.TotalPlayerCount           = point.TotalPlayerCount;
                    intelPage.TotalPlayerCountVariance   = point.TotalPlayerCountVariance;
                    intelPage.TwoWeekPlayerCount         = point.TwoWeekPlayerCount;
                    intelPage.TwoWeekPlayerCountVariance = point.TwoWeekPlayerCountVariance;
                    intelPage.Ccu = point.Ccu;
                    intelPage.AveragePlayedTime        = point.AveragePlayedTime;
                    intelPage.TwoWeekAveragePlayedTime = point.TwoWeekAveragePlayedTime;
                    intelPage.MedianPlayedTime         = point.MedianPlayedTime;
                }
            }
            return(intelPage);
        }
        private static void AutoSubscribe(string userId)
        {
            Task.Run(async() =>
            {
                using (var dbContext = new KeylolDbContext())
                    using (var userManager = new KeylolUserManager(dbContext))
                    {
                        var redis      = Global.Container.GetInstance <RedisProvider>();
                        var cachedData = new CachedDataProvider(dbContext, redis);
                        if (await SteamCrawlerProvider.UpdateUserSteamGameRecordsAsync(userId, dbContext, userManager,
                                                                                       redis, cachedData))
                        {
                            var games = await(from record in dbContext.UserSteamGameRecords
                                              where record.UserId == userId
                                              join point in dbContext.Points on record.SteamAppId equals point.SteamAppId
                                              orderby record.TotalPlayedTime
                                              select new
                            {
                                PointId = point.Id,
                                record.LastPlayTime
                            }).ToListAsync();

                            var gamePointIds         = games.Select(g => g.PointId).ToList();
                            var mostPlayedPointIds   = gamePointIds.Take(3).ToList();
                            var recentPlayedPointIds = games.Where(g => !mostPlayedPointIds.Contains(g.PointId))
                                                       .OrderByDescending(g => g.LastPlayTime)
                                                       .Select(g => g.PointId).Take(3).ToList();
                            var categoryPointIds = await(from relationship in dbContext.PointRelationships
                                                         where gamePointIds.Contains(relationship.SourcePointId) &&
                                                         (relationship.Relationship == PointRelationshipType.Tag ||
                                                          relationship.Relationship == PointRelationshipType.Series)
                                                         group 1 by relationship.TargetPointId
                                                         into g
                                                         orderby g.Count() descending
                                                         select g.Key).Take(3).ToListAsync();

                            var pointIds = mostPlayedPointIds.Concat(recentPlayedPointIds).Concat(categoryPointIds).ToList();
                            foreach (var pointId in pointIds)
                            {
                                await cachedData.Subscriptions.AddAsync(userId, pointId, SubscriptionTargetType.Point);
                            }

                            var pointFeedStreams = pointIds.Select(PointStream.Name).ToList();
                            var feeds            = await(from feed in dbContext.Feeds
                                                         where pointFeedStreams.Contains(feed.StreamName)
                                                         orderby feed.Id descending
                                                         group new { feed.Id, feed.StreamName } by new { feed.Entry, feed.EntryType }
                                                         into g
                                                         orderby g.Max(f => f.Id)
                                                         select g).Take(120).ToListAsync();
                            var subscriptionStream = SubscriptionStream.Name(userId);
                            foreach (var feed in feeds)
                            {
                                var properties = new SubscriptionStream.FeedProperties
                                {
                                    Reasons = feed.Select(f => f.StreamName.Split(':')[1]).Distinct()
                                              .Select(id => $"point:{id}").ToList()
                                };
                                dbContext.Feeds.Add(new Models.Feed
                                {
                                    StreamName = subscriptionStream,
                                    Entry      = feed.Key.Entry,
                                    EntryType  = feed.Key.EntryType,
                                    Properties = JsonConvert.SerializeObject(properties)
                                });
                            }
                            await dbContext.SaveChangesAsync();
                        }
                    }
            });
        }
        /// <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);
        }