public async Task <IHttpActionResult> GetBySubscription(string articleTypeFilter = null,
                                                                int shortReviewFilter    = 1, int beforeSn = int.MaxValue, int take = 30)
        {
            var userId = User.Identity.GetUserId();

            if (take > 50)
            {
                take = 50;
            }
            var userQuery          = _dbContext.Users.AsNoTracking().Where(u => u.Id == userId);
            var profilePointsQuery = userQuery.SelectMany(u => u.SubscribedPoints.OfType <ProfilePoint>());

            var shortReviewFilter1 = (shortReviewFilter & 1) != 0;
            var shortReviewFilter2 = (shortReviewFilter & (1 << 1)) != 0;
            var shortReviewFilter3 = (shortReviewFilter & (1 << 2)) != 0;
            var articleQuery       =
                userQuery.SelectMany(u => u.SubscribedPoints.OfType <Models.NormalPoint>())
                .SelectMany(p => p.Articles.Select(a => new { article = a, fromPoint = p }))
                .Where(e => e.article.SequenceNumber < beforeSn &&
                       e.article.Archived == ArchivedState.None && e.article.Rejected == false &&
                       (shortReviewFilter2 || e.article.Type != ArticleType.简评))
                .Select(e => new
            {
                e.article,
                e.fromPoint,
                reason      = ArticleDto.TimelineReasonType.Point,
                likedByUser = (KeylolUser)null
            })
                .Concat(profilePointsQuery.SelectMany(p => p.Articles)
                        .Where(a => a.SequenceNumber < beforeSn &&
                               a.Archived == ArchivedState.None && a.Rejected == false &&
                               (shortReviewFilter1 || a.Type != ArticleType.简评))
                        .Select(a => new
            {
                article     = a,
                fromPoint   = (Models.NormalPoint)null,
                reason      = ArticleDto.TimelineReasonType.Publish,
                likedByUser = (KeylolUser)null
            }))
                .Concat(profilePointsQuery.Select(p => p.User)
                        .SelectMany(u => u.Likes.OfType <ArticleLike>())
                        .Where(l => l.Article.SequenceNumber < beforeSn &&
                               l.Article.Archived == ArchivedState.None && l.Article.Rejected == false &&
                               (shortReviewFilter1 || l.Article.Type != ArticleType.简评))
                        .Select(l => new
            {
                article     = l.Article,
                fromPoint   = (Models.NormalPoint)null,
                reason      = ArticleDto.TimelineReasonType.Like,
                likedByUser = l.Operator
            }))
                .Concat(_dbContext.AutoSubscriptions.Where(s => s.UserId == userId)
                        .SelectMany(
                            s => s.NormalPoint.Articles.Select(a => new { article = a, fromPoint = s.NormalPoint }))
                        .Where(e =>
                               e.article.SequenceNumber < beforeSn &&
                               e.article.Archived == ArchivedState.None && e.article.Rejected == false &&
                               (shortReviewFilter3 || e.article.Type != ArticleType.简评))
                        .Select(e => new
            {
                e.article,
                e.fromPoint,
                reason      = ArticleDto.TimelineReasonType.Point,
                likedByUser = (KeylolUser)null
            }));

            if (articleTypeFilter != null)
            {
                var types = articleTypeFilter.Split(',').Select(s => s.Trim().ToEnum <ArticleType>()).ToList();
                if (shortReviewFilter != 0)
                {
                    types.Add(ArticleType.简评);
                }
                articleQuery = articleQuery.Where(PredicateBuilder.Contains(types, a => a.article.Type, new
                {
                    article     = (Models.Article)null,
                    fromPoint   = (Models.NormalPoint)null,
                    reason      = ArticleDto.TimelineReasonType.Like,
                    likedByUser = (KeylolUser)null
                }));
            }

            var articleEntries = await articleQuery.GroupBy(e => e.article)
                                 .OrderByDescending(g => g.Key.SequenceNumber).Take(() => take)
                                 .Select(g => new
            {
                article      = g.Key,
                likedByUsers = g.Where(e => e.reason == ArticleDto.TimelineReasonType.Like)
                               .Take(3)
                               .Select(e => e.likedByUser),
                fromPoints = g.Where(e => e.fromPoint != null).Select(e => e.fromPoint),
                reason     = g.Max(ee => ee.reason)
            })
                                 .Select(g => new
            {
                g.article,
                g.reason,
                g.likedByUsers,
                g.fromPoints,
                voteForPoint = g.article.VoteForPoint,
                author       = g.article.Principal.User,
                likeCount    = g.article.Likes.Count,
                commentCount = g.article.Comments.Count,
                type         = g.article.Type
            })
                                 .ToListAsync();

            return(Ok(articleEntries.Select(entry =>
            {
                var articleDto = new ArticleDto(entry.article, true, 256, true)
                {
                    TimelineReason = entry.reason,
                    LikeCount = entry.likeCount,
                    CommentCount = entry.commentCount,
                    TypeName = entry.type.ToString(),
                    Author = new UserDto(entry.author),
                    VoteForPoint = entry.voteForPoint == null ? null : new NormalPointDto(entry.voteForPoint, true)
                };
                if (string.IsNullOrWhiteSpace(entry.article.ThumbnailImage))
                {
                    articleDto.ThumbnailImage = entry.voteForPoint?.BackgroundImage;
                }
                if (entry.type != ArticleType.简评)
                {
                    articleDto.TruncateContent(128);
                }
                switch (entry.reason)
                {
                case ArticleDto.TimelineReasonType.Point:
                    if (!entry.fromPoints.Select(p => p.Id).Contains(entry.voteForPoint?.Id))
                    {
                        articleDto.AttachedPoints =
                            entry.fromPoints.Select(p => new NormalPointDto(p, true)).ToList();
                    }
                    break;

                case ArticleDto.TimelineReasonType.Like:
                    articleDto.LikeByUsers = entry.likedByUsers.Select(u => new UserDto(u)).ToList();
                    break;
                }
                return articleDto;
            }).ToList()));
        }
        public async Task <IHttpActionResult> GetListByNormalPointId(string normalPointId,
                                                                     NormalPointIdentityType idType, string articleTypeFilter = null, int beforeSn = int.MaxValue,
                                                                     int take = 30)
        {
            if (take > 50)
            {
                take = 50;
            }
            var articleQuery = _dbContext.Articles.AsNoTracking().Where(a => a.SequenceNumber < beforeSn &&
                                                                        a.Archived == ArchivedState.None &&
                                                                        a.Rejected == false);

            switch (idType)
            {
            case NormalPointIdentityType.Id:
                articleQuery = articleQuery.Where(a => a.AttachedPoints.Select(p => p.Id).Contains(normalPointId));
                break;

            case NormalPointIdentityType.IdCode:
                articleQuery =
                    articleQuery.Where(a => a.AttachedPoints.Select(p => p.IdCode).Contains(normalPointId));
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(idType), idType, null);
            }
            if (articleTypeFilter != null)
            {
                var types = articleTypeFilter.Split(',').Select(s => s.Trim().ToEnum <ArticleType>()).ToList();
                articleQuery =
                    articleQuery.Where(PredicateBuilder.Contains <Models.Article, ArticleType>(types, a => a.Type));
            }
            var articleEntries = await articleQuery.OrderByDescending(a => a.SequenceNumber).Take(() => take).Select(
                a => new
            {
                article      = a,
                likeCount    = a.Likes.Count,
                commentCount = a.Comments.Count,
                type         = a.Type,
                author       = a.Principal.User,
                voteForPoint = a.VoteForPoint
            }).ToListAsync();

            return(Ok(articleEntries.Select(entry =>
            {
                var articleDto = new ArticleDto(entry.article, true, 256, true)
                {
                    LikeCount = entry.likeCount,
                    CommentCount = entry.commentCount,
                    TypeName = entry.type.ToString(),
                    Author = new UserDto(entry.author),
                    VoteForPoint = entry.voteForPoint == null ? null : new NormalPointDto(entry.voteForPoint, true)
                };
                if (string.IsNullOrWhiteSpace(entry.article.ThumbnailImage))
                {
                    articleDto.ThumbnailImage = entry.voteForPoint?.BackgroundImage;
                }
                if (entry.type != ArticleType.简评)
                {
                    articleDto.TruncateContent(128);
                }
                return articleDto;
            })));
        }
        public async Task <IHttpActionResult> GetListOfLatest(bool titleOnly = true, string articleTypeFilter = null,
                                                              int beforeSn   = int.MaxValue, int take         = 30)
        {
            if (take > 50)
            {
                take = 50;
            }
            var articleQuery = _dbContext.Articles.AsNoTracking()
                               .Where(a => a.Archived == ArchivedState.None && a.Rejected == false && a.SequenceNumber < beforeSn);

            if (articleTypeFilter != null)
            {
                var types = articleTypeFilter.Split(',').Select(s => s.Trim().ToEnum <ArticleType>()).ToList();
                articleQuery =
                    articleQuery.Where(PredicateBuilder.Contains <Models.Article, ArticleType>(types, a => a.Type));
            }
            articleQuery = articleQuery.OrderByDescending(a => a.SequenceNumber).Take(() => take);
            if (titleOnly)
            {
                var articleEntries = await articleQuery.Select(a => new
                {
                    article      = a,
                    authorIdCode = a.Principal.User.IdCode
                }).ToListAsync();

                return(Ok(articleEntries.Select(e => new ArticleDto
                {
                    Id = e.article.Id,
                    PublishTime = e.article.PublishTime,
                    Title = e.article.Title,
                    AuthorIdCode = e.authorIdCode,
                    SequenceNumberForAuthor = e.article.SequenceNumberForAuthor
                })));
            }
            else
            {
                var articleEntries = await articleQuery.Select(a => new
                {
                    article        = a,
                    likeCount      = a.Likes.Count,
                    commentCount   = a.Comments.Count,
                    type           = a.Type,
                    author         = a.Principal.User,
                    voteForPoint   = a.VoteForPoint,
                    attachedPoints = a.AttachedPoints
                }).ToListAsync();

                return(Ok(articleEntries.Select(entry =>
                {
                    var articleDto = new ArticleDto(entry.article, true, 256, true)
                    {
                        LikeCount = entry.likeCount,
                        CommentCount = entry.commentCount,
                        TypeName = entry.type.ToString(),
                        Author = new UserDto(entry.author),
                        VoteForPoint = entry.voteForPoint == null ? null : new NormalPointDto(entry.voteForPoint, true)
                    };
                    if (string.IsNullOrWhiteSpace(entry.article.ThumbnailImage))
                    {
                        articleDto.ThumbnailImage = entry.voteForPoint?.BackgroundImage;
                    }
                    if (entry.type != ArticleType.简评)
                    {
                        articleDto.TruncateContent(128);
                        if (entry.type != ArticleType.评)
                        {
                            articleDto.AttachedPoints =
                                entry.attachedPoints.Select(p => new NormalPointDto(p, true)).ToList();
                        }
                    }
                    return articleDto;
                })));
            }
        }
Example #4
0
        public async Task <IHttpActionResult> GetListByUser(string userId, UserIdentityType idType,
                                                            string articleTypeFilter = null, int source = 1, int beforeSn = int.MaxValue, int take = 30)
        {
            IQueryable <KeylolUser> userQuery;

            switch (idType)
            {
            case UserIdentityType.Id:
                userQuery = _dbContext.Users.AsNoTracking().Where(u => u.Id == userId);
                break;

            case UserIdentityType.IdCode:
                userQuery = _dbContext.Users.AsNoTracking().Where(u => u.IdCode == userId);
                break;

            case UserIdentityType.UserName:
                userQuery = _dbContext.Users.AsNoTracking().Where(u => u.UserName == userId);
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(idType), idType, null);
            }

            if (take > 50)
            {
                take = 50;
            }
            var publishedQuery = userQuery.SelectMany(u => u.ProfilePoint.Articles)
                                 .Where(a => a.SequenceNumber < beforeSn && a.Archived == ArchivedState.None)
                                 .Select(a => new
            {
                article = a,
                reason  = ArticleDto.TimelineReasonType.Publish,
                author  = (KeylolUser)null
            });
            var likedQuery = userQuery.SelectMany(u => u.Likes.OfType <ArticleLike>())
                             .Where(l => l.Article.SequenceNumber < beforeSn && l.Article.Archived == ArchivedState.None)
                             .Select(l => new
            {
                article = l.Article,
                reason  = ArticleDto.TimelineReasonType.Like,
                author  = l.Article.Principal.User
            });
            var published    = (source & 1) != 0;
            var liked        = (source & 1 << 1) != 0;
            var articleQuery = publishedQuery;

            if (published)
            {
                if (liked)
                {
                    articleQuery = articleQuery.Concat(likedQuery);
                }
            }
            else
            {
                if (liked)
                {
                    articleQuery = likedQuery;
                }
                else
                {
                    return(Ok());
                }
            }
            if (articleTypeFilter != null)
            {
                var types = articleTypeFilter.Split(',').Select(s => s.Trim().ToEnum <ArticleType>()).ToList();
                articleQuery = articleQuery.Where(PredicateBuilder.Contains(types, a => a.article.Type, new
                {
                    article = (Models.Article)null,
                    reason  = ArticleDto.TimelineReasonType.Like,
                    author  = (KeylolUser)null
                }));
            }
            var articleEntries = await articleQuery.GroupBy(e => e.article)
                                 .OrderByDescending(g => g.Key.SequenceNumber).Take(() => take)
                                 .Select(g => new
            {
                article    = g.Key,
                candicates = g,
                reason     = g.Max(ee => ee.reason)
            })
                                 .Select(g => new
            {
                g.article,
                g.reason,
                g.candicates.FirstOrDefault(e => e.reason == g.reason).author,
                voteForPoint = g.article.VoteForPoint,
                likeCount    = g.article.Likes.Count,
                commentCount = g.article.Comments.Count,
                type         = g.article.Type
            })
                                 .ToListAsync();

            return(Ok(articleEntries.Select(entry =>
            {
                var articleDto = new ArticleDto(entry.article, true, 256, true)
                {
                    TimelineReason = entry.reason,
                    LikeCount = entry.likeCount,
                    CommentCount = entry.commentCount,
                    TypeName = entry.type.ToString(),
                    VoteForPoint = entry.voteForPoint == null ? null : new NormalPointDto(entry.voteForPoint, true)
                };
                if (string.IsNullOrWhiteSpace(entry.article.ThumbnailImage))
                {
                    articleDto.ThumbnailImage = entry.voteForPoint?.BackgroundImage;
                }
                if (entry.type != ArticleType.简评)
                {
                    articleDto.TruncateContent(128);
                }
                if (entry.reason != ArticleDto.TimelineReasonType.Publish)
                {
                    articleDto.Author = new UserDto(entry.author);
                }
                return articleDto;
            }).ToList()));
        }