diff --git a/ZR.Admin.WebApi/Controllers/CommonController.cs b/ZR.Admin.WebApi/Controllers/CommonController.cs
index 9d621bd..813c2f1 100644
--- a/ZR.Admin.WebApi/Controllers/CommonController.cs
+++ b/ZR.Admin.WebApi/Controllers/CommonController.cs
@@ -1,15 +1,10 @@
-using System.Net;
-using System.Net.Sockets;
-using Infrastructure.Helper;
+using Infrastructure.Helper;
using JinianNet.JNTemplate;
-using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using ZR.Admin.WebApi.Filters;
-using ZR.Model.System;
using ZR.Service.IService;
using ZR.Service.System;
-using ZR.Service.System.IService;
using ZR.ServiceCore.Model;
using ZR.ServiceCore.Services.IService;
@@ -135,15 +130,6 @@ namespace ZR.Admin.WebApi.Controllers
SysFile file = new();
string fileExt = Path.GetExtension(formFile.FileName);//文件后缀
double fileSize = Math.Round(formFile.Length / 1024.0, 2);//文件大小KB
- var scheme = HttpContext.Request.Scheme + "://";
- var serverIP = HttpContext.Request.Host.Value;
- if (WebHostEnvironment.IsProduction())
- {
- var host = await Dns.GetHostEntryAsync(Dns.GetHostName());
- var ip = host.AddressList
- .FirstOrDefault(it => it.AddressFamily == AddressFamily.InterNetwork);
- serverIP = ip + ":" + Request.HttpContext.Connection.LocalPort;//获取服务器IP
- }
if (OptionsSetting.Upload.NotAllowedExt.Contains(fileExt))
{
@@ -166,7 +152,7 @@ namespace ZR.Admin.WebApi.Controllers
uploadDto.FileDir = OptionsSetting.Upload.LocalSavePath;
}
file = await SysFileService.SaveFileToLocal(savePath, uploadDto.FileName, uploadDto.FileDir,
- HttpContext.GetUId(), HttpContext.GetName(), formFile, scheme + serverIP);
+ HttpContext.GetUId(), HttpContext.GetNickName(), formFile, OptionsSetting.Upload.UploadUrl);
break;
case StoreType.REMOTE:
break;
@@ -181,7 +167,7 @@ namespace ZR.Admin.WebApi.Controllers
return ToResponse(ResultCode.CUSTOM_ERROR, "上传文件过大,不能超过 " + AlimaxContentLength + " MB");
}
file = new(formFile.FileName, uploadDto.FileName, fileExt, fileSize + "kb",
- uploadDto.FileDir, HttpContext.GetUId(), HttpContext.GetName())
+ uploadDto.FileDir, HttpContext.GetUId(), HttpContext.GetNickName())
{
StoreType = (int)StoreType.ALIYUN,
FileType = formFile.ContentType
diff --git a/ZR.Admin.WebApi/Controllers/System/SysFileController.cs b/ZR.Admin.WebApi/Controllers/System/SysFileController.cs
index dd22b6f..9476742 100644
--- a/ZR.Admin.WebApi/Controllers/System/SysFileController.cs
+++ b/ZR.Admin.WebApi/Controllers/System/SysFileController.cs
@@ -1,8 +1,5 @@
-using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using ZR.Admin.WebApi.Filters;
-using ZR.Model.System;
-using ZR.Service.System.IService;
using ZR.ServiceCore.Model;
using ZR.ServiceCore.Model.Dto;
using ZR.ServiceCore.Services.IService;
@@ -20,11 +17,11 @@ namespace ZR.Admin.WebApi.Controllers
///
/// 文件存储接口
///
- private readonly ISysFileService _SysFileService;
+ private readonly ISysFileService _sysFileService;
- public SysFileController(ISysFileService SysFileService)
+ public SysFileController(ISysFileService sysFileService)
{
- _SysFileService = SysFileService;
+ _sysFileService = sysFileService;
}
///
@@ -43,7 +40,7 @@ namespace ZR.Admin.WebApi.Controllers
predicate = predicate.AndIF(parm.StoreType != null, m => m.StoreType == parm.StoreType);
predicate = predicate.AndIF(parm.FileId != null, m => m.Id == parm.FileId);
- var response = _SysFileService.GetPages(predicate.ToExpression(), parm, x => x.Id, OrderByType.Desc);
+ var response = _sysFileService.GetPages(predicate.ToExpression(), parm, x => x.Id, OrderByType.Desc);
return SUCCESS(response);
}
@@ -56,7 +53,7 @@ namespace ZR.Admin.WebApi.Controllers
[ActionPermissionFilter(Permission = "tool:file:query")]
public IActionResult GetSysFile(long Id)
{
- var response = _SysFileService.GetFirst(x => x.Id == Id);
+ var response = _sysFileService.GetFirst(x => x.Id == Id);
return SUCCESS(response);
}
@@ -68,13 +65,12 @@ namespace ZR.Admin.WebApi.Controllers
[HttpDelete("{ids}")]
[ActionPermissionFilter(Permission = "tool:file:delete")]
[Log(Title = "文件存储", BusinessType = BusinessType.DELETE)]
- public IActionResult DeleteSysFile(string ids)
+ public async Task DeleteSysFile(string ids)
{
long[] idsArr = Tools.SpitLongArrary(ids);
if (idsArr.Length <= 0) { return ToResponse(ApiResult.Error($"删除失败Id 不能为空")); }
- var response = _SysFileService.Delete(idsArr);
- //TODO 删除本地资源
+ var response = await _sysFileService.DeleteSysFileAsync(idsArr);
return ToResponse(response);
}
@@ -88,10 +84,50 @@ namespace ZR.Admin.WebApi.Controllers
[ActionPermissionFilter(Permission = "tool:file:export")]
public IActionResult Export()
{
- var list = _SysFileService.GetAll();
+ var list = _sysFileService.GetAll();
string sFileName = ExportExcel(list, "SysFile", "文件存储");
return SUCCESS(new { path = "/export/" + sFileName, fileName = sFileName });
}
+
+ ///
+ /// 通过文件ID下载文件
+ ///
+ ///
+ ///
+ [HttpPost("download")]
+ public IActionResult Download([FromBody] SysFile file)
+ {
+ var sysFile = _sysFileService.Queryable().Where(it => it.Id == file.Id).First();
+ if (sysFile == null)
+ {
+ return NoContent();
+ }
+
+ Stream? stream = null;
+ switch ((StoreType)Enum.Parse(typeof(StoreType), sysFile.StoreType.ToString() ?? string.Empty))
+ {
+ case StoreType.LOCAL:
+ stream = sysFile.IsEncrypted == "1" ? _sysFileService.DecryptSysFileStream(sysFile.FileUrl)
+ : new FileStream(sysFile.FileUrl, FileMode.Open);
+ break;
+ case StoreType.ALIYUN:
+ stream = AliyunOssHelper.DownloadFile(sysFile.FileUrl, "", sysFile.IsEncrypted == "1");
+ break;
+ default:
+ throw new CustomException("不支持的存储类型");
+ }
+ if (stream != null)
+ {
+ return new FileStreamResult(stream, "application/octet-stream")
+ {
+ FileDownloadName = sysFile.RealName
+ };
+ }
+ else
+ {
+ return NoContent();
+ }
+ }
}
}
\ No newline at end of file
diff --git a/ZR.Admin.WebApi/Controllers/System/SysProfileController.cs b/ZR.Admin.WebApi/Controllers/System/SysProfileController.cs
index 252d985..ff7008a 100644
--- a/ZR.Admin.WebApi/Controllers/System/SysProfileController.cs
+++ b/ZR.Admin.WebApi/Controllers/System/SysProfileController.cs
@@ -1,8 +1,5 @@
-using System.Net;
-using System.Net.Sockets;
-using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Options;
using ZR.Admin.WebApi.Filters;
-using ZR.Model.System;
using ZR.Service.System.IService;
using ZR.ServiceCore.Model;
using ZR.ServiceCore.Model.Dto;
@@ -24,6 +21,7 @@ namespace ZR.Admin.WebApi.Controllers.System
private readonly ISysDeptService DeptService;
private readonly ISysFileService FileService;
private IWebHostEnvironment hostEnvironment;
+ private readonly OptionsSetting _optionsSetting;
public SysProfileController(
ISysUserService userService,
@@ -31,7 +29,8 @@ namespace ZR.Admin.WebApi.Controllers.System
ISysUserPostService postService,
ISysDeptService deptService,
ISysFileService sysFileService,
- IWebHostEnvironment hostEnvironment)
+ IWebHostEnvironment hostEnvironment,
+ IOptions options)
{
UserService = userService;
RoleService = roleService;
@@ -39,6 +38,7 @@ namespace ZR.Admin.WebApi.Controllers.System
DeptService = deptService;
FileService = sysFileService;
this.hostEnvironment = hostEnvironment;
+ _optionsSetting = options.Value;
}
///
@@ -122,19 +122,10 @@ namespace ZR.Admin.WebApi.Controllers.System
{
long userId = HttpContext.GetUId();
if (formFile == null) throw new CustomException("请选择文件");
-
- var scheme = HttpContext.Request.Scheme + "://";
- var serverIP = HttpContext.Request.Host.Value;
- if (hostEnvironment.IsProduction())
- {
- var host = await Dns.GetHostEntryAsync(Dns.GetHostName());
- var ip = host.AddressList
- .FirstOrDefault(it => it.AddressFamily == AddressFamily.InterNetwork);
- serverIP = ip + ":" + Request.HttpContext.Connection.LocalPort;//获取服务器IP
- }
+
var file = await FileService.SaveFileToLocal(hostEnvironment.WebRootPath, "", "avatar",
- HttpContext.GetUId(), HttpContext.GetName(), formFile, serverIP);
+ HttpContext.GetUId(), HttpContext.GetName(), formFile, _optionsSetting.Upload.UploadUrl);
UserService.UpdatePhoto(new SysUser() { Avatar = file.AccessUrl, UserId = userId });
return SUCCESS(new { imgUrl = file.AccessUrl });
diff --git a/ZR.Common/AliyunOssHelper.cs b/ZR.Common/AliyunOssHelper.cs
index b45c87a..0360e6f 100644
--- a/ZR.Common/AliyunOssHelper.cs
+++ b/ZR.Common/AliyunOssHelper.cs
@@ -3,6 +3,7 @@ using Aliyun.OSS.Common;
using Infrastructure;
using System;
using System.IO;
+using System.Security.Cryptography;
namespace ZR.Common
{
@@ -55,7 +56,9 @@ namespace ZR.Common
try
{
OssClient client = new(endpoint, accessKeyId, accessKeySecret);
+ dirPath = dirPath.Replace("\\", "/");
DeleteObjectResult putObjectResult = client.DeleteObject(bucketName, dirPath);
+ return putObjectResult.HttpStatusCode;
}
catch (Exception ex)
{
@@ -63,5 +66,52 @@ namespace ZR.Common
}
return System.Net.HttpStatusCode.BadRequest;
}
+
+ public static Stream DownloadFile(string dirPath, string bucketName = "", bool isEncrypted = false)
+ {
+ if (string.IsNullOrEmpty(bucketName))
+ {
+ bucketName = bucketName1;
+ }
+ try
+ {
+ OssClient client = new(endpoint, accessKeyId, accessKeySecret);
+ dirPath = dirPath.Replace("\\", "/");
+ var ossObject = client.GetObject(bucketName, dirPath);
+ if (isEncrypted)
+ {
+ try
+ {
+ var key = new byte[]
+ {
+ 13, 57, 174, 2, 102, 26, 253, 192, 141, 38, 175, 244, 32, 86, 163, 25, 237, 134,
+ 253, 162, 62, 203, 57, 52, 56, 157, 78, 155, 63, 28, 63, 255
+ };
+ var iv = new byte[]
+ {
+ 137, 221, 84, 122, 104, 162, 48, 60, 108, 130, 170, 238, 186, 190, 111, 176
+ };
+ var aes = Aes.Create();
+ aes.Key = key;
+ aes.IV = iv;
+ var decryptor = aes.CreateDecryptor();
+ var cryptoStream = new CryptoStream(ossObject.Content, decryptor, CryptoStreamMode.Read);
+ return cryptoStream;
+ }
+ catch (Exception e)
+ {
+ // 处理异常,例如记录日志或抛出自定义异常
+ Console.WriteLine($"解密文件时发生异常: {e.Message}");
+ throw;
+ }
+ }
+ return ossObject.Content;
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ throw;
+ }
+ }
}
}
diff --git a/ZR.Common/Tools.cs b/ZR.Common/Tools.cs
index d95c47f..7ee02d9 100644
--- a/ZR.Common/Tools.cs
+++ b/ZR.Common/Tools.cs
@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
+using System.IO;
+using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
@@ -126,5 +128,31 @@ namespace ZR.Common
return true; //由数字、字母、符号构成的密码
}
+
+ ///
+ /// 获取文件的MD5值
+ ///
+ /// 文件流
+ ///
+ public static string GetMD5HashFromFile(Stream filestream)
+ {
+ try
+ {
+ MD5 md5 = new MD5CryptoServiceProvider();
+ byte[] retVal = md5.ComputeHash(filestream);
+ filestream.Close();
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < retVal.Length; i++)
+ {
+ sb.Append(retVal[i].ToString("x2"));
+ }
+ return sb.ToString();
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ throw;
+ }
+ }
}
}
diff --git a/ZR.ServiceCore/Model/SysFile.cs b/ZR.ServiceCore/Model/SysFile.cs
index 8144663..c77d371 100644
--- a/ZR.ServiceCore/Model/SysFile.cs
+++ b/ZR.ServiceCore/Model/SysFile.cs
@@ -58,6 +58,21 @@
/// 访问路径
///
public string AccessUrl { get; set; }
+ ///
+ /// 描述 : 文件MD5
+ /// 空值 : true
+ ///
+ public string FileMd5 { get; set; }
+ ///
+ /// 已加密
+ ///
+ public string IsEncrypted { get; set; }
+ ///
+ /// 描述:文件是否已上传
+ /// 空值:false
+ ///
+ [SugarColumn(IsIgnore = true)]
+ public bool FileExists { get; set; }
public SysFile() { }
public SysFile(string originFileName, string fileName, string ext, string fileSize, string storePath,
diff --git a/ZR.ServiceCore/Services/IService/ISysFileService.cs b/ZR.ServiceCore/Services/IService/ISysFileService.cs
index 7fc4de9..8876b71 100644
--- a/ZR.ServiceCore/Services/IService/ISysFileService.cs
+++ b/ZR.ServiceCore/Services/IService/ISysFileService.cs
@@ -8,16 +8,20 @@ namespace ZR.ServiceCore.Services.IService
{
Task InsertFile(SysFile file);
+ Task SaveFile(SysFile file, IFormFile formFile, string rootPath, string uploadUrl);
+
///
/// 上传文件
///
- ///
- ///
- ///
///
- ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
/// 文件对象
- Task SaveFileToLocal(string rootPath, string fileName, string fileDir, long userId, string userName,
+ Task SaveFileToLocal(string rootPath, string fileName, string fileDir, long userId, string nickName,
IFormFile formFile, string uploadUrl);
Task SaveFileToAliyun(SysFile file, IFormFile formFile);
@@ -35,5 +39,26 @@ namespace ZR.ServiceCore.Services.IService
/// 文件名,不包括扩展名
///
string HashFileName(string str = null);
+
+ ///
+ /// 删除文件
+ ///
+ /// 文件ID
+ ///
+ Task DeleteSysFileAsync(long[] ids);
+
+ ///
+ /// 条件查询文件列表
+ ///
+ /// 文件对象
+ ///
+ List SelectFileList(SysFile sysFile);
+
+ ///
+ /// 文件解密流
+ ///
+ ///
+ ///
+ Stream DecryptSysFileStream(string fileUrl);
}
}
diff --git a/ZR.ServiceCore/Services/SysFileService.cs b/ZR.ServiceCore/Services/SysFileService.cs
index 90a5330..75fbf01 100644
--- a/ZR.ServiceCore/Services/SysFileService.cs
+++ b/ZR.ServiceCore/Services/SysFileService.cs
@@ -22,25 +22,42 @@ namespace ZR.ServiceCore.Services
public class SysFileService : BaseService, ISysFileService
{
private string domainUrl = AppSettings.GetConfig("ALIYUN_OSS:domainUrl");
- private readonly ISysConfigService SysConfigService;
- private OptionsSetting OptionsSetting;
+ private readonly ISysConfigService _sysConfigService;
+ private OptionsSetting _optionsSetting;
public SysFileService(ISysConfigService sysConfigService, IOptions options)
{
- SysConfigService = sysConfigService;
- OptionsSetting = options.Value;
+ _sysConfigService = sysConfigService;
+ _optionsSetting = options.Value;
+ }
+
+ public async Task SaveFile(SysFile file, IFormFile formFile, string rootPath, string uploadUrl)
+ {
+ var storeTypeConfig = _sysConfigService.GetSysConfigByKey("sys.file.storetype").ConfigValue;
+ switch ((StoreType)Enum.Parse(typeof(StoreType), storeTypeConfig))
+ {
+ case StoreType.LOCAL:
+ return await SaveFileToLocal(rootPath, file.FileName,
+ file.StorePath, file.Create_by, file.Create_name, formFile, uploadUrl);
+ case StoreType.ALIYUN:
+ return await SaveFileToAliyun(file, formFile);
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
}
///
/// 存储本地
///
- /// 存储文件夹
/// 存储根目录
/// 自定文件名
+ /// 存储文件夹
+ ///
+ ///
/// 上传的文件流
- ///
+ ///
///
- public async Task SaveFileToLocal(string rootPath, string fileName, string fileDir, long userId, string userName,
- IFormFile formFile, string uploadUrl)
+ public async Task SaveFileToLocal(string rootPath, string fileName, string fileDir, long userId,
+ string nickName, IFormFile formFile, string uploadUrl)
{
string fileExt = Path.GetExtension(formFile.FileName);
fileName = (fileName.IsEmpty() ? HashFileName() : fileName) + fileExt;
@@ -53,20 +70,56 @@ namespace ZR.ServiceCore.Services
{
Directory.CreateDirectory(Path.GetDirectoryName(finalFilePath));
}
-
- using (var stream = new FileStream(finalFilePath, FileMode.Create))
+
+ var md5HashFromFile = Tools.GetMD5HashFromFile(formFile.OpenReadStream());
+ var exp = Expressionable.Create();
+ exp.AndIF(md5HashFromFile.IsNotEmpty(), it => it.FileMd5 == md5HashFromFile);
+ var sysFile = await GetSingleAsync(exp.ToExpression());
+ if (sysFile != null)
{
+ sysFile.FileExists = true;
+ return sysFile;
+ }
+
+ var notEncryptExt = _sysConfigService.GetSysConfigByKey("sys.file.notEncryptExt")
+ .ConfigValue.Split(",");
+ var encryptOnOff = !notEncryptExt.Contains(fileExt) && _sysConfigService
+ .GetSysConfigByKey("sys.file.encryptOnOff").ConfigValue.ParseToBool();
+ if (encryptOnOff)
+ {
+ var key = new byte[]
+ {
+ 13, 57, 174, 2, 102, 26, 253, 192, 141, 38, 175, 244, 32, 86, 163, 25, 237, 134,
+ 253, 162, 62, 203, 57, 52, 56, 157, 78, 155, 63, 28, 63, 255
+ };
+ var iv = new byte[]
+ {
+ 137, 221, 84, 122, 104, 162, 48, 60, 108, 130, 170, 238, 186, 190, 111, 176
+ };
+
+ var encryptor = Aes.Create().CreateEncryptor(key, iv);
+ await using var outputFileStream = new FileStream(finalFilePath, FileMode.Create);
+ await using var cryptoStream = new CryptoStream(outputFileStream, encryptor, CryptoStreamMode.Write);
+ await formFile.CopyToAsync(cryptoStream);
+ }
+ else
+ {
+ await using var stream = new FileStream(finalFilePath, FileMode.Create);
await formFile.CopyToAsync(stream);
}
+
// string uploadUrl = OptionsSetting.Upload.UploadUrl;
string accessPath = string.Concat(uploadUrl, "/", filePath.Replace("\\", "/"), "/", fileName);
- SysFile file = new(formFile.FileName, fileName, fileExt, fileSize + "kb", filePath, userId, userName)
+ SysFile file = new(formFile.FileName, fileName, fileExt, fileSize + "kb", filePath, userId, nickName)
{
StoreType = (int)StoreType.LOCAL,
FileType = formFile.ContentType,
FileUrl = finalFilePath.Replace("\\", "/"),
AccessUrl = accessPath
};
+ file.IsEncrypted = encryptOnOff ? "1" : "0";
+ file.FileExists = false;
+ file.FileMd5 = md5HashFromFile;
file.Id = await InsertFile(file);
return file;
}
@@ -82,12 +135,49 @@ namespace ZR.ServiceCore.Services
file.FileName = (file.FileName.IsEmpty() ? HashFileName() : file.FileName) + file.FileExt;
file.StorePath = GetdirPath(file.StorePath);
string finalPath = Path.Combine(file.StorePath, file.FileName);
- HttpStatusCode statusCode = AliyunOssHelper.PutObjectFromFile(formFile.OpenReadStream(), finalPath, "");
- if (statusCode != HttpStatusCode.OK) return file;
+
+ var md5HashFromFile = Tools.GetMD5HashFromFile(formFile.OpenReadStream());
+ var exp = Expressionable.Create();
+ exp.AndIF(md5HashFromFile.IsNotEmpty(), it => it.FileMd5 == md5HashFromFile);
+ var sysFile = await GetSingleAsync(exp.ToExpression());
+ if (sysFile != null)
+ {
+ sysFile.FileExists = true;
+ return sysFile;
+ }
+ var notEncryptExt = _sysConfigService.GetSysConfigByKey("sys.file.notEncryptExt")
+ .ConfigValue.Split(",");
+ var encryptOnOff = !notEncryptExt.Contains(file.FileExt) && _sysConfigService.GetSysConfigByKey("sys.file.encryptOnOff")
+ .ConfigValue.ParseToBool();
+ if (encryptOnOff)
+ {
+ var key = new byte[]
+ {
+ 13, 57, 174, 2, 102, 26, 253, 192, 141, 38, 175, 244, 32, 86, 163, 25, 237, 134,
+ 253, 162, 62, 203, 57, 52, 56, 157, 78, 155, 63, 28, 63, 255
+ };
+ var iv = new byte[]
+ {
+ 137, 221, 84, 122, 104, 162, 48, 60, 108, 130, 170, 238, 186, 190, 111, 176
+ };
+ var encryptor = Aes.Create().CreateEncryptor(key, iv);
+ await using var cryptoStream = new CryptoStream(formFile.OpenReadStream(), encryptor, CryptoStreamMode.Write);
+ HttpStatusCode statusCode = AliyunOssHelper.PutObjectFromFile(cryptoStream, finalPath, "");
+ if (statusCode != HttpStatusCode.OK) return file;
+
+ }
+ else
+ {
+ HttpStatusCode statusCode = AliyunOssHelper.PutObjectFromFile(formFile.OpenReadStream(), finalPath, "");
+ if (statusCode != HttpStatusCode.OK) return file;
+ }
- file.StorePath = file.StorePath;
+ file.IsEncrypted = encryptOnOff ? "1" : "0";
+ file.FileExists = false;
+ file.FileMd5 = md5HashFromFile;
file.FileUrl = finalPath;
file.AccessUrl = string.Concat(domainUrl, "/", file.StorePath.Replace("\\", "/"), "/", file.FileName);
+ file.StoreType = (int)StoreType.ALIYUN;
file.Id = await InsertFile(file);
return file;
@@ -120,6 +210,52 @@ namespace ZR.ServiceCore.Services
return BitConverter.ToString(MD5.HashData(Encoding.Default.GetBytes(str)), 4, 8).Replace("-", "");
}
+ public async Task DeleteSysFileAsync(long[] ids)
+ {
+ var sysFiles = await GetListAsync(x => ids.Contains(x.Id));
+ // var accessUrls = sysFiles.Select(t => t.AccessUrl).ToList();
+ var res = 0;
+ foreach (var item in sysFiles)
+ {
+ switch (item.StoreType)
+ {
+ case (int)StoreType.LOCAL:
+ File.Delete(item.FileUrl);
+ res += await DeleteByIdAsync(item.Id) ? 1 : 0;
+ break;
+ case (int)StoreType.ALIYUN:
+ var httpStatusCode = AliyunOssHelper.DeleteFile(item.FileUrl);
+ if (httpStatusCode == HttpStatusCode.NoContent)
+ {
+ res += await DeleteByIdAsync(item.Id) ? 1 : 0;
+ }
+
+ break;
+ }
+ }
+
+ return res;
+ }
+
+ public List SelectFileList(SysFile sysFile)
+ {
+ var exp = Expressionable.Create();
+ exp.AndIF(sysFile.FileName.IsNotEmpty(), it => it.FileName.Contains(sysFile.FileName));
+ exp.AndIF(sysFile.FileExt.IsNotEmpty(), it => it.FileExt == sysFile.FileExt);
+ exp.AndIF(sysFile.FileSize.IsNotEmpty(), it => it.FileSize == sysFile.FileSize);
+ exp.AndIF(sysFile.StorePath.IsNotEmpty(), it => it.StorePath == sysFile.StorePath);
+ exp.AndIF(sysFile.StoreType > 0, it => it.StoreType == sysFile.StoreType);
+ exp.AndIF(sysFile.FileType.IsNotEmpty(), it => it.FileType == sysFile.FileType);
+ exp.AndIF(sysFile.AccessUrl.IsNotEmpty(), it => it.AccessUrl == sysFile.AccessUrl);
+ exp.AndIF(sysFile.FileUrl.IsNotEmpty(), it => it.FileUrl == sysFile.FileUrl);
+ exp.AndIF(sysFile.Create_by.IsNotEmpty(), it => it.Create_by == sysFile.Create_by);
+ exp.AndIF(sysFile.Create_name.IsNotEmpty(), it => it.Create_name == sysFile.Create_name);
+ exp.AndIF(sysFile.Create_time != null, it => it.Create_time == sysFile.Create_time);
+ exp.AndIF(sysFile.FileMd5.IsNotEmpty(), it => it.FileMd5 == sysFile.FileMd5);
+ exp.AndIF(sysFile.Id > 0, it => it.Id == sysFile.Id);
+ return GetList(exp.ToExpression());
+ }
+
public Task InsertFile(SysFile file)
{
try
@@ -132,5 +268,53 @@ namespace ZR.ServiceCore.Services
throw new Exception(ex.Message);
}
}
+
+ ///
+ /// 文件解密流
+ ///
+ ///
+ ///
+ public Stream DecryptSysFileStream(string fileUrl)
+ {
+ var key = new byte[]
+ {
+ 13, 57, 174, 2, 102, 26, 253, 192, 141, 38, 175, 244, 32, 86, 163, 25, 237, 134,
+ 253, 162, 62, 203, 57, 52, 56, 157, 78, 155, 63, 28, 63, 255
+ };
+ var iv = new byte[]
+ {
+ 137, 221, 84, 122, 104, 162, 48, 60, 108, 130, 170, 238, 186, 190, 111, 176
+ };
+ try
+ {
+ var aes = Aes.Create();
+ aes.Key = key;
+ aes.IV = iv;
+ var decryptor = aes.CreateDecryptor();
+ var fsInput = new FileStream(fileUrl.Replace("/","\\"), FileMode.Open, FileAccess.ReadWrite);
+ var msOutput = new MemoryStream();
+ var cryptoStream = new CryptoStream(fsInput, decryptor, CryptoStreamMode.Read);
+ // 从加密文件中读取并解密
+ int bytesRead;
+ var buffer = new byte[4096];
+ while ((bytesRead = cryptoStream.Read(buffer, 0, buffer.Length)) > 0)
+ {
+ msOutput.Write(buffer, 0, bytesRead);
+ }
+
+ fsInput.Position = 0;
+ cryptoStream.Close();
+ // 返回解密后的流
+ msOutput.Position = 0;
+ return msOutput;
+ }
+ catch (Exception e)
+ {
+ // 处理异常,例如记录日志或抛出自定义异常
+ Console.WriteLine($"解密文件时发生异常: {e.Message}");
+ throw;
+ }
+
+ }
}
}