diff options
author | crupest <crupest@outlook.com> | 2022-04-10 20:25:29 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2022-04-10 20:25:29 +0800 |
commit | 9d2056786a38558c2ecba4406e2ba172eb0c5597 (patch) | |
tree | e0b26da3fa0282a48c0bfcfc6be661482df14cc2 /BackEnd/Timeline | |
parent | d260c3c3fa073d1a9d09b94c5c4749334e26ab9a (diff) | |
download | timeline-9d2056786a38558c2ecba4406e2ba172eb0c5597.tar.gz timeline-9d2056786a38558c2ecba4406e2ba172eb0c5597.tar.bz2 timeline-9d2056786a38558c2ecba4406e2ba172eb0c5597.zip |
...
Diffstat (limited to 'BackEnd/Timeline')
-rw-r--r-- | BackEnd/Timeline/Models/TimelineBookmark.cs | 16 | ||||
-rw-r--r-- | BackEnd/Timeline/Services/Api/ITimelineBookmarkService1.cs | 20 | ||||
-rw-r--r-- | BackEnd/Timeline/Services/Api/TimelineBookmarkService1.cs | 166 | ||||
-rw-r--r-- | BackEnd/Timeline/Services/EntityNotExistException.cs | 2 | ||||
-rw-r--r-- | BackEnd/Timeline/Startup.cs | 2 |
5 files changed, 205 insertions, 1 deletions
diff --git a/BackEnd/Timeline/Models/TimelineBookmark.cs b/BackEnd/Timeline/Models/TimelineBookmark.cs new file mode 100644 index 00000000..58392182 --- /dev/null +++ b/BackEnd/Timeline/Models/TimelineBookmark.cs @@ -0,0 +1,16 @@ +namespace Timeline.Models +{ + public class TimelineBookmark + { + public TimelineBookmark(string timelineOwner, string timelineName, int position) + { + TimelineOwner = timelineOwner; + TimelineName = timelineName; + Position = position; + } + + public string TimelineOwner { get; set; } + public string TimelineName { get; set; } + public int Position { get; set; } + } +} diff --git a/BackEnd/Timeline/Services/Api/ITimelineBookmarkService1.cs b/BackEnd/Timeline/Services/Api/ITimelineBookmarkService1.cs new file mode 100644 index 00000000..82e4dc48 --- /dev/null +++ b/BackEnd/Timeline/Services/Api/ITimelineBookmarkService1.cs @@ -0,0 +1,20 @@ +using System; +using System.Threading.Tasks; +using Timeline.Models; + +namespace Timeline.Services.Api +{ + public interface ITimelineBookmarkService1 + { + Task<Page<TimelineBookmark>> GetBookmarksAsync(long userId, int page, int pageSize); + + Task<TimelineBookmark> GetBookmarkAsync(long userId, long timelineId); + + Task<TimelineBookmark> AddBookmarkAsync(long userId, long timelineId, int? position = null); + + Task DeleteBookmarkAsync(long userId, long timelineId); + + Task<TimelineBookmark> MoveBookmarkAsync(long userId, long timelineId, int position); + } +} + diff --git a/BackEnd/Timeline/Services/Api/TimelineBookmarkService1.cs b/BackEnd/Timeline/Services/Api/TimelineBookmarkService1.cs new file mode 100644 index 00000000..9dd3c0d7 --- /dev/null +++ b/BackEnd/Timeline/Services/Api/TimelineBookmarkService1.cs @@ -0,0 +1,166 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Timeline.Entities; +using Timeline.Models; +using Timeline.Services.Timeline; +using Timeline.Services.User; + +namespace Timeline.Services.Api +{ + public class TimelineBookmarkService1 : ITimelineBookmarkService1 + { + private DatabaseContext _databaseContext; + private IUserService _userService; + private ITimelineService _timelineService; + + public TimelineBookmarkService1(DatabaseContext databaseContext, IUserService userService, ITimelineService timelineService) + { + _databaseContext = databaseContext; + _userService = userService; + _timelineService = timelineService; + + } + + public async Task<TimelineBookmark> AddBookmarkAsync(long userId, long timelineId, int? position = null) + { + var user = await _userService.GetUserAsync(userId); + var timeline = await _timelineService.GetTimelineAsync(timelineId); + + var count = await _databaseContext.BookmarkTimelines.Where(b => b.UserId == userId).CountAsync(); + + if (position.HasValue) + { + if (position <= 0) + { + position = 1; + } + else if (position > count + 1) + { + position = count + 1; + } + } + else + { + position = count + 1; + } + + await using var transaction = await _databaseContext.Database.BeginTransactionAsync(); + + if (position.Value < count + 1) + { + await _databaseContext.Database.ExecuteSqlRawAsync("UPDATE `bookmark_timelines` SET `rank` = `rank` + 1 WHERE `rank` >= {0} AND `user` = {1}", position.Value, userId); + } + + BookmarkTimelineEntity entity = new BookmarkTimelineEntity + { + UserId = userId, + TimelineId = timelineId, + Rank = position.Value + }; + + _databaseContext.BookmarkTimelines.Add(entity); + await _databaseContext.SaveChangesAsync(); + + await _databaseContext.Database.CommitTransactionAsync(); + + return new TimelineBookmark(user.Username, timeline.Name is null ? "self" : timeline.Name, position.Value); + } + + public async Task DeleteBookmarkAsync(long userId, long timelineId) + { + var entity = await _databaseContext.BookmarkTimelines.Where(b => b.UserId == userId && b.TimelineId == timelineId).SingleOrDefaultAsync(); + if (entity is null) return; + + await _databaseContext.Database.BeginTransactionAsync(); + await _databaseContext.Database.ExecuteSqlRawAsync("UPDATE `bookmark_timelines` SET `rank` = `rank` - 1 WHERE `rank` > {0} AND `user` = {1}", entity.Rank, userId); + _databaseContext.BookmarkTimelines.Remove(entity); + await _databaseContext.SaveChangesAsync(); + await _databaseContext.Database.CommitTransactionAsync(); + } + + public async Task<TimelineBookmark> GetBookmarkAsync(long userId, long timelineId) + { + var user = await _userService.GetUserAsync(userId); + var timeline = await _timelineService.GetTimelineAsync(timelineId); var entity = await _databaseContext.BookmarkTimelines.Where(b => b.UserId == userId && b.TimelineId == timelineId).SingleOrDefaultAsync(); + + if (entity is null) + { + throw new EntityNotExistException(EntityTypes.BookmarkTimeline, new Dictionary<string, object> + { + { "user-id", userId }, + { "timeline-id", timelineId } + }); + } + + return new TimelineBookmark(user.Username, timeline.Name is null ? "self" : timeline.Name, (int)entity.Rank); + } + + public async Task<Page<TimelineBookmark>> GetBookmarksAsync(long userId, int page, int pageSize) + { + if (page <= 0) throw new ArgumentOutOfRangeException(nameof(page)); + if (pageSize <= 0) throw new ArgumentOutOfRangeException(nameof(pageSize)); + + var user = await _userService.GetUserAsync(userId); + + var totalCount = await _databaseContext.BookmarkTimelines.Where(b => b.UserId == userId).CountAsync(); + var entities = await _databaseContext.BookmarkTimelines.Where(b => b.UserId == userId).Skip(pageSize * (page - 1)).Take(pageSize).ToListAsync(); + + var items = new List<TimelineBookmark>(); + foreach (var entity in entities) + { + var timeline = await _timelineService.GetTimelineAsync(entity.TimelineId); + items.Add(new TimelineBookmark(user.Username, timeline.Name is null ? "self" : timeline.Name, (int)entity.Rank)); + } + + return new Page<TimelineBookmark>(page, pageSize, totalCount, items); + } + + public async Task<TimelineBookmark> MoveBookmarkAsync(long userId, long timelineId, int position) + { + var user = await _userService.GetUserAsync(userId); + var timeline = await _timelineService.GetTimelineAsync(timelineId); + + var entity = await _databaseContext.BookmarkTimelines.SingleOrDefaultAsync(t => t.TimelineId == timelineId && t.UserId == userId); + + if (entity is null) + { + throw new EntityNotExistException(EntityTypes.BookmarkTimeline); + } + + var oldPosition = entity.Rank; + + if (position < 1) + { + position = 1; + } + else + { + var totalCount = await _databaseContext.BookmarkTimelines.CountAsync(t => t.UserId == userId); + if (position > totalCount) position = totalCount; + } + + if (oldPosition != position) + { + await using var transaction = await _databaseContext.Database.BeginTransactionAsync(); + + if (position > oldPosition) + { + await _databaseContext.Database.ExecuteSqlRawAsync("UPDATE `bookmark_timelines` SET `rank` = `rank` - 1 WHERE `rank` BETWEEN {0} AND {1} AND `user` = {2}", oldPosition + 1, position, userId); + await _databaseContext.Database.ExecuteSqlRawAsync("UPDATE `bookmark_timelines` SET `rank` = {0} WHERE `id` = {1}", position, entity.Id); + } + else + { + await _databaseContext.Database.ExecuteSqlRawAsync("UPDATE `bookmark_timelines` SET `rank` = `rank` + 1 WHERE `rank` BETWEEN {0} AND {1} AND `user` = {2}", position, oldPosition - 1, userId); + await _databaseContext.Database.ExecuteSqlRawAsync("UPDATE `bookmark_timelines` SET `rank` = {0} WHERE `id` = {1}", position, entity.Id); + } + + await transaction.CommitAsync(); + } + + return new TimelineBookmark(user.Username, timeline.Name is null ? "self" : timeline.Name, (int)entity.Rank); + } + } +} diff --git a/BackEnd/Timeline/Services/EntityNotExistException.cs b/BackEnd/Timeline/Services/EntityNotExistException.cs index 6ae8442d..afebc68e 100644 --- a/BackEnd/Timeline/Services/EntityNotExistException.cs +++ b/BackEnd/Timeline/Services/EntityNotExistException.cs @@ -12,7 +12,7 @@ namespace Timeline.Services [Serializable]
public class EntityNotExistException : EntityException
{
- public EntityNotExistException() : base() { }
+ public EntityNotExistException(EntityType bookmarkTimeline) : base() { }
public EntityNotExistException(string? message) : base(message) { }
public EntityNotExistException(string? message, Exception? inner) : base(message, inner) { }
public EntityNotExistException(EntityType entityType, IDictionary<string, object>? constraints = null, string? message = null, Exception? inner = null)
diff --git a/BackEnd/Timeline/Startup.cs b/BackEnd/Timeline/Startup.cs index 665705a7..3f94f8a9 100644 --- a/BackEnd/Timeline/Startup.cs +++ b/BackEnd/Timeline/Startup.cs @@ -116,6 +116,8 @@ namespace Timeline services.AddScoped<IBookmarkTimelineService, BookmarkTimelineService>();
services.AddScoped<ISearchService, SearchService>();
+ services.AddScoped<ITimelineBookmarkService1, TimelineBookmarkService1>();
+
services.AddOpenApiDocs();
if (_frontEndMode == FrontEndMode.Mock)
|