From d934c1273bc20533683eaad858a1c499c7729a28 Mon Sep 17 00:00:00 2001 From: crupest Date: Thu, 17 Dec 2020 20:08:33 +0800 Subject: ... --- .../Timeline/Services/HighlightTimelineService.cs | 85 +++++++++++++++++++++- 1 file changed, 82 insertions(+), 3 deletions(-) (limited to 'BackEnd/Timeline/Services/HighlightTimelineService.cs') diff --git a/BackEnd/Timeline/Services/HighlightTimelineService.cs b/BackEnd/Timeline/Services/HighlightTimelineService.cs index 0f4e5488..ea3e4c7e 100644 --- a/BackEnd/Timeline/Services/HighlightTimelineService.cs +++ b/BackEnd/Timeline/Services/HighlightTimelineService.cs @@ -9,10 +9,25 @@ using Timeline.Services.Exceptions; namespace Timeline.Services { + + [Serializable] + public class InvalidHighlightTimelineException : Exception + { + public InvalidHighlightTimelineException() { } + public InvalidHighlightTimelineException(string message) : base(message) { } + public InvalidHighlightTimelineException(string message, Exception inner) : base(message, inner) { } + protected InvalidHighlightTimelineException( + System.Runtime.Serialization.SerializationInfo info, + System.Runtime.Serialization.StreamingContext context) : base(info, context) { } + } + + /// + /// Service that controls highlight timeline. + /// public interface IHighlightTimelineService { /// - /// Get all highlight timelines. + /// Get all highlight timelines in order. /// /// A list of all highlight timelines. Task> GetHighlightTimelines(); @@ -39,6 +54,21 @@ namespace Timeline.Services /// Thrown when timeline with given name does not exist. /// Thrown when user with given operator id does not exist. Task RemoveHighlightTimeline(string timelineName, long? operatorId); + + /// + /// Move a highlight timeline to a new position. + /// + /// The timeline name. + /// The new position. Starts at 1. + /// Thrown when is null. + /// Thrown when is not a valid timeline name. + /// Thrown when timeline with given name does not exist. + /// Thrown when given timeline is not a highlight timeline. + /// + /// If is smaller than 1. Then move the timeline to head. + /// If is bigger than total count. Then move the timeline to tail. + /// + Task MoveHighlightTimeline(string timelineName, long newPosition); } public class HighlightTimelineService : IHighlightTimelineService @@ -72,13 +102,13 @@ namespace Timeline.Services if (alreadyIs) return; - _database.HighlightTimelines.Add(new HighlightTimelineEntity { TimelineId = timelineId, OperatorId = operatorId, AddTime = _clock.GetCurrentTime() }); + _database.HighlightTimelines.Add(new HighlightTimelineEntity { TimelineId = timelineId, OperatorId = operatorId, AddTime = _clock.GetCurrentTime(), Order = await _database.HighlightTimelines.CountAsync() + 1 }); await _database.SaveChangesAsync(); } public async Task> GetHighlightTimelines() { - var entities = await _database.HighlightTimelines.Select(t => new { t.Id }).ToListAsync(); + var entities = await _database.HighlightTimelines.OrderBy(t => t.Order).Select(t => new { t.Id }).ToListAsync(); var result = new List(); @@ -106,10 +136,59 @@ namespace Timeline.Services if (entity == null) return false; + await using var transaction = await _database.Database.BeginTransactionAsync(); + + var order = entity.Order; + _database.HighlightTimelines.Remove(entity); await _database.SaveChangesAsync(); + await _database.Database.ExecuteSqlRawAsync("UPDATE highlight_timelines SET `order` = `order` - 1 WHERE `order` > {0}", order); + + await transaction.CommitAsync(); + return true; } + + public async Task MoveHighlightTimeline(string timelineName, long newPosition) + { + if (timelineName == null) + throw new ArgumentNullException(nameof(timelineName)); + + var timelineId = await _timelineService.GetTimelineIdByName(timelineName); + + var entity = await _database.HighlightTimelines.SingleOrDefaultAsync(t => t.TimelineId == timelineId); + + if (entity == null) throw new InvalidHighlightTimelineException("You can't move a non-highlight timeline."); + + var oldPosition = entity.Order; + + if (newPosition < 1) + { + newPosition = 1; + } + else + { + var totalCount = await _database.HighlightTimelines.CountAsync(); + if (newPosition > totalCount) newPosition = totalCount; + } + + if (oldPosition == newPosition) return; + + await using var transaction = await _database.Database.BeginTransactionAsync(); + + if (newPosition > oldPosition) + { + await _database.Database.ExecuteSqlRawAsync("UPDATE highlight_timelines SET `order` = `order` - 1 WHERE `order` BETWEEN {0} AND {1}", oldPosition + 1, newPosition); + await _database.Database.ExecuteSqlRawAsync("UPDATE highlight_timelines SET `order` = {0} WHERE id = {1}", newPosition, entity.Id); + } + else + { + await _database.Database.ExecuteSqlRawAsync("UPDATE highlight_timelines SET `order` = `order` + 1 WHERE `order` BETWEEN {0} AND {1}", newPosition, oldPosition - 1); + await _database.Database.ExecuteSqlRawAsync("UPDATE highlight_timelines SET `order` = {0} WHERE id = {1}", newPosition, entity.Id); + } + + await transaction.CommitAsync(); + } } } -- cgit v1.2.3