diff --git a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Config/SwaggerDoc.xml b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Config/SwaggerDoc.xml index a0aa002d..92d0af2b 100644 --- a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Config/SwaggerDoc.xml +++ b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Config/SwaggerDoc.xml @@ -270,29 +270,37 @@ 文件 - + 文件上传下载 + - + - 文件下载,只需用文件code即可 + 文件下载,只需用文件code即可,可选择是否为缩略图 + - 多文件上传,type可空,默认上传至File文件夹下,swagger返回雪花id精度是有问题的 + 多文件上传,type可空,默认上传至File文件夹下,swagger返回雪花id精度是有问题的,同时如果时图片类型,还需要进行缩略图制作 文件类型,可空 多文件表单 描述 + + + 一键同步图片到缩略图 + + + 自动分表,日志添加 @@ -438,7 +446,7 @@ 测试控制器 - + 依赖注入 @@ -448,6 +456,7 @@ + @@ -547,6 +556,12 @@ + + + 缩略图测试,需要生成前及生成后的路径 + + + 用户管理 diff --git a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/FileController.cs b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/FileController.cs index cc9c5dde..c01f4ebd 100644 --- a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/FileController.cs +++ b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/FileController.cs @@ -11,7 +11,9 @@ using System.Linq; using System.Threading.Tasks; using Yi.Framework.Common.Const; using Yi.Framework.Common.Enum; +using Yi.Framework.Common.Helper; using Yi.Framework.Common.Models; +using Yi.Framework.Core; using Yi.Framework.Interface; using Yi.Framework.Model.Models; using Yi.Framework.WebCore; @@ -27,26 +29,30 @@ namespace Yi.Framework.ApiMicroservice.Controllers { private IFileService _iFileService; private readonly IHostEnvironment _env; + private ThumbnailSharpInvoer _thumbnailSharpInvoer; /// /// 文件上传下载 /// /// /// - public FileController(IFileService iFileService, IHostEnvironment env) + /// + public FileController(IFileService iFileService, IHostEnvironment env, ThumbnailSharpInvoer thumbnailSharpInvoer) { _iFileService = iFileService; _env = env; + _thumbnailSharpInvoer = thumbnailSharpInvoer; } /// - /// 文件下载,只需用文件code即可 + /// 文件下载,只需用文件code即可,可选择是否为缩略图 /// /// + /// /// - [Route("/api/file/{code}")] + [Route("/api/file/{code}/{isThumbnail?}")] [HttpGet] - public async Task Get(long code) + public async Task Get(long code, bool? isThumbnail) { var file = await _iFileService._repository.GetByIdAsync(code); if (file is null) @@ -55,6 +61,11 @@ namespace Yi.Framework.ApiMicroservice.Controllers } try { + //如果为缩略图 + if (isThumbnail is true) + { + file.FilePath = PathEnum.Thumbnail.ToString(); + } //路径为: 文件路径/文件id+文件扩展名 var path = Path.Combine($"{PathConst.wwwroot}/{file.FilePath}", file.Id.ToString() + Path.GetExtension(file.FileName)); var stream = System.IO.File.OpenRead(path); @@ -68,7 +79,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers } /// - /// 多文件上传,type可空,默认上传至File文件夹下,swagger返回雪花id精度是有问题的 + /// 多文件上传,type可空,默认上传至File文件夹下,swagger返回雪花id精度是有问题的,同时如果时图片类型,还需要进行缩略图制作 /// /// 文件类型,可空 /// 多文件表单 @@ -117,10 +128,30 @@ namespace Yi.Framework.ApiMicroservice.Controllers { Directory.CreateDirectory(typePath); } - using (var stream = new FileStream(Path.Combine(typePath, filename), FileMode.CreateNew, FileAccess.Write)) + + //生成文件 + using (var stream = new FileStream(Path.Combine(typePath, filename), FileMode.CreateNew, FileAccess.ReadWrite)) { await f.CopyToAsync(stream); - } + + //如果是图片类型,还需要生成缩略图 + if (PathEnum.Image.ToString().Equals(type)) + { + //保存至缩略图路径 + var result = _thumbnailSharpInvoer.CreateThumbnailBytes(thumbnailSize: 300, + imageStream: stream, + imageFormat: Format.Jpeg); + string thumbnailPath = $"{PathConst.wwwroot}/{PathEnum.Thumbnail}"; + if (!Directory.Exists(thumbnailPath)) + { + Directory.CreateDirectory(thumbnailPath); + } + await System.IO.File.WriteAllBytesAsync(Path.Combine(thumbnailPath, filename), result); + } + + + }; + //将文件信息添加到数据库 datas.Add(data); codes.Add(data.Id); @@ -132,5 +163,44 @@ namespace Yi.Framework.ApiMicroservice.Controllers return Result.Error(); } } + + /// + /// 一键同步图片到缩略图 + /// + /// + [HttpGet] + public async Task ThumbnailSync() + { + string typePath = $"{PathConst.wwwroot}/{PathEnum.Image}"; + string thumbnailPath = $"{PathConst.wwwroot}/{PathEnum.Thumbnail}"; + List fileNames =FileHelper. GetAllFileNames(typePath); + foreach (var filename in fileNames) + { + if (System.IO.File.Exists(Path.Combine(thumbnailPath, filename))) + { + //如果缩略图存在,直接跳过 + continue; + } + if (!Directory.Exists(typePath)) + { + Directory.CreateDirectory(typePath); + } + using (var stream = new FileStream(Path.Combine(typePath, filename), FileMode.Open, FileAccess.ReadWrite)) + { + //保存至缩略图路径 + var result = _thumbnailSharpInvoer.CreateThumbnailBytes(thumbnailSize: 300, + imageStream: stream, + imageFormat: Format.Jpeg); + + if (!Directory.Exists(thumbnailPath)) + { + Directory.CreateDirectory(thumbnailPath); + } + await System.IO.File.WriteAllBytesAsync(Path.Combine(thumbnailPath, filename), result); + }; + + } + return Result.Success(); + } } } diff --git a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/TestController.cs b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/TestController.cs index ae30e68f..8e0c2f73 100644 --- a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/TestController.cs +++ b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/TestController.cs @@ -35,6 +35,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers private IRoleService _iRoleService; private QuartzInvoker _quartzInvoker; private IHubContext _hub; + private ThumbnailSharpInvoer _thumbnailSharpInvoer; //你可以依赖注入服务层各各接口,也可以注入其他仓储层,怎么爽怎么来! /// /// 依赖注入 @@ -45,13 +46,15 @@ namespace Yi.Framework.ApiMicroservice.Controllers /// /// /// - public TestController(IHubContext hub , ILogger logger, IRoleService iRoleService, IUserService iUserService, IStringLocalizer local, QuartzInvoker quartzInvoker) + /// + public TestController(IHubContext hub, ILogger logger, IRoleService iRoleService, IUserService iUserService, IStringLocalizer local, QuartzInvoker quartzInvoker, ThumbnailSharpInvoer thumbnailSharpInvoer) { _iUserService = iUserService; _iRoleService = iRoleService; _quartzInvoker = quartzInvoker; _hub = hub; _local = local; + _thumbnailSharpInvoer = thumbnailSharpInvoer; } /// @@ -266,7 +269,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers /// /// [HttpGet] - public Result SeedDb() + public Result SeedDb() { var rep = _iUserService._repository; return Result.Success().SetStatus(DbSeedExtend.Invoer(rep._Db)); @@ -290,11 +293,33 @@ namespace Yi.Framework.ApiMicroservice.Controllers /// /// [HttpGet] - public async Task SignalrTest(int msg) + public async Task SignalrTest(int msg) { await _hub.Clients.All.SendAsync("onlineNum", msg); return Result.Success("向所有连接客户端发送一个消息"); } //job任务与公告管理 + + /// + /// 缩略图测试,需要生成前及生成后的路径 + /// + /// + [HttpGet] + public Result ThumbnailTest() + { + try + { + var path = @"D:\App\test11.jpg"; + var result = _thumbnailSharpInvoer.CreateThumbnailBytes(thumbnailSize: 300, + imageStream: new FileStream(path, FileMode.Open, FileAccess.ReadWrite), + imageFormat: Format.Jpeg); + System.IO.File.WriteAllBytes(@"D:\App\test222.jpg", result); + } + catch (Exception ex) + { + return Result.Error(ex.Message); + } + return Result.Success(); + } } } diff --git a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Program.cs b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Program.cs index 7949d9c1..392211b4 100644 --- a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Program.cs +++ b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Program.cs @@ -137,8 +137,11 @@ builder.Services.AddHeiCaptcha(); #region //Http #endregion - builder.Services.AddHttpContextAccessor(); +#region +//ͼ +#endregion +builder.Services.AddSingleton(); //----------------------------------------------------------------------------------------------------------- var app = builder.Build(); #region diff --git a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/wwwroot/Image/1581689552274329600.jpg b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/wwwroot/Image/1581689552274329600.jpg new file mode 100644 index 00000000..aa4daf73 Binary files /dev/null and b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/wwwroot/Image/1581689552274329600.jpg differ diff --git a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/wwwroot/Image/1581690286596296704.png b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/wwwroot/Image/1581690286596296704.png new file mode 100644 index 00000000..55e0425c Binary files /dev/null and b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/wwwroot/Image/1581690286596296704.png differ diff --git a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/wwwroot/Thumbnail/0.jpg b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/wwwroot/Thumbnail/0.jpg new file mode 100644 index 00000000..446af2c8 Binary files /dev/null and b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/wwwroot/Thumbnail/0.jpg differ diff --git a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/wwwroot/Thumbnail/1581689552274329600.jpg b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/wwwroot/Thumbnail/1581689552274329600.jpg new file mode 100644 index 00000000..fe374ad7 Binary files /dev/null and b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/wwwroot/Thumbnail/1581689552274329600.jpg differ diff --git a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/wwwroot/Thumbnail/1581690286596296704.png b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/wwwroot/Thumbnail/1581690286596296704.png new file mode 100644 index 00000000..de598b6b Binary files /dev/null and b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/wwwroot/Thumbnail/1581690286596296704.png differ diff --git a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/yi-sqlsugar-dev.db b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/yi-sqlsugar-dev.db index 70b96057..2b7e921a 100644 Binary files a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/yi-sqlsugar-dev.db and b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/yi-sqlsugar-dev.db differ diff --git a/Yi.Framework.Net6/Yi.Framework.Common/Enum/PathEnum.cs b/Yi.Framework.Net6/Yi.Framework.Common/Enum/PathEnum.cs index fd391c7a..49927991 100644 --- a/Yi.Framework.Net6/Yi.Framework.Common/Enum/PathEnum.cs +++ b/Yi.Framework.Net6/Yi.Framework.Common/Enum/PathEnum.cs @@ -11,6 +11,7 @@ namespace Yi.Framework.Common.Enum Excel, File, Image, + Thumbnail, Temp } } diff --git a/Yi.Framework.Net6/Yi.Framework.Common/Helper/FileHelper.cs b/Yi.Framework.Net6/Yi.Framework.Common/Helper/FileHelper.cs index 2ffc9ba2..4e13d382 100644 --- a/Yi.Framework.Net6/Yi.Framework.Common/Helper/FileHelper.cs +++ b/Yi.Framework.Net6/Yi.Framework.Common/Helper/FileHelper.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; @@ -10,6 +11,8 @@ namespace Yi.Framework.Common.Helper private bool _alreadyDispose = false; + + #region 构造函数 public FileHelper() { @@ -391,5 +394,19 @@ namespace Yi.Framework.Common.Helper } } #endregion + + /// + /// 获取目录下全部文件名 + /// + /// + /// + /// + public static List GetAllFileNames(string path, string pattern = "*") + { + List folder = new DirectoryInfo(path).GetFiles(pattern).ToList(); + + return folder.Select(x => x.Name).ToList(); + } + } } diff --git a/Yi.Framework.Net6/Yi.Framework.Core/CacheClientDB.cs b/Yi.Framework.Net6/Yi.Framework.Core/CacheInvoker.cs similarity index 96% rename from Yi.Framework.Net6/Yi.Framework.Core/CacheClientDB.cs rename to Yi.Framework.Net6/Yi.Framework.Core/CacheInvoker.cs index ab3162ab..442f895f 100644 --- a/Yi.Framework.Net6/Yi.Framework.Core/CacheClientDB.cs +++ b/Yi.Framework.Net6/Yi.Framework.Core/CacheInvoker.cs @@ -12,7 +12,7 @@ using CSRedis; namespace Yi.Framework.Core { - public class CacheClientDB + public class CacheInvoker { public delegate T MyAction(CSRedisClient client); @@ -22,7 +22,7 @@ namespace Yi.Framework.Core private CSRedisClient Client { get; set; } public CSRedisClient _Db { get { return Client; } set { } } - public CacheClientDB(IOptionsMonitor redisConnOptions) + public CacheInvoker(IOptionsMonitor redisConnOptions) { this._RedisOptions = redisConnOptions.CurrentValue; Client = new CSRedisClient($"{_RedisOptions.Host}:{_RedisOptions.Prot},password={_RedisOptions.Password},defaultDatabase ={ _RedisOptions.DB }"); diff --git a/Yi.Framework.Net6/Yi.Framework.Core/ThumbnailSharpInvoer.cs b/Yi.Framework.Net6/Yi.Framework.Core/ThumbnailSharpInvoer.cs new file mode 100644 index 00000000..18c1ffa4 --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.Core/ThumbnailSharpInvoer.cs @@ -0,0 +1,410 @@ +/*MIT License + +Copyright(c) 2017 Mirza Ghulam Rasyid + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; +using System.IO; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Yi.Framework.Core +{ + /// + /// Image format to use when creating a thumbnail. + /// + public enum Format + { + Jpeg, + Bmp, + Png, + Gif, + Tiff + + } + /// + /// Thumbnail class that holds various methods to create an image thumbnail. + /// + public class ThumbnailSharpInvoer + { + private Bitmap CreateBitmapThumbnail(uint thumbnailSize, string imageFileLocation) + { + Bitmap bitmap = null; + Image image = null; + float actualHeight = default(float); + float actualWidth = default(float); + uint thumbnailHeight = default(uint); + uint thumbnailWidth = default(uint); + try + { + image = Image.FromFile(imageFileLocation); + } + catch + { + if (image != null) + image = null; + } + if (image != null) + { + actualHeight = image.Height; + actualWidth = image.Width; + if (actualHeight > actualWidth) + { + if ((uint)actualHeight <= thumbnailSize) + throw new Exception("Thumbnail size must be less than actual height (portrait image)"); + thumbnailHeight = thumbnailSize; + thumbnailWidth = (uint)((actualWidth / actualHeight) * thumbnailSize); + } + else if (actualWidth > actualHeight) + { + + if ((uint)actualWidth <= thumbnailSize) + throw new Exception("Thumbnail size must be less than actual width (landscape image)"); + thumbnailWidth = thumbnailSize; + thumbnailHeight = (uint)((actualHeight / actualWidth) * thumbnailSize); + } + else + { + if ((uint)actualWidth <= thumbnailSize) + throw new Exception("Thumbnail size must be less than image's size"); + thumbnailWidth = thumbnailSize; + thumbnailHeight = thumbnailSize; + } + try + { + + bitmap = new Bitmap((int)thumbnailWidth, (int)thumbnailHeight); + Graphics resizedImage = Graphics.FromImage(bitmap); + resizedImage.InterpolationMode = InterpolationMode.HighQualityBicubic; + resizedImage.CompositingQuality = CompositingQuality.HighQuality; + resizedImage.SmoothingMode = SmoothingMode.HighQuality; + resizedImage.DrawImage(image, 0, 0, thumbnailWidth, thumbnailHeight); + } + catch + { + if (bitmap != null) + bitmap = null; + } + } + return bitmap; + } + private Bitmap CreateBitmapThumbnail(uint thumbnailSize, Stream imageStream) + { + Bitmap bitmap = null; + Image image = null; + float actualHeight = default(float); + float actualWidth = default(float); + uint thumbnailHeight = default(uint); + uint thumbnailWidth = default(uint); + try + { + image = Image.FromStream(imageStream); + } + catch + { + if (image != null) + image = null; + } + if (image != null) + { + actualHeight = image.Height; + actualWidth = image.Width; + if (actualHeight > actualWidth) + { + if ((uint)actualHeight <= thumbnailSize) + throw new Exception("Thumbnail size must be less than actual height (portrait image)"); + thumbnailHeight = thumbnailSize; + thumbnailWidth = (uint)((actualWidth / actualHeight) * thumbnailSize); + } + else if (actualWidth > actualHeight) + { + + if ((uint)actualWidth <= thumbnailSize) + throw new Exception("Thumbnail size must be less than actual width (landscape image)"); + thumbnailWidth = thumbnailSize; + thumbnailHeight = (uint)((actualHeight / actualWidth) * thumbnailSize); + } + else + { + if ((uint)actualWidth <= thumbnailSize) + throw new Exception("Thumbnail size must be less than image's size"); + thumbnailWidth = thumbnailSize; + thumbnailHeight = thumbnailSize; + } + try + { + bitmap = new Bitmap((int)thumbnailWidth, (int)thumbnailHeight); + Graphics resizedImage = Graphics.FromImage(bitmap); + resizedImage.InterpolationMode = InterpolationMode.HighQualityBicubic; + resizedImage.CompositingQuality = CompositingQuality.HighQuality; + resizedImage.SmoothingMode = SmoothingMode.HighQuality; + resizedImage.DrawImage(image, 0, 0, thumbnailWidth, thumbnailHeight); + } + catch + { + if (bitmap != null) + bitmap = null; + } + } + return bitmap; + } + private ImageFormat GetImageFormat(Format format) + { + switch (format) + { + case Format.Jpeg: + return ImageFormat.Jpeg; + case Format.Bmp: + return ImageFormat.Bmp; + case Format.Png: + return ImageFormat.Png; + case Format.Gif: + return ImageFormat.Gif; + default: + return ImageFormat.Tiff; + } + } + private async Task GetImageStreamFromUrl(Uri urlAddress) + { + Stream result = null; + try + { + byte[] bytes = await GetImageBytesFromUrl(urlAddress); + result = new MemoryStream(bytes); + } + catch + { + result = null; + } + return result; + } + private async Task GetImageBytesFromUrl(Uri urlAddress) + { + byte[] buffer = null; + try + { + using (HttpClient client = new HttpClient()) + { + buffer = await client.GetByteArrayAsync(urlAddress); + } + } + catch + { + buffer = null; + } + return buffer; + } + + /// + /// Create a thumbnail from file and returns as stream. + /// + /// Thumbnail size. For portrait image, thumbnail size must be less than its height. + /// For landscape image, thumbnail size must be less than its width. For the same size image (Proportional), thumbnail size must be less than its width and height. + /// Correct image file location. + /// Image format to use. + /// A thumbnail image as stream. Returns null if it fails. + /// 'imageFileLocation' is null. + /// 'imageFileLocation' does not exist. + public Stream CreateThumbnailStream(uint thumbnailSize, string imageFileLocation, Format imageFormat) + { + if (String.IsNullOrEmpty(imageFileLocation)) + throw new ArgumentNullException(nameof(imageFileLocation), "'imageFileLocation' cannot be null"); + if (!File.Exists(imageFileLocation)) + throw new FileNotFoundException($"'{imageFileLocation}' cannot be found"); + Bitmap bitmap = CreateBitmapThumbnail(thumbnailSize, imageFileLocation); + if (bitmap != null) + { + MemoryStream stream = new MemoryStream(); + bitmap.Save(stream, GetImageFormat(imageFormat)); + stream.Position = 0; + return stream; + } + return null; + } + /// + /// Create a thumbnail from image stream and returns as stream. + /// + /// Thumbnail size. For portrait image, thumbnail size must be less than its height. + /// For landscape image, thumbnail size must be less than its width. For the same size image (Proportional), thumbnail size must be less than its width and height. + /// Valid image stream object. + /// Image format to use. + /// A thumbnail image as stream. Returns null if it fails. + /// 'imageStream' is null. + public Stream CreateThumbnailStream(uint thumbnailSize, Stream imageStream, Format imageFormat) + { + if (imageStream == null) + throw new ArgumentNullException(nameof(imageStream), "'imageStream' cannot be null"); + Bitmap bitmap = CreateBitmapThumbnail(thumbnailSize, imageStream); + if (bitmap != null) + { + MemoryStream stream = new MemoryStream(); + bitmap.Save(stream, GetImageFormat(imageFormat)); + stream.Position = 0; + return stream; + } + return null; + } + /// + /// Create a thumbnail from image in bytes and returns as stream. + /// + /// Thumbnail size. For portrait image, thumbnail size must be less than its height. + /// For landscape image, thumbnail size must be less than its width. For the same size image (Proportional), thumbnail size must be less than its width and height. + /// Valid image bytes array. + /// Image format to use. + /// A thumbnail image as stream. Returns null if it fails. + /// 'imageBytes' is null. + public Stream CreateThumbnailStream(uint thumbnailSize, byte[] imageBytes, Format imageFormat) + { + if (imageBytes == null) + throw new ArgumentNullException(nameof(imageBytes), "'imageStream' cannot be null"); + Bitmap bitmap = CreateBitmapThumbnail(thumbnailSize, new MemoryStream(imageBytes)); + if (bitmap != null) + { + MemoryStream stream = new MemoryStream(); + bitmap.Save(stream, GetImageFormat(imageFormat)); + stream.Position = 0; + return stream; + } + return null; + } + /// + /// Create a thumbnail from file and returns as bytes. + /// + /// Thumbnail size. For portrait image, thumbnail size must be less than its height. + /// For landscape image, thumbnail size must be less than its width. For the same size image (Proportional), thumbnail size must be less than its width and height. + /// Correct image file location. + /// Image format to use. + /// A thumbnail image as bytes. Returns null if it fails. + /// 'imageFileLocation' is null. + /// 'imageFileLocation' does not exist. + public byte[] CreateThumbnailBytes(uint thumbnailSize, string imageFileLocation, Format imageFormat) + { + if (String.IsNullOrEmpty(imageFileLocation)) + throw new ArgumentNullException(nameof(imageFileLocation), "'imageFileLocation' cannot be null"); + if (!File.Exists(imageFileLocation)) + throw new FileNotFoundException($"'{imageFileLocation}' cannot be found"); + Stream stream = CreateThumbnailStream(thumbnailSize, imageFileLocation, imageFormat); + if (stream != null) + { + byte[] streamBytes = new byte[stream.Length]; + stream.Read(streamBytes, 0, streamBytes.Length); + return streamBytes; + } + return null; + } + /// + /// Create a thumbnail from image stream and returns as bytes. + /// + /// Thumbnail size. For portrait image, thumbnail size must be less than its height. + /// For landscape image, thumbnail size must be less than its width. For the same size image (Proportional), thumbnail size must be less than its width and height. + /// Valid image stream object. + /// Image format to use. + /// A thumbnail image as bytes. Returns null if it fails. + /// 'imageStream' is null. + public byte[] CreateThumbnailBytes(uint thumbnailSize, Stream imageStream, Format imageFormat) + { + if (imageStream == null) + throw new ArgumentNullException(nameof(imageStream), "'imageStream' cannot be null"); + + Stream stream = CreateThumbnailStream(thumbnailSize, imageStream, imageFormat); + if (stream != null) + { + byte[] streamBytes = new byte[stream.Length]; + stream.Read(streamBytes, 0, streamBytes.Length); + return streamBytes; + } + return null; + } + /// + /// Create a thumbnail from image in bytes and returns as bytes. + /// + /// Thumbnail size. For portrait image, thumbnail size must be less than its height. + /// For landscape image, thumbnail size must be less than its width. For the same size image (Proportional), thumbnail size must be less than its width and height. + /// Valid image bytes array. + /// Image format to use. + /// A thumbnail image as bytes. Returns null if it fails. + /// 'imageBytes' is null. + public byte[] CreateThumbnailBytes(uint thumbnailSize, byte[] imageBytes, Format imageFormat) + { + if (imageBytes == null) + throw new ArgumentNullException(nameof(imageBytes), "'imageStream' cannot be null"); + Stream stream = CreateThumbnailStream(thumbnailSize, imageBytes, imageFormat); + if (stream != null) + { + byte[] streamBytes = new byte[stream.Length]; + stream.Read(streamBytes, 0, streamBytes.Length); + return streamBytes; + } + return null; + } + + + /// + /// Create a thumbnail from valid image url asynchronously. + /// + /// Thumbnail size. For portrait image, thumbnail size must be less than its height. + /// For landscape image, thumbnail size must be less than its width. For the same size image (Proportional), thumbnail size must be less than its width and height. + /// Valid absolute url address with proper scheme. + /// Image format to use. + /// A thumbnail image as stream. Returns null if it fails. + /// 'urlAddress' is null. + public async Task CreateThumbnailStreamAsync(uint thumbnailSize, Uri urlAddress, Format imageFormat) + { + if (urlAddress == null) + throw new ArgumentNullException(nameof(urlAddress), "'urlAddress' cannot be null"); + Stream result = null; + Stream stream = await GetImageStreamFromUrl(urlAddress); + if (stream != null) + { + result = CreateThumbnailStream(thumbnailSize, stream, imageFormat); + } + return result; + } + + /// + /// Create a thumbnail from valid image url asynchronously. + /// + /// Thumbnail size. For portrait image, thumbnail size must be less than its height. + /// For landscape image, thumbnail size must be less than its width. For the same size image (Proportional), thumbnail size must be less than its width and height. + /// Valid absolute url address with proper scheme. + /// Image format to use. + /// A thumbnail image as bytes. Returns null if it fails. + /// 'urlAddress' is null. + public async Task CreateThumbnailBytesAsync(uint thumbnailSize, Uri urlAddress, Format imageFormat) + { + if (urlAddress == null) + throw new ArgumentNullException(nameof(urlAddress), "'urlAddress' cannot be null"); + byte[] result = null; + byte[] imageBytes = await GetImageBytesFromUrl(urlAddress); + if (imageBytes != null) + { + result = CreateThumbnailBytes(thumbnailSize, imageBytes, imageFormat); + } + return result; + } + + + + } +} \ No newline at end of file diff --git a/Yi.Framework.Net6/Yi.Framework.Core/TreeMenuBuild.cs b/Yi.Framework.Net6/Yi.Framework.Core/TreeMenuBuild.cs deleted file mode 100644 index f91d1a16..00000000 --- a/Yi.Framework.Net6/Yi.Framework.Core/TreeMenuBuild.cs +++ /dev/null @@ -1,109 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Yi.Framework.Model.Models; - -namespace Yi.Framework.Core -{ - public static class TreeMenuBuild - { - // /// - // /// 过滤所有已经删除的菜单 - // /// - // /// - // /// - // public static menu Normal(menu menu_data) - // { - // for (int i = menu_data.children.Count() - 1; i >= 0; i--) - // { - // if (menu_data.children[i].is_delete == (short)Common.Enum.DelFlagEnum.Deleted) - // { - // menu_data.children.Remove(menu_data.children[i]); - // } - // else if (menu_data.children[i] != null) - // { - // Normal(menu_data.children[i]); - // } - // } - // return menu_data; - // } - - - - // public static menu ShowFormat(menu menu_data, List allMenuIds) - // { - // return Format(Show(menu_data, allMenuIds)); - // } - - - - // /// - // /// 过滤用户不展示及已删除及未拥有的菜单 - // /// - // /// - // /// - // /// - // private static menu Show(menu menu_data, List allMenuIds) - // { - // for (int i = menu_data.children.Count() - 1; i >= 0; i--) - // { - // if (!allMenuIds.Contains(menu_data.children[i].id) || menu_data.children[i].is_delete == (short)Common.Enum.DelFlagEnum.Deleted || menu_data.children[i].is_show == (short)Common.Enum.ShowFlagEnum.NoShow) - // { - // menu_data.children.Remove(menu_data.children[i]); - // } - // else - // { - // Show(menu_data.children[i], allMenuIds); - // } - // } - // return menu_data; - // } - - // /// - // /// 为了匹配前端格式,通常和show方法一起 - // /// - // /// - // /// - // private static menu Format(menu menu_data) - // { - // for (int i = menu_data.children.Count() - 1; i >= 0; i--) - // { - // if (menu_data.children[i].icon == null) - // { - // menu_data.children[i].icon = "mdi-view-dashboard"; - // } - // if (menu_data.children != null || menu_data.children.Count() != 0) - // { - // Format(menu_data.children[i]); - // } - // } - // if (menu_data.children.Count() == 0) - // { - // menu_data.children = null; - // } - - // return menu_data; - // } - - // public static menu Sort(menu menu_data) - // { - // if (menu_data.children != null) - // { - // for (int i = menu_data.children.Count() - 1; i >= 0; i--) - // { - // menu_data.children = menu_data.children.AsEnumerable().OrderByDescending(u => u.sort).ToList(); - - // if (menu_data.children != null || menu_data.children.Count() != 0) - // { - // Sort(menu_data.children[i]); - // } - // } - // } - // return menu_data; - // } - - } -} - diff --git a/Yi.Framework.Net6/Yi.Framework.Core/Yi.Framework.Core.csproj b/Yi.Framework.Net6/Yi.Framework.Core/Yi.Framework.Core.csproj index b88b0e6b..8b54712d 100644 --- a/Yi.Framework.Net6/Yi.Framework.Core/Yi.Framework.Core.csproj +++ b/Yi.Framework.Net6/Yi.Framework.Core/Yi.Framework.Core.csproj @@ -1,4 +1,4 @@ - + net6.0 diff --git a/Yi.Framework.Net6/Yi.Framework.OcelotGateway/Builder/DataContext.cs b/Yi.Framework.Net6/Yi.Framework.OcelotGateway/Builder/DataContext.cs index dae008e7..4063842b 100644 --- a/Yi.Framework.Net6/Yi.Framework.OcelotGateway/Builder/DataContext.cs +++ b/Yi.Framework.Net6/Yi.Framework.OcelotGateway/Builder/DataContext.cs @@ -37,7 +37,7 @@ namespace Yi.Framework.OcelotGateway.Builder public HttpContext? Context { get; set; } - public CacheClientDB? DB { get; set; } + public CacheInvoker? DB { get; set; } } } diff --git a/Yi.Framework.Net6/Yi.Framework.OcelotGateway/WebCore/OcelotExtension.cs b/Yi.Framework.Net6/Yi.Framework.OcelotGateway/WebCore/OcelotExtension.cs index cc31ca71..eedbb578 100644 --- a/Yi.Framework.Net6/Yi.Framework.OcelotGateway/WebCore/OcelotExtension.cs +++ b/Yi.Framework.Net6/Yi.Framework.OcelotGateway/WebCore/OcelotExtension.cs @@ -12,8 +12,8 @@ namespace Yi.Framework.OcelotGateway.WebCore public class OcelotMiddleware { private readonly RequestDelegate next; - private CacheClientDB _cacheClientDB; - public OcelotMiddleware(RequestDelegate next, CacheClientDB cacheClientDB) + private CacheInvoker _cacheClientDB; + public OcelotMiddleware(RequestDelegate next, CacheInvoker cacheClientDB) { this.next = next; this._cacheClientDB = cacheClientDB; diff --git a/Yi.Framework.Net6/Yi.Framework.WebCore/DbExtend/DbFiterExtend.cs b/Yi.Framework.Net6/Yi.Framework.WebCore/DbExtend/DbFiterExtend.cs index be89bcd7..59aeb3d2 100644 --- a/Yi.Framework.Net6/Yi.Framework.WebCore/DbExtend/DbFiterExtend.cs +++ b/Yi.Framework.Net6/Yi.Framework.WebCore/DbExtend/DbFiterExtend.cs @@ -35,7 +35,7 @@ namespace Yi.Framework.Core //这里可以优化一下 //根据缓存获取全部用户信息 - var userRoleMenu = ServiceLocator.Instance.GetService().Get("用户id"); + var userRoleMenu = ServiceLocator.Instance.GetService().Get("用户id"); var roles = userRoleMenu.Roles; diff --git a/Yi.Framework.Net6/Yi.Framework.WebCore/MiddlewareExtend/RedisExtension.cs b/Yi.Framework.Net6/Yi.Framework.WebCore/MiddlewareExtend/RedisExtension.cs index 4e244d7b..0201e529 100644 --- a/Yi.Framework.Net6/Yi.Framework.WebCore/MiddlewareExtend/RedisExtension.cs +++ b/Yi.Framework.Net6/Yi.Framework.WebCore/MiddlewareExtend/RedisExtension.cs @@ -18,7 +18,7 @@ namespace Yi.Framework.WebCore.MiddlewareExtend if (Appsettings.appBool("Redis_Enabled")) { services.Configure(Appsettings.appConfiguration("RedisConnOptions")); - services.AddSingleton(); + services.AddSingleton(); } return services; } diff --git a/Yi.Framework.Net6/Yi.Framework.WebCore/MiddlewareExtend/RedisInitExtend.cs b/Yi.Framework.Net6/Yi.Framework.WebCore/MiddlewareExtend/RedisInitExtend.cs index 529b96d5..9b91ae9c 100644 --- a/Yi.Framework.Net6/Yi.Framework.WebCore/MiddlewareExtend/RedisInitExtend.cs +++ b/Yi.Framework.Net6/Yi.Framework.WebCore/MiddlewareExtend/RedisInitExtend.cs @@ -20,7 +20,7 @@ namespace Yi.Framework.WebCore.MiddlewareExtend if (Appsettings.appBool("RedisSeed_Enabled")) { - var _cacheClientDB = app.ApplicationServices.GetService(); + var _cacheClientDB = app.ApplicationServices.GetService(); try { diff --git a/Yi.Vue3.x.Vant/src/components/AppUserIcon.vue b/Yi.Vue3.x.Vant/src/components/AppUserIcon.vue index a0ef5340..4b476de6 100644 --- a/Yi.Vue3.x.Vant/src/components/AppUserIcon.vue +++ b/Yi.Vue3.x.Vant/src/components/AppUserIcon.vue @@ -3,7 +3,7 @@ round :width="width" :height="height" -:src="url+(src??'0')" +:src="url+(src??'0')+'/true'" /> diff --git a/Yi.Vue3.x.Vant/src/view/main/recommend.vue b/Yi.Vue3.x.Vant/src/view/main/recommend.vue index 2a7eb6dc..b0f1ae3c 100644 --- a/Yi.Vue3.x.Vant/src/view/main/recommend.vue +++ b/Yi.Vue3.x.Vant/src/view/main/recommend.vue @@ -36,7 +36,7 @@ fit="cover" width="100%" height="7rem" - :src="url + image" + :src="url + image+'/true'" radius="5" />