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; } } }