public async Task <ActionResult> Post(string name, [FromBody] RegionCreationInfo creationInfo) { // _logger.LogInformation("Image Base64: {0}", creationInfo.ImageBase64); var region = new PostRegionEntity { Title = name }; if (!string.IsNullOrEmpty(creationInfo?.ImageBase64)) { region.IconData = Convert.FromBase64String(creationInfo.ImageBase64); } try { _dataFacade.AddPostRegion(region); await _dataFacade.CommitChanges(); } catch (DataFacadeException) { // name 字段不合法 return(BadRequest()); } catch (Exception ex) { _logger.LogError(ex, "向数据源添加板块时抛出异常:{0}:{1}", ex.GetType(), ex.Message); throw; } return(Ok()); }
/// <summary> /// 向数据源中添加帖子。 /// </summary> /// <param name="dataFacade">数据源的外观。</param> /// <param name="indexEntity">帖子索引实体对象。</param> /// <param name="contentEntity">帖子内容对象。</param> /// <returns></returns> /// <exception cref="ArgumentNullException"> /// <paramref name="dataFacade"/>为null /// 或 /// <paramref name="indexEntity"/>为null /// 或 /// <paramref name="contentEntity"/>为null /// </exception> /// <exception cref="DataFacadeException">数据源抛出了未经处理的异常</exception> public static async Task <int> AddPost(this IDataFacade dataFacade, PostEntity indexEntity, PostContentEntity contentEntity) { if (dataFacade == null) { throw new ArgumentNullException(nameof(dataFacade)); } if (indexEntity == null) { throw new ArgumentNullException(nameof(indexEntity)); } if (contentEntity == null) { throw new ArgumentNullException(nameof(contentEntity)); } // 将内容实体对象插入到数据源中。 await dataFacade.AddPostContentEntity(contentEntity); // 将帖子索引实体对象插入到数据源中。 dataFacade.AddPostIndexEntity(indexEntity); await dataFacade.CommitChanges(); return(indexEntity.Id); }
/// <summary> /// 移除帖子图片。 /// </summary> /// <param name="dataFacade"></param> /// <param name="postId">帖子 ID。</param> /// <param name="indexesToRemove">要移除的图片索引。</param> /// <returns></returns> /// <exception cref="ArgumentNullException"> /// <paramref name="dataFacade"/>为null /// 或 /// <paramref name="indexesToRemove"/>为null /// </exception> /// <exception cref="PostNotFoundException">指定的帖子不存在。</exception> public static async Task RemovePostImages(this IDataFacade dataFacade, int postId, IEnumerable <int> indexesToRemove) { if (dataFacade == null) { throw new ArgumentNullException(nameof(dataFacade)); } if (indexesToRemove == null) { throw new ArgumentNullException(nameof(indexesToRemove)); } // TODO: 在这里添加代码对 indexesToRemove 进行验证 var indexEntity = await dataFacade.Posts .Where(e => e.Id == postId) .FirstOrDefaultAsync(); if (indexEntity == null) { throw new PostNotFoundException(); } var contentId = new ObjectId(indexEntity.ContentId); var contentEntity = await dataFacade.FindPostContentEntity(contentId); var indexesToRemoveConcrete = indexesToRemove.ToArray(); // 删除图片数据 var removeTasks = new List <Task>(); foreach (var imageIndex in indexesToRemoveConcrete.Where(i => i >= 0 && i < contentEntity.ImageIds.Length)) { var imageId = contentEntity.ImageIds[imageIndex]; if (imageId == null) { continue; } removeTasks.Add(dataFacade.RemoveImage(imageId.Value)); } await Task.WhenAll(removeTasks); // 更新内容实体对象 var imageSetDict = indexesToRemoveConcrete.ToDictionary <int, int, ObjectId?>(i => i, i => null); await dataFacade.UpdatePostContentImageIds(contentId, imageSetDict); // 更新索引实体对象中的最后更新时间戳 indexEntity.UpdateTime = DateTime.Now; await dataFacade.CommitChanges(); }
/// <summary> /// 当给定的用户不存在时,向数据源添加用户。返回用户实体对象。 /// </summary> /// <param name="dataFacade">数据源外观。</param> /// <param name="wechatId">用户的微信 ID。</param> /// <returns></returns> /// <exception cref="ArgumentNullException"> /// <paramref name="dataFacade"/> 为 null /// 或 /// <paramref name="wechatId"/> 为 null /// </exception> public static async Task <UserEntity> AddOrFindUserByWechatId(this IDataFacade dataFacade, string wechatId) { if (dataFacade == null) { throw new ArgumentNullException(nameof(dataFacade)); } if (wechatId == null) { throw new ArgumentNullException(nameof(wechatId)); } var existingEntity = await dataFacade.Users .Where(u => u.WechatId == wechatId) .FirstOrDefaultAsync(); if (existingEntity != null) { // 用户已经存在于数据源中 return(existingEntity); } // 用户在数据源中未找到 var userEntity = new UserEntity { WechatId = wechatId }; try { dataFacade.AddUser(userEntity); await dataFacade.CommitChanges(); return(userEntity); } catch (DataFacadeException) { // 重做用户查询 existingEntity = await dataFacade.Users .Where(u => u.WechatId == wechatId) .FirstOrDefaultAsync(); if (existingEntity != null) { return(existingEntity); } // 重做用户查询仍然无法找到用户 throw; } }
/// <summary> /// 向数据源添加评论索引实体对象及其对应的内容实体对象。 /// </summary> /// <param name="dataFacade"></param> /// <param name="indexEntity">要添加的索引实体对象。</param> /// <param name="contentEntity">要添加的内容实体对象。</param> /// <returns></returns> /// <exception cref="ArgumentNullException"> /// <paramref name="indexEntity"/>为null /// 或 /// <paramref name="contentEntity"/>为null /// </exception> public static async Task AddPostComment(this IDataFacade dataFacade, CommentEntity indexEntity, CommentContentEntity contentEntity) { if (indexEntity == null) { throw new ArgumentNullException(nameof(indexEntity)); } if (contentEntity == null) { throw new ArgumentNullException(nameof(contentEntity)); } dataFacade.AddCommentIndexEntity(indexEntity); await dataFacade.CommitChanges(); await dataFacade.AddCommentContentEntity(contentEntity); }
/// <summary> /// 删除指定的帖子。 /// </summary> /// <param name="dataFacade"></param> /// <param name="postId">要删除的帖子 ID。</param> /// <param name="permanent">是否永久性地删除帖子数据</param> /// <returns></returns> /// <exception cref="ArgumentNullException"> /// <paramref name="dataFacade"/>为null /// </exception> /// <exception cref="DataFacadeException">当数据源抛出了未经处理的异常时抛出</exception> public static async Task RemovePost(this IDataFacade dataFacade, int postId, bool permanent = false) { if (dataFacade == null) { throw new ArgumentNullException(nameof(dataFacade)); } if (permanent) { throw new NotImplementedException(); } var indexEntity = await dataFacade.Posts .Where(e => e.Id == postId && e.IsRemoved == false) .FirstOrDefaultAsync(); if (indexEntity == null) { throw new PostNotFoundException(); } indexEntity.IsRemoved = true; await dataFacade.CommitChanges(); }
/// <summary> /// 向给定的帖子上传图片。 /// </summary> /// <param name="dataFacade"></param> /// <param name="postId">帖子 ID。</param> /// <param name="images">图片 ID 及对应图片的数据流工厂。</param> /// <returns></returns> /// <exception cref="ArgumentNullException"> /// <paramref name="images"/>为null /// </exception> /// <exception cref="PostNotFoundException"> /// 指定的帖子不存在 /// 或 /// 帖子存在但其删除标记为true /// </exception> public static async Task UpdatePostImages(this IDataFacade dataFacade, int postId, IReadOnlyDictionary <int, Func <Stream> > images) { if (images == null) { throw new ArgumentNullException(nameof(images)); } // TODO: 在这里添加代码对 images 执行验证 var indexEntity = await dataFacade.Posts // 下面的语句中务必使用 e.IsRemoved == true 以正确引导 EF Core 建立查询 .Where(e => e.Id == postId && e.IsRemoved == false) .FirstOrDefaultAsync(); if (indexEntity == null) { // 指定的帖子不存在 throw new PostNotFoundException(); } var contentId = new ObjectId(indexEntity.ContentId); var contentEntity = await dataFacade.FindPostContentEntity(contentId); // 删除已有的、被覆盖的图片数据 var removeTasks = new List <Task>(); foreach (var imageIndex in images.Keys.Where(i => i >= 0 && i < contentEntity.ImageIds.Length)) { var imageId = contentEntity.ImageIds[imageIndex]; if (imageId == null) { continue; } removeTasks.Add(dataFacade.RemoveImage(imageId.Value)); } await Task.WhenAll(removeTasks); // 将图片上传至数据源 var imageIds = new ConcurrentDictionary <int, ObjectId?>(); var uploadTasks = new List <Task>(); foreach (var(index, imageDataStreamFactory) in images) { var imageDataStream = imageDataStreamFactory(); uploadTasks.Add(dataFacade.UploadImage(imageDataStream) .ContinueWith((t, i) => { imageDataStream.Close(); imageIds.TryAdd((int)i, t.Result); }, index)); } await Task.WhenAll(uploadTasks); // 更新内容实体对象 await dataFacade.UpdatePostContentImageIds(contentId, imageIds); // 更新索引实体对象中的上次更新时间戳 indexEntity.UpdateTime = DateTime.Now; await dataFacade.CommitChanges(); }