From 03c9d4edc4e321db8c1b70ae621f77fa89664dfc Mon Sep 17 00:00:00 2001 From: crupest Date: Tue, 4 Feb 2020 18:02:39 +0800 Subject: Add get timeline list feature. --- Timeline/Controllers/PersonalTimelineController.cs | 4 +- Timeline/Controllers/TimelineController.cs | 31 ++++++++++++-- Timeline/Models/Http/ErrorResponse.cs | 15 +++++++ Timeline/Models/Http/TimelineCommon.cs | 35 +++++++--------- Timeline/Resources/Messages.Designer.cs | 9 ++++ Timeline/Resources/Messages.resx | 3 ++ Timeline/Services/TimelineService.cs | 48 ++++++++++++++++++++++ 7 files changed, 119 insertions(+), 26 deletions(-) (limited to 'Timeline') diff --git a/Timeline/Controllers/PersonalTimelineController.cs b/Timeline/Controllers/PersonalTimelineController.cs index b6c213d9..cef04a97 100644 --- a/Timeline/Controllers/PersonalTimelineController.cs +++ b/Timeline/Controllers/PersonalTimelineController.cs @@ -28,7 +28,7 @@ namespace Timeline.Controllers [HttpGet("users/{username}/timeline")] public async Task> TimelineGet([FromRoute][Username] string username) { - return (await _service.GetTimeline(username)).FillLinksForPersonalTimeline(Url); + return (await _service.GetTimeline(username)).FillLinks(Url); } [HttpGet("users/{username}/timeline/posts")] @@ -84,7 +84,7 @@ namespace Timeline.Controllers return StatusCode(StatusCodes.Status403Forbidden, ErrorResponse.Common.Forbid()); } await _service.ChangeProperty(username, body); - var timeline = (await _service.GetTimeline(username)).FillLinksForPersonalTimeline(Url); + var timeline = (await _service.GetTimeline(username)).FillLinks(Url); return Ok(timeline); } diff --git a/Timeline/Controllers/TimelineController.cs b/Timeline/Controllers/TimelineController.cs index a514ccd9..811b0426 100644 --- a/Timeline/Controllers/TimelineController.cs +++ b/Timeline/Controllers/TimelineController.cs @@ -17,18 +17,41 @@ namespace Timeline.Controllers { private readonly ILogger _logger; + private readonly IUserService _userService; private readonly ITimelineService _service; - public TimelineController(ILogger logger, ITimelineService service) + public TimelineController(ILogger logger, IUserService userService, ITimelineService service) { _logger = logger; + _userService = userService; _service = service; } + [HttpGet("timelines")] + public async Task>> TimelineList([FromQuery][Username] string? relate) + { + long? relatedUserId = null; + if (relate != null) + { + try + { + relatedUserId = await _userService.GetUserIdByUsername(relate); + } + catch (UserNotExistException) + { + return BadRequest(ErrorResponse.TimelineController.QueryRelateNotExist()); + } + } + + var result = await _service.GetTimelines(relatedUserId); + result.ForEach(t => t.FillLinks(Url)); + return Ok(result); + } + [HttpGet("timelines/{name}")] public async Task> TimelineGet([FromRoute][TimelineName] string name) { - var result = (await _service.GetTimeline(name)).FillLinksForNormalTimeline(Url); + var result = (await _service.GetTimeline(name)).FillLinks(Url); return Ok(result); } @@ -85,7 +108,7 @@ namespace Timeline.Controllers return StatusCode(StatusCodes.Status403Forbidden, ErrorResponse.Common.Forbid()); } await _service.ChangeProperty(name, body); - var timeline = (await _service.GetTimeline(name)).FillLinksForNormalTimeline(Url); + var timeline = (await _service.GetTimeline(name)).FillLinks(Url); return Ok(timeline); } @@ -137,7 +160,7 @@ namespace Timeline.Controllers try { - var timelineInfo = (await _service.CreateTimeline(body.Name, userId)).FillLinksForNormalTimeline(Url); + var timelineInfo = (await _service.CreateTimeline(body.Name, userId)).FillLinks(Url); return Ok(timelineInfo); } catch (ConflictException) diff --git a/Timeline/Models/Http/ErrorResponse.cs b/Timeline/Models/Http/ErrorResponse.cs index 0d23fe59..9f7e70e1 100644 --- a/Timeline/Models/Http/ErrorResponse.cs +++ b/Timeline/Models/Http/ErrorResponse.cs @@ -277,6 +277,21 @@ namespace Timeline.Models.Http } + public static class TimelineController + { + + public static CommonResponse QueryRelateNotExist(params object?[] formatArgs) + { + return new CommonResponse(ErrorCodes.TimelineController.QueryRelateNotExist, string.Format(TimelineController_QueryRelateNotExist, formatArgs)); + } + + public static CommonResponse CustomMessage_QueryRelateNotExist(string message, params object?[] formatArgs) + { + return new CommonResponse(ErrorCodes.TimelineController.QueryRelateNotExist, string.Format(message, formatArgs)); + } + + } + } } diff --git a/Timeline/Models/Http/TimelineCommon.cs b/Timeline/Models/Http/TimelineCommon.cs index 6b857862..d0dfd837 100644 --- a/Timeline/Models/Http/TimelineCommon.cs +++ b/Timeline/Models/Http/TimelineCommon.cs @@ -53,34 +53,29 @@ namespace Timeline.Models.Http public static class TimelineInfoExtensions { - public static TimelineInfo FillLinksForPersonalTimeline(this TimelineInfo info, IUrlHelper urlHelper) + public static TimelineInfo FillLinks(this TimelineInfo info, IUrlHelper urlHelper) { if (info == null) throw new ArgumentNullException(nameof(info)); if (urlHelper == null) throw new ArgumentNullException(nameof(urlHelper)); - info._links = new TimelineInfoLinks + if (string.IsNullOrEmpty(info.Name)) { - Self = urlHelper.ActionLink(nameof(PersonalTimelineController.TimelineGet), nameof(PersonalTimelineController)[0..^nameof(Controller).Length], new { info.Owner.Username }), - Posts = urlHelper.ActionLink(nameof(PersonalTimelineController.PostListGet), nameof(PersonalTimelineController)[0..^nameof(Controller).Length], new { info.Owner.Username }) - }; - - return info; - } - - public static TimelineInfo FillLinksForNormalTimeline(this TimelineInfo info, IUrlHelper urlHelper) - { - if (info == null) - throw new ArgumentNullException(nameof(info)); - if (urlHelper == null) - throw new ArgumentNullException(nameof(urlHelper)); - - info._links = new TimelineInfoLinks + info._links = new TimelineInfoLinks + { + Self = urlHelper.ActionLink(nameof(PersonalTimelineController.TimelineGet), nameof(PersonalTimelineController)[0..^nameof(Controller).Length], new { info.Owner.Username }), + Posts = urlHelper.ActionLink(nameof(PersonalTimelineController.PostListGet), nameof(PersonalTimelineController)[0..^nameof(Controller).Length], new { info.Owner.Username }) + }; + } + else { - Self = urlHelper.ActionLink(nameof(TimelineController.TimelineGet), nameof(TimelineController)[0..^nameof(Controller).Length], new { info.Name }), - Posts = urlHelper.ActionLink(nameof(TimelineController.PostListGet), nameof(TimelineController)[0..^nameof(Controller).Length], new { info.Name }) - }; + info._links = new TimelineInfoLinks + { + Self = urlHelper.ActionLink(nameof(TimelineController.TimelineGet), nameof(TimelineController)[0..^nameof(Controller).Length], new { info.Name }), + Posts = urlHelper.ActionLink(nameof(TimelineController.PostListGet), nameof(TimelineController)[0..^nameof(Controller).Length], new { info.Name }) + }; + } return info; } diff --git a/Timeline/Resources/Messages.Designer.cs b/Timeline/Resources/Messages.Designer.cs index eeb44f10..727df046 100644 --- a/Timeline/Resources/Messages.Designer.cs +++ b/Timeline/Resources/Messages.Designer.cs @@ -177,6 +177,15 @@ namespace Timeline.Resources { } } + /// + /// Looks up a localized string similar to The user specified by query param "relate" does not exist.. + /// + internal static string TimelineController_QueryRelateNotExist { + get { + return ResourceManager.GetString("TimelineController_QueryRelateNotExist", resourceCulture); + } + } + /// /// Looks up a localized string similar to Username or password is invalid.. /// diff --git a/Timeline/Resources/Messages.resx b/Timeline/Resources/Messages.resx index 66a84d5f..c42657d3 100644 --- a/Timeline/Resources/Messages.resx +++ b/Timeline/Resources/Messages.resx @@ -156,6 +156,9 @@ The timeline with given name does not exist. + + The user specified by query param "relate" does not exist. + Username or password is invalid. diff --git a/Timeline/Services/TimelineService.cs b/Timeline/Services/TimelineService.cs index 6f9d437e..67a57deb 100644 --- a/Timeline/Services/TimelineService.cs +++ b/Timeline/Services/TimelineService.cs @@ -228,6 +228,16 @@ namespace Timeline.Services /// public interface ITimelineService : IBaseTimelineService { + /// + /// Get all timelines including personal timelines. + /// + /// Filter timelines related (own or is a member) to specific user. + /// The list of timelines. + /// + /// If user with related user id does not exist, empty list will be returned. + /// + Task> GetTimelines(long? relatedUserId = null); + /// /// Create a timeline. /// @@ -618,6 +628,44 @@ namespace Timeline.Services } } + public async Task> GetTimelines(long? relatedUserId = null) + { + List entities; + + if (relatedUserId == null) + { + entities = await Database.Timelines.Include(t => t.Members).ToListAsync(); + } + else + { + var timelineAsMemberIds = await Database.TimelineMembers.Where(m => m.UserId == relatedUserId).Select(m => m.TimelineId).ToListAsync(); + entities = await Database.Timelines.Where(t => t.OwnerId == relatedUserId || timelineAsMemberIds.Contains(t.Id)).Include(t => t.Members).ToListAsync(); + } + + var result = new List(); + + foreach (var entity in entities) + { + var timeline = new TimelineInfo + { + Name = entity.Name, + Description = entity.Description ?? "", + Owner = Mapper.Map(await UserService.GetUserById(entity.OwnerId)), + Visibility = entity.Visibility, + Members = new List() + }; + + foreach (var m in entity.Members) + { + timeline.Members.Add(Mapper.Map(await UserService.GetUserById(m.UserId))); + } + + result.Add(timeline); + } + + return result; + } + public async Task CreateTimeline(string name, long owner) { if (name == null) -- cgit v1.2.3