From b0d124029b427ead63bb6c6517d911b65fff3f7a Mon Sep 17 00:00:00 2001 From: qwj <qwjzorro@163.com> Date: 星期一, 31 七月 2023 09:11:11 +0800 Subject: [PATCH] 文件上传下载服务 --- .gitignore | 2 DocumentFile.Service/IUploadService.cs | 130 ++++++++++++++++++ DocumentFile.Service/DocumentFile.Service.csproj | 16 ++ DocumentFile.Service/Controllers/DocumentController.cs | 66 +++++++++ DocumentFile.Service/appsettings.json | 9 + DocumentFile.Service/Program.cs | 51 +++++++ DocumentFile.Service/ReturnMsg.cs | 31 ++++ DocumentFile.Service/NLog.config | 27 +++ DocumentFile.Service/appsettings.Development.json | 8 + DocumentFile.Service/NLogProvider.cs | 51 +++++++ 10 files changed, 391 insertions(+), 0 deletions(-) diff --git a/.gitignore b/.gitignore index 62dd116..3ee380a 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,5 @@ DocumentServiceAPI.Enum/obj/ /.vs /DocumentServiceAPI.Web.Entry/appsettings.json +/DocumentFile.Service/bin +/DocumentFile.Service/obj diff --git a/DocumentFile.Service/Controllers/DocumentController.cs b/DocumentFile.Service/Controllers/DocumentController.cs new file mode 100644 index 0000000..7fa7452 --- /dev/null +++ b/DocumentFile.Service/Controllers/DocumentController.cs @@ -0,0 +1,66 @@ +锘縰sing Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using System.ComponentModel.DataAnnotations; + +namespace DocumentFile.Service.Controllers +{ + [Route("api/[controller]/[action]")] + [ApiController] + public class DocumentController : ControllerBase + { + private readonly IUploadService _uploadService; + + /// <summary> + /// 鏋勯�� + /// </summary> + /// <param name="uploadService"></param> + public DocumentController(IUploadService uploadService) + { + _uploadService = uploadService; + } + + /// <summary> + /// 涓婁紶鏂囦欢锛坵ord锛� + /// </summary> + /// <returns></returns> + [HttpPost] + public async Task<IActionResult> UploadDocument(IFormFile formFile) + { + ReturnMsg msg = new ReturnMsg(); + if(formFile.Length>0) + { + msg = await this._uploadService.HandleUploadWordFile(formFile); + } + else + { + msg.error = "璇蜂笂浼犳枃浠�"; + } + + return new JsonResult(msg); + } + + /// <summary> + /// 涓嬭浇鏂囦欢 + /// </summary> + /// <param name="url"></param> + /// <returns></returns> + [HttpPost] + public IActionResult Download([FromBody] string url) + { + try + { + if (!string.IsNullOrEmpty(url)) + { + var _webRootPath = AppDomain.CurrentDomain.BaseDirectory; + + return new FileStreamResult(new FileStream(_webRootPath + url, FileMode.Open), "application/octet-stream");// { FileDownloadName = FileName }; + } + } + catch (Exception ex) + { + NLogProvider.GetInstance().Error(ex); + } + return BadRequest(); + } + } +} diff --git a/DocumentFile.Service/DocumentFile.Service.csproj b/DocumentFile.Service/DocumentFile.Service.csproj new file mode 100644 index 0000000..edf2063 --- /dev/null +++ b/DocumentFile.Service/DocumentFile.Service.csproj @@ -0,0 +1,16 @@ +<Project Sdk="Microsoft.NET.Sdk.Web"> + + <PropertyGroup> + <TargetFramework>net6.0</TargetFramework> + <Nullable>enable</Nullable> + <ImplicitUsings>enable</ImplicitUsings> + </PropertyGroup> + + <ItemGroup> + <PackageReference Include="Autofac" Version="7.0.1" /> + <PackageReference Include="Autofac.Extensions.DependencyInjection" Version="8.0.0" /> + <PackageReference Include="NLog" Version="5.2.2" /> + <PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" /> + </ItemGroup> + +</Project> diff --git a/DocumentFile.Service/IUploadService.cs b/DocumentFile.Service/IUploadService.cs new file mode 100644 index 0000000..9d91a2c --- /dev/null +++ b/DocumentFile.Service/IUploadService.cs @@ -0,0 +1,130 @@ +锘縰sing System.IO.Compression; + +namespace DocumentFile.Service +{ + public interface IUploadService + { + Task<ReturnMsg> HandleUploadWordFile(IFormFile iFormFile); + + Task<ReturnMsg> HandleUploadTemplateFile(IFormFile iFormFile); + + Task<ReturnMsg> HandleUploadImageFile(IFormFile iFormFile); + + //(string fileType, byte[] archiveData, string archiveName) DownloadFiles(string subDirectory); + + } + + public class UploadService : IUploadService + { + private readonly string _webRootPath; + + public UploadService() + { + _webRootPath = AppDomain.CurrentDomain.BaseDirectory; + } + + /// <summary> + /// 涓婁紶鏂囦欢 杈呭姪鍑芥暟 + /// </summary> + /// <param name="formFile"></param> + /// <param name="folder"></param> + /// <param name="format"></param> + /// <returns></returns> + protected async virtual Task<ReturnMsg> HandleUploadFile(IFormFile formFile, string folder, params string[] format) + { + ReturnMsg msg = new ReturnMsg(); + + try + { + var extensionName = Path.GetExtension(formFile.FileName)?.ToLower().Trim(); //鑾峰彇鍚庣紑鍚� + + if (format != null && format.Length > 0 && !format.ToList().Contains(extensionName.ToLower())) + { + msg.error = "璇蜂笂浼犲悗缂�鍚嶄负锛�" + string.Join("銆�", format) + " 鏍煎紡鐨勬枃浠�"; + } + else + { + var path = $"/upload/{folder}/{DateTime.Now:yyyyMMdd}"; + var dir = this._webRootPath + path; + if (!Directory.Exists(dir)) + { + Directory.CreateDirectory(dir); + } + + var filename = $"ZC_{DateTime.Now:HHmmssfff}" + extensionName; + + path += "/" + filename; + + // 鍒涘缓鏂版枃浠� + using var fs = File.Create(this._webRootPath+ path); + await formFile.CopyToAsync(fs); + // 娓呯┖缂撳啿鍖烘暟鎹� + fs.Flush(); + + msg.code = 1; + msg.url = path; + } + } + catch (Exception er) + { + msg.code = -1; + msg.error = "涓婁紶澶辫触"; + NLogProvider.GetInstance().Error(er); + } + + return msg; + } + + + /// <summary> + /// 涓婁紶word鏂囦欢 + /// </summary> + /// <param name="iFormFile"></param> + /// <param name="format"></param> + /// <returns></returns> + public async virtual Task<ReturnMsg> HandleUploadWordFile(IFormFile iFormFile) + => await this.HandleUploadFile(iFormFile, "Instance", ".doc",".docx"); + + /// <summary> + /// 涓婁紶word妯℃澘鏂囦欢 + /// </summary> + /// <param name="iFormFile"></param> + /// <param name="format"></param> + /// <returns></returns> + public async virtual Task<ReturnMsg> HandleUploadTemplateFile(IFormFile iFormFile) + => await this.HandleUploadFile(iFormFile, "Template", ".doc", ".docx"); + + /// <summary> + /// 涓婁紶鍥剧墖 + /// </summary> + /// <param name="iFormFile"></param> + /// <param name="folder"></param> + /// <returns></returns> + public async virtual Task<ReturnMsg> HandleUploadImageFile(IFormFile iFormFile) + => await this.HandleUploadFile(iFormFile, "Photo", ".jpg", ".jpeg", ".png"); + /*, ".gif", ".jfif"*/ + + ///// <summary> + ///// 涓嬭浇璇佷功鏂囦欢 + ///// 鎵撳寘zip + ///// </summary> + ///// <param name="subDirectory"></param> + ///// <returns></returns> + //public (string fileType, byte[] archiveData, string archiveName) DownloadFiles(string path) + //{ + // using var memoryStream = new MemoryStream(); + // using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true)) + // { + // files.ForEach(file => + // { + // var theFile = archive.CreateEntry(Path.GetFileName(file)); + // using var binaryWriter = new BinaryWriter(theFile.Open()); + // binaryWriter.Write(File.ReadAllBytes(file)); + // }); + // } + + // return ("application/zip", memoryStream.ToArray(), zipName); + //} + + } +} diff --git a/DocumentFile.Service/NLog.config b/DocumentFile.Service/NLog.config new file mode 100644 index 0000000..a891ee6 --- /dev/null +++ b/DocumentFile.Service/NLog.config @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8" ?> +<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"> + + <targets> + + <target xsi:type="File" name="info_file" fileName="${basedir}/logs/${shortdate}_info.log" layout="${longdate} ${uppercase:${level}} ${message}"/> + <target xsi:type="File" name="error_file" fileName="${basedir}/logs/${shortdate}_error.log" layout="${longdate} ${uppercase:${level}} ${message} ${exception:stacktrace}" /> + + <!-- + Write events to a file with the date in the filename. + <target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log" + layout="${longdate} ${uppercase:${level}} ${message}" /> + --> + </targets> + + <rules> + <logger name="*" minlevel="Info" maxlevel="Info" writeTo="info_file" /> + <logger name="*" minlevel="Error" maxlevel="Error" writeTo="error_file" /> + + <!-- + Write all events with minimal level of Debug (So Debug, Info, Warn, Error and Fatal, but not Trace) to "f" + <logger name="*" minlevel="Debug" writeTo="f" /> + --> + </rules> +</nlog> diff --git a/DocumentFile.Service/NLogProvider.cs b/DocumentFile.Service/NLogProvider.cs new file mode 100644 index 0000000..979ba25 --- /dev/null +++ b/DocumentFile.Service/NLogProvider.cs @@ -0,0 +1,51 @@ +锘縰sing NLog; + +namespace DocumentFile.Service +{ + /// <summary> + /// 鏃ュ織 + /// </summary> + public class NLogProvider + { + private NLogProvider() + { + logger = LogManager.GetLogger("Logger");//.GetCurrentClassLogger(); + } + + private readonly Logger logger = null; + private static NLogProvider logProvider = null; + + /// <summary> + /// 闈欐�佸疄渚� + /// </summary> + /// <returns></returns> + public static NLogProvider GetInstance() + { + if (logProvider == null) + { + logProvider = new NLogProvider(); + } + return logProvider; + } + + /// <summary> + /// Info + /// </summary> + /// <param name="txt"></param> + public void Info(string txt) + { + if (logger != null) + logger.Info(txt); + } + + /// <summary> + /// Error + /// </summary> + /// <param name="er"></param> + public void Error(Exception er) + { + if (logger != null) + logger.Error(er); + } + } +} diff --git a/DocumentFile.Service/Program.cs b/DocumentFile.Service/Program.cs new file mode 100644 index 0000000..f415d33 --- /dev/null +++ b/DocumentFile.Service/Program.cs @@ -0,0 +1,51 @@ +using Autofac; +using Autofac.Extensions.DependencyInjection; +using DocumentFile.Service; +using Microsoft.AspNetCore.Http.Features; + +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. + +builder.Services.AddControllers(); +// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); + +builder.WebHost.UseKestrel(options => +{ + //options.Limits.MaxRequestLineSize = int.MaxValue;//HTTP 请求行的最大允许大小。 默认为 8kb + //options.Limits.MaxRequestBufferSize = int.MaxValue;//请求缓冲区的最大大小。 默认为 1M + //任何请求正文的最大允许大小(以字节为单位),默认 30,000,000 字节,大约为 28.6MB + options.Limits.MaxRequestBodySize = 300 * 1024 * 1024; //限制请求长度 +}); +builder.Services.Configure<FormOptions>(options => +{ + //默认上传大小限制 + options.MultipartBodyLengthLimit = 300 * 1024 * 1024; + options.ValueLengthLimit = 300 * 1024 * 1024; +}); + +builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()); +builder.Host.ConfigureContainer<ContainerBuilder>(builder => +{ + //注册ioc + builder.RegisterType<UploadService>().As<IUploadService>(); +}); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(); +} + +app.UseHttpsRedirection(); + +app.UseAuthorization(); + +app.MapControllers(); + +app.Run(); diff --git a/DocumentFile.Service/ReturnMsg.cs b/DocumentFile.Service/ReturnMsg.cs new file mode 100644 index 0000000..acfdf41 --- /dev/null +++ b/DocumentFile.Service/ReturnMsg.cs @@ -0,0 +1,31 @@ +锘縩amespace DocumentFile.Service +{ + public class ReturnMsg + { + public ReturnMsg() + { + code = 0; + count = 0; + } + + /// <summary> + /// 鏍囪瘑浠g爜 + /// </summary> + public int code { get; set; } + + /// <summary> + /// 閿欒鍐呭 + /// </summary> + public string error { get; set; } + + /// <summary> + /// 鏂囦欢璺緞 + /// </summary> + public string url { get; set; } + + /// <summary> + /// 璁板綍鏁伴噺 + /// </summary> + public int count { get; set; } + } +} diff --git a/DocumentFile.Service/appsettings.Development.json b/DocumentFile.Service/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/DocumentFile.Service/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/DocumentFile.Service/appsettings.json b/DocumentFile.Service/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/DocumentFile.Service/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} -- Gitblit v1.9.1