腾讯云cos

This commit is contained in:
zpc 2025-11-15 15:47:04 +08:00
parent 73eb608139
commit 70f3212840
7 changed files with 205 additions and 2 deletions

View File

@ -32,6 +32,10 @@ namespace Infrastructure.Model
/// 阿里云oss
/// </summary>
public ALIYUN_OSS ALIYUN_OSS { get; set; }
/// <summary>
/// 腾讯云COS
/// </summary>
public TENCENT_COS TENCENT_COS { get; set; }
public JwtSettings JwtSettings { get; set; }
/// <summary>
/// 代码生成配置
@ -86,6 +90,19 @@ namespace Infrastructure.Model
public int MaxSize { get; set; } = 100;
}
/// <summary>
/// 腾讯云COS存储
/// </summary>
public class TENCENT_COS
{
public string REGION { get; set; }
public string SECRET_ID { get; set; }
public string SECRET_KEY { get; set; }
public string BUCKET_NAME { get; set; }
public string DOMAIN_URL { get; set; }
public int MAX_SIZE { get; set; } = 100;
}
/// <summary>
/// Jwt
/// </summary>

View File

@ -98,7 +98,7 @@ namespace ZR.Admin.WebApi.Controllers
/// <returns></returns>
[HttpPost]
[ActionPermissionFilter(Permission = "common")]
public async Task<IActionResult> UploadFile([FromForm] UploadDto uploadDto, IFormFile file, StoreType storeType = StoreType.LOCAL)
public async Task<IActionResult> UploadFile([FromForm] UploadDto uploadDto, IFormFile file, StoreType storeType = StoreType.TENCENT)
{
if (file == null) throw new CustomException(ResultCode.PARAM_ERROR, "上传文件不能为空");
SysFile sysfile = new();
@ -152,6 +152,25 @@ namespace ZR.Admin.WebApi.Controllers
if (sysfile.Id <= 0) { return ToResponse(ApiResult.Error("阿里云连接失败")); }
break;
case StoreType.TENCENT:
int TencentMaxSize = OptionsSetting.TENCENT_COS.MAX_SIZE;
if (OptionsSetting.TENCENT_COS.REGION.IsEmpty())
{
return ToResponse(ResultCode.CUSTOM_ERROR, "配置文件缺失");
}
if ((fileSize / 1024) > TencentMaxSize)
{
return ToResponse(ResultCode.CUSTOM_ERROR, "上传文件过大,不能超过 " + TencentMaxSize + " MB");
}
sysfile = new(formFile.FileName, uploadDto.FileName, fileExt, fileSize + "kb", uploadDto.FileDir, HttpContext.GetName())
{
StoreType = (int)StoreType.TENCENT,
FileType = formFile.ContentType,
ClassifyType = uploadDto.ClassifyType,
CategoryId = uploadDto.CategoryId,
};
sysfile = await SysFileService.SaveFileToTencent(sysfile, uploadDto, formFile);
if (sysfile.Id <= 0) { return ToResponse(ApiResult.Error("腾讯云连接失败")); }
break;
case StoreType.QINIU:
break;

View File

@ -70,6 +70,16 @@
"domainUrl": "http://xxx.xxx.com", //访
"maxSize": 100 // 100M
},
//COS
"TENCENT_COS": {
"APPID": "1308826010",
"REGION": "ap-shanghai", //egap-beijing
"SECRET_ID": "AKIDVyMfzKZdZP8zkNyOdsFuSsBJDB7EScs0",
"SECRET_KEY": "89GWr7JPWYTL8ueHlAYowGZnvzKZjqs9",
"BUCKET_NAME": "miaoyu",
"DOMAIN_URL": "https://miaoyu-1308826010.cos.ap-shanghai.myqcloud.com", //访
"MAX_SIZE": 100 // 100M
},
//
"WxCorp": {
"AgentID": "",

View File

@ -0,0 +1,110 @@
using COSXML;
using COSXML.Auth;
using COSXML.Model.Object;
using Infrastructure;
using System;
using System.IO;
using System.Net;
namespace ZR.Common
{
public class TencentCosHelper
{
static string secretId = AppSettings.GetConfig("TENCENT_COS:SECRET_ID");
static string secretKey = AppSettings.GetConfig("TENCENT_COS:SECRET_KEY");
static string region = AppSettings.GetConfig("TENCENT_COS:REGION");
static string bucketName1 = AppSettings.GetConfig("TENCENT_COS:BUCKET_NAME");
static string appId = AppSettings.GetConfig("TENCENT_COS:APPID");
/// <summary>
/// 获取COS客户端
/// </summary>
/// <returns></returns>
private static CosXmlServer GetCosXmlServer()
{
var config = new CosXmlConfig.Builder()
.SetRegion(region)
.Build();
var qCloudCredentialProvider = new DefaultQCloudCredentialProvider(secretId, secretKey, 600);
return new CosXmlServer(config, qCloudCredentialProvider);
}
/// <summary>
/// 上传到腾讯云COS
/// </summary>
/// <param name="filestreams">文件流</param>
/// <param name="dirPath">存储路径 eg upload/2020/01/01/xxx.png</param>
/// <param name="bucketName">存储桶 如果为空默认取配置文件</param>
/// <returns></returns>
public static HttpStatusCode PutObjectFromFile(Stream filestreams, string dirPath, string bucketName = "")
{
if (string.IsNullOrEmpty(bucketName)) { bucketName = bucketName1; }
try
{
dirPath = dirPath.Replace("\\", "/");
var cosXml = GetCosXmlServer();
var request = new PutObjectRequest(bucketName, dirPath, filestreams);
request.APPID = appId;
var result = cosXml.PutObject(request);
return result.IsSuccessful() ? HttpStatusCode.OK : HttpStatusCode.BadRequest;
}
catch (COSXML.CosException.CosClientException ex)
{
Console.WriteLine("Failed with CosClientException: {0}", ex.Message);
}
catch (COSXML.CosException.CosServerException ex)
{
Console.WriteLine("Failed with CosServerException. ErrorCode: {0}; ErrorMessage: {1}; RequestID: {2}",
ex.errorCode, ex.Message, ex.requestId);
}
catch (Exception ex)
{
Console.WriteLine("Failed with error info: {0}", ex.Message);
}
return HttpStatusCode.BadRequest;
}
/// <summary>
/// 删除资源
/// </summary>
/// <param name="dirPath">文件路径</param>
/// <param name="bucketName">存储桶 如果为空默认取配置文件</param>
/// <returns></returns>
public static HttpStatusCode DeleteFile(string dirPath, string bucketName = "")
{
if (string.IsNullOrEmpty(bucketName)) { bucketName = bucketName1; }
try
{
dirPath = dirPath.Replace("\\", "/");
var cosXml = GetCosXmlServer();
var request = new DeleteObjectRequest(bucketName, dirPath);
var result = cosXml.DeleteObject(request);
return result.IsSuccessful() ? HttpStatusCode.OK : HttpStatusCode.BadRequest;
}
catch (COSXML.CosException.CosClientException ex)
{
Console.WriteLine("Failed with CosClientException: {0}", ex.Message);
}
catch (COSXML.CosException.CosServerException ex)
{
Console.WriteLine("Failed with CosServerException. ErrorCode: {0}; ErrorMessage: {1}; RequestID: {2}",
ex.errorCode, ex.errorMessage, ex.requestId);
}
catch (Exception ex)
{
Console.WriteLine("Failed with error info: {0}", ex.Message);
}
return HttpStatusCode.BadRequest;
}
}
}

View File

@ -8,6 +8,8 @@
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.14.1" />
<PackageReference Include="MailKit" Version="4.9.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.10" />
<PackageReference Include="Tencent.QCloud.Cos.Sdk" Version="5.4.49" />
</ItemGroup>
<ItemGroup>

View File

@ -31,6 +31,15 @@ namespace ZR.ServiceCore.Services
/// <returns></returns>
Task<SysFile> SaveFileToAliyun(SysFile file, UploadDto dto, IFormFile formFile);
/// <summary>
/// 上传文件到腾讯云
/// </summary>
/// <param name="file"></param>
/// <param name="dto"></param>
/// <param name="formFile"></param>
/// <returns></returns>
Task<SysFile> SaveFileToTencent(SysFile file, UploadDto dto, IFormFile formFile);
/// <summary>
/// 按时间来创建文件夹
/// </summary>

View File

@ -133,6 +133,42 @@ namespace ZR.ServiceCore.Services
return file;
}
/// <summary>
/// 上传文件到腾讯云
/// </summary>
/// <param name="file"></param>
/// <param name="dto"></param>
/// <param name="formFile"></param>
/// <returns></returns>
public async Task<SysFile> SaveFileToTencent(SysFile file, UploadDto dto, IFormFile formFile)
{
string tencentDomainUrl = AppSettings.GetConfig("TENCENT_COS:DOMAIN_URL");
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;
if (dto.Quality > 0)
{
// 压缩图片
using var stream = new MemoryStream();
await CompressImageAsync(formFile, stream, dto.Quality);
stream.Position = 0;
statusCode = TencentCosHelper.PutObjectFromFile(stream, finalPath, "");
}
else
{
statusCode = TencentCosHelper.PutObjectFromFile(formFile.OpenReadStream(), finalPath, "");
}
if (statusCode != HttpStatusCode.OK) return file;
file.StorePath = file.StorePath;
file.FileUrl = finalPath;
file.AccessUrl = string.Concat(tencentDomainUrl, "/", file.StorePath.Replace("\\", "/"), "/", file.FileName);
file.Id = await InsertFile(file);
return file;
}
/// <summary>
/// 获取文件存储目录
/// </summary>