using COSXML;
using COSXML.Auth;
using COSXML.Model;
using COSXML.Model.Object;
using Infrastructure;
using Infrastructure.Model;
using System;
using System.Collections.Generic;
using ZR.Model.Business.Dto;
namespace ZR.Common
{
///
/// 腾讯云COS服务
///
public class CosService
{
private static readonly TencentCOS _config;
private static readonly CosXml _cosXml;
private static readonly string _bucket;
static CosService()
{
_config = AppSettings.Get("TencentCOS") ?? new TencentCOS();
_bucket = $"{_config.BucketName}-{_config.AppId}";
// 初始化COS客户端
var cosConfig = new CosXmlConfig.Builder()
.IsHttps(true)
.SetRegion(_config.Region)
.SetDebugLog(false)
.Build();
var qCloudCredentialProvider = new DefaultQCloudCredentialProvider(
_config.SecretId,
_config.SecretKey,
_config.DurationSecond);
_cosXml = new CosXmlServer(cosConfig, qCloudCredentialProvider);
}
///
/// 生成批量上传预签名URL
///
/// 上传请求参数
/// 预签名URL列表
public static CosUploadUrlsResponse GetUploadUrls(CosUploadUrlsRequest request)
{
var response = new CosUploadUrlsResponse
{
Images = new List()
};
var recordTime = request.RecordTime;
var dateFolder = recordTime.ToString("yyyyMM");
var dayFolder = recordTime.ToString("yyyyMMdd");
var timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds();
for (int i = 0; i < request.ImageCount; i++)
{
var random = new Random().Next(1000, 9999);
var fileName = $"{timestamp}_{random}{i}{request.FileExt}";
var imageId = Guid.NewGuid().ToString("N");
var imageInfo = new CosImageUploadInfo
{
ImageId = imageId,
FileName = fileName,
UploadUrls = new CosUploadUrls
{
Workers = new Dictionary()
}
};
// 生成各分类目录的预签名URL
var basePath = $"{_config.Prefixes}/{dateFolder}/{dayFolder}";
// 1. 当日照片目录
var dailyPath = $"{basePath}/当日照片/{fileName}";
imageInfo.UploadUrls.Daily = GeneratePresignedUrl(dailyPath);
// 2. 参与人员目录(每个人员一个URL)
if (request.Workers != null)
{
foreach (var worker in request.Workers)
{
if (!string.IsNullOrWhiteSpace(worker))
{
var workerPath = $"{basePath}/参与人员/{worker}/{fileName}";
imageInfo.UploadUrls.Workers[worker] = GeneratePresignedUrl(workerPath);
}
}
}
// 3. 工作内容目录
if (!string.IsNullOrWhiteSpace(request.Content))
{
var contentPath = $"{basePath}/工作内容/{request.Content}/{fileName}";
imageInfo.UploadUrls.Content = GeneratePresignedUrl(contentPath);
}
// 4. 部门目录
if (!string.IsNullOrWhiteSpace(request.DeptName))
{
var deptPath = $"{basePath}/部门/{request.DeptName}/{fileName}";
imageInfo.UploadUrls.Dept = GeneratePresignedUrl(deptPath);
}
// 设置访问URL(使用当日照片目录作为主URL)
imageInfo.AccessUrl = $"{_config.DomainUrl}/{dailyPath}";
response.Images.Add(imageInfo);
}
return response;
}
///
/// 获取临时密钥(用于迁移)
///
/// 临时密钥信息
public static CosTempCredentials GetTempCredentials()
{
// 返回配置中的密钥信息(实际生产环境应使用STS临时密钥)
return new CosTempCredentials
{
SecretId = _config.SecretId,
SecretKey = _config.SecretKey,
Region = _config.Region,
Bucket = _bucket,
DomainUrl = _config.DomainUrl,
Prefixes = _config.Prefixes,
DurationSecond = _config.DurationSecond
};
}
///
/// 生成预签名URL
///
/// 对象键
/// 预签名URL
private static string GeneratePresignedUrl(string key)
{
try
{
// 使用PutObjectRequest生成预签名URL
var request = new PutObjectRequest(_bucket, key, new byte[0]);
var preSignatureStruct = new COSXML.Model.Tag.PreSignatureStruct
{
appid = _config.AppId,
region = _config.Region,
bucket = _bucket,
key = key,
httpMethod = "PUT",
isHttps = true,
signDurationSecond = _config.DurationSecond
};
return _cosXml.GenerateSignURL(preSignatureStruct);
}
catch (Exception ex)
{
Console.WriteLine($"生成预签名URL失败: {ex.Message}");
return string.Empty;
}
}
///
/// 验证是否为有效的COS URL
///
/// URL地址
/// 是否有效
public static bool IsValidCosUrl(string url)
{
if (string.IsNullOrWhiteSpace(url))
return false;
return url.StartsWith(_config.DomainUrl + "/" + _config.Prefixes + "/");
}
///
/// 获取COS域名
///
/// COS域名
public static string GetDomainUrl()
{
return _config.DomainUrl;
}
///
/// 获取路径前缀
///
/// 路径前缀
public static string GetPrefixes()
{
return _config.Prefixes;
}
}
}