From 3c9e0a7569ea012e665d0b690fda7eeaa06516d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=8D=E5=81=9A=E7=A0=81=E5=86=9C?= <599854767@qq.com> Date: Mon, 29 Nov 2021 13:46:55 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=8A=A0=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=88=B0=E9=98=BF=E9=87=8C=E4=BA=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/UploadController.cs | 43 +++++++++++-- ZR.Admin.WebApi/appsettings.json | 7 ++- ZR.CodeGenerator/CodeGenerateTemplate.cs | 5 +- ZR.Common/AliyunOssHelper.cs | 47 +++++++++++++++ ZR.Common/ZR.Common.csproj | 5 ++ ZR.Service/System/IService/ISysFileService.cs | 17 +++++- ZR.Service/System/SysFileService.cs | 60 ++++++++++++++++++- ZR.Vue/src/views/business/gendemo/index.vue | 5 +- 8 files changed, 176 insertions(+), 13 deletions(-) create mode 100644 ZR.Common/AliyunOssHelper.cs diff --git a/ZR.Admin.WebApi/Controllers/UploadController.cs b/ZR.Admin.WebApi/Controllers/UploadController.cs index 3762e45..7702b11 100644 --- a/ZR.Admin.WebApi/Controllers/UploadController.cs +++ b/ZR.Admin.WebApi/Controllers/UploadController.cs @@ -5,7 +5,9 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using System; using System.IO; +using System.Linq; using ZR.Admin.WebApi.Filters; +using ZR.Service.System.IService; namespace ZR.Admin.WebApi.Controllers { @@ -15,10 +17,12 @@ namespace ZR.Admin.WebApi.Controllers private NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); private OptionsSetting OptionsSetting; private IWebHostEnvironment WebHostEnvironment; - public UploadController(IOptions optionsSetting, IWebHostEnvironment webHostEnvironment) + private ISysFileService SysFileService; + public UploadController(IOptions optionsSetting, IWebHostEnvironment webHostEnvironment, ISysFileService fileService) { OptionsSetting = optionsSetting.Value; WebHostEnvironment = webHostEnvironment; + SysFileService = fileService; } /// /// 存储文件 @@ -26,8 +30,8 @@ namespace ZR.Admin.WebApi.Controllers /// /// [HttpPost] - [Verify] - [ActionPermissionFilter(Permission = "system")] + //[Verify] + //[ActionPermissionFilter(Permission = "system")] public IActionResult SaveFile([FromForm(Name = "file")] IFormFile formFile) { if (formFile == null) throw new CustomException(ResultCode.PARAM_ERROR, "上传图片不能为空"); @@ -35,7 +39,7 @@ namespace ZR.Admin.WebApi.Controllers string fileName = FileUtil.HashFileName(Guid.NewGuid().ToString()).ToLower() + fileExt; string finalFilePath = Path.Combine(WebHostEnvironment.WebRootPath, FileUtil.GetdirPath("uploads"), fileName); finalFilePath = finalFilePath.Replace("\\", "/").Replace("//", "/"); - + if (!Directory.Exists(Path.GetDirectoryName(finalFilePath))) { Directory.CreateDirectory(Path.GetDirectoryName(finalFilePath)); @@ -47,7 +51,36 @@ namespace ZR.Admin.WebApi.Controllers } string accessPath = $"{OptionsSetting.Upload.UploadUrl}/{FileUtil.GetdirPath("uploads").Replace("\\", " /")}{fileName}"; - return ToResponse(ResultCode.SUCCESS, new { accessPath, fullPath = finalFilePath }); + return ToResponse(ResultCode.SUCCESS, accessPath); + } + + /// + /// 存储文件到阿里云 + /// + /// + /// + [HttpPost] + //[Verify] + //[ActionPermissionFilter(Permission = "system")] + public IActionResult SaveFileAliyun([FromForm(Name = "file")] IFormFile formFile) + { + if (formFile == null) throw new CustomException(ResultCode.PARAM_ERROR, "上传文件不能为空"); + string fileExt = Path.GetExtension(formFile.FileName); + string[] AllowedFileExtensions = new string[] { ".jpg", ".gif", ".png", ".jpeg", ".webp", ".svga", ".xls" }; + int MaxContentLength = 1024 * 1024 * 4; + + if (!AllowedFileExtensions.Contains(fileExt)) + { + return ToResponse(ResultCode.CUSTOM_ERROR, "上传失败,未经允许上传类型"); + } + + if (formFile.Length > MaxContentLength) + { + return ToResponse(ResultCode.CUSTOM_ERROR, "上传文件过大,不能超过 " + (MaxContentLength / 1024).ToString() + " MB"); + } + (bool, string) result = SysFileService.SaveFile("", formFile); + + return ToResponse(ResultCode.SUCCESS, result.Item2); } } } diff --git a/ZR.Admin.WebApi/appsettings.json b/ZR.Admin.WebApi/appsettings.json index eaafb97..58dd587 100644 --- a/ZR.Admin.WebApi/appsettings.json +++ b/ZR.Admin.WebApi/appsettings.json @@ -24,10 +24,13 @@ "UploadDirectory": "/", "UploadUrl": "http://localhost:8888" }, - "QIQIU_OSS": { + //ƴ洢 + "ALIYUN_OSS": { "REGIONID": "cn-hangzhou", "KEY": "XX", - "SECRET": "XX" + "SECRET": "XX", + "bucketName": "bucketName", + "domainUrl": "http://xxx.xxx.com"//Դ }, "gen": { "conn": "server=LAPTOP-STKF2M8H\\SQLEXPRESS;user=zr;pwd=abc;database=ZrAdmin;Trusted_Connection=SSPI", diff --git a/ZR.CodeGenerator/CodeGenerateTemplate.cs b/ZR.CodeGenerator/CodeGenerateTemplate.cs index 3914017..1f97147 100644 --- a/ZR.CodeGenerator/CodeGenerateTemplate.cs +++ b/ZR.CodeGenerator/CodeGenerateTemplate.cs @@ -98,7 +98,8 @@ namespace ZR.CodeGenerator { sb.AppendLine($" //文件上传成功方法"); sb.AppendLine($" handleUpload{dbFieldInfo.CsharpField}Success(res, file) {{"); - sb.AppendLine($" this.form.{columnName} = URL.createObjectURL(file.raw);"); + sb.AppendLine($" this.form.{columnName} = res.data;"); + sb.AppendLine($" // this.form.{columnName} = URL.createObjectURL(file.raw);"); sb.AppendLine($" // this.$refs.upload.clearFiles();"); sb.AppendLine($" }},"); replaceDto.VueBeforeUpload = TplJsBeforeUpload(); @@ -346,7 +347,7 @@ namespace ZR.CodeGenerator { StringBuilder sb = new StringBuilder(); sb.AppendLine(@" //文件上传前判断方法"); - sb.AppendLine(@" uploadUrl: process.env.VUE_APP_BASE_API + ""/upload/SaveFile/"","); + sb.AppendLine(@" uploadUrl: process.env.VUE_APP_BASE_API + ""upload/SaveFile"","); return sb.ToString(); } diff --git a/ZR.Common/AliyunOssHelper.cs b/ZR.Common/AliyunOssHelper.cs new file mode 100644 index 0000000..8510317 --- /dev/null +++ b/ZR.Common/AliyunOssHelper.cs @@ -0,0 +1,47 @@ +using Aliyun.OSS; +using Aliyun.OSS.Common; +using Infrastructure; +using System; +using System.IO; + +namespace ZR.Common +{ + public class AliyunOssHelper + { + static string accessKeyId = ConfigUtils.Instance.GetConfig("ALIYUN_OSS:KEY"); + static string accessKeySecret = ConfigUtils.Instance.GetConfig("ALIYUN_OSS:SECRET"); + static string endpoint = ConfigUtils.Instance.GetConfig("ALIYUN_OSS:REGIONID"); + static string bucketName1 = ConfigUtils.Instance.GetConfig("ALIYUN_OSS:bucketName"); + + /// + /// 上传到阿里云 + /// + /// + /// 存储路径 eg: upload/2020/01/01/xxx.png + /// 存储桶 如果为空默认取配置文件 + public static System.Net.HttpStatusCode PutObjectFromFile(Stream filestreams, string dirPath, string bucketName = "") + { + OssClient client = new OssClient(endpoint, accessKeyId, accessKeySecret); + if (string.IsNullOrEmpty(bucketName)) { bucketName = bucketName1; } + try + { + dirPath = dirPath.Replace("\\", "/"); + PutObjectResult putObjectResult = client.PutObject(bucketName, dirPath, filestreams); + // Console.WriteLine("Put object:{0} succeeded", directory); + + return putObjectResult.HttpStatusCode; + } + catch (OssException ex) + { + Console.WriteLine("Failed with error code: {0}; Error info: {1}. \nRequestID:{2}\tHostID:{3}", + ex.ErrorCode, ex.Message, ex.RequestId, ex.HostId); + } + catch (Exception ex) + { + Console.WriteLine("Failed with error info: {0}", ex.Message); + } + return System.Net.HttpStatusCode.BadRequest; + } + + } +} diff --git a/ZR.Common/ZR.Common.csproj b/ZR.Common/ZR.Common.csproj index 988d309..1bffb47 100644 --- a/ZR.Common/ZR.Common.csproj +++ b/ZR.Common/ZR.Common.csproj @@ -5,7 +5,12 @@ + + + + + diff --git a/ZR.Service/System/IService/ISysFileService.cs b/ZR.Service/System/IService/ISysFileService.cs index 99daf07..ff1b047 100644 --- a/ZR.Service/System/IService/ISysFileService.cs +++ b/ZR.Service/System/IService/ISysFileService.cs @@ -1,9 +1,24 @@ using Infrastructure.Attribute; -using ZR.Model.System; +using Microsoft.AspNetCore.Http; namespace ZR.Service.System.IService { public interface ISysFileService { + (bool, string) SaveFile(string picdir, IFormFile formFile); + + /// + /// 按时间来创建文件夹 + /// + /// + /// eg: 2020/11/3 + string GetdirPath(string path = ""); + + /// + /// 取文件名的MD5值(16位) + /// + /// 文件名,不包括扩展名 + /// + string HashFileName(string str = null); } } diff --git a/ZR.Service/System/SysFileService.cs b/ZR.Service/System/SysFileService.cs index 7a0741d..7a78c8b 100644 --- a/ZR.Service/System/SysFileService.cs +++ b/ZR.Service/System/SysFileService.cs @@ -1,6 +1,13 @@ using Infrastructure.Attribute; -using ZR.Model.System; +using Microsoft.AspNetCore.Http; +using System.IO; using ZR.Service.System.IService; +using ZR.Common; +using Infrastructure; +using System; +using System.Text; +using System.Security.Cryptography; +using System.Net; namespace ZR.Service.System { @@ -10,6 +17,57 @@ namespace ZR.Service.System [AppService(ServiceType = typeof(ISysFileService), ServiceLifetime = LifeTime.Transient)] public class SysFileService : ISysFileService { + private string domainUrl = ConfigUtils.Instance.GetConfig("ALIYUN_OSS:domainUrl"); + + /// + /// 上传文件到阿里云 + /// + /// + /// + /// + public (bool, string) SaveFile(string picdir, IFormFile formFile) + { + // eg: idcard/2020/08/18 + string dir = GetdirPath(picdir.ToString()); + string tempName = HashFileName(); + string fileExt = Path.GetExtension(formFile.FileName); + string fileName = $"{tempName}{fileExt}"; + string webUrl = $"{domainUrl}/{dir}/{fileName}"; + + HttpStatusCode statusCode = AliyunOssHelper.PutObjectFromFile(formFile.OpenReadStream(), Path.Combine(dir, fileName)); + + if (statusCode == HttpStatusCode.OK) + { + return (true, webUrl); + } + return (false, ""); + } + + public string GetdirPath(string path = "") + { + DateTime date = DateTime.Now; + int year = date.Year; + int month = date.Month; + int day = date.Day; + //int hour = date.Hour; + + string timeDir = $"{year}/{month}/{day}";// date.ToString("yyyyMM/dd/HH/"); + if (!string.IsNullOrEmpty(path)) + { + timeDir = path + "/" + timeDir; + } + return timeDir; + } + + public string HashFileName(string str = null) + { + if (string.IsNullOrEmpty(str)) + { + str = Guid.NewGuid().ToString(); + } + MD5CryptoServiceProvider md5 = new(); + return BitConverter.ToString(md5.ComputeHash(Encoding.Default.GetBytes(str)), 4, 8).Replace("-", ""); + } } } diff --git a/ZR.Vue/src/views/business/gendemo/index.vue b/ZR.Vue/src/views/business/gendemo/index.vue index f543ac0..614f3ea 100644 --- a/ZR.Vue/src/views/business/gendemo/index.vue +++ b/ZR.Vue/src/views/business/gendemo/index.vue @@ -179,7 +179,7 @@ export default { // 用户性别选项列表 sexOptions: [], //文件上传前判断方法 - uploadUrl: process.env.VUE_APP_BASE_API + "/upload/SaveFile/", + uploadUrl: process.env.VUE_APP_BASE_API + "upload/SaveFile", // 数据列表 dataList: [], @@ -291,7 +291,8 @@ export default { }, //文件上传成功方法 handleUploadIconSuccess(res, file) { - this.form.icon = URL.createObjectURL(file.raw); + this.form.icon = res.data; + // this.form.icon = URL.createObjectURL(file.raw); // this.$refs.upload.clearFiles(); }, // 显示状态字典翻译