WorkCamera/server/Zr.Admin.NET/ZR.Common/CosService.cs
2026-01-05 21:20:55 +08:00

200 lines
6.7 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
{
/// <summary>
/// 腾讯云COS服务
/// </summary>
public class CosService
{
private static readonly TencentCOS _config;
private static readonly CosXml _cosXml;
private static readonly string _bucket;
static CosService()
{
_config = AppSettings.Get<TencentCOS>("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);
}
/// <summary>
/// 生成批量上传预签名URL
/// </summary>
/// <param name="request">上传请求参数</param>
/// <returns>预签名URL列表</returns>
public static CosUploadUrlsResponse GetUploadUrls(CosUploadUrlsRequest request)
{
var response = new CosUploadUrlsResponse
{
Images = new List<CosImageUploadInfo>()
};
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<string, string>()
}
};
// 生成各分类目录的预签名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;
}
/// <summary>
/// 获取临时密钥(用于迁移)
/// </summary>
/// <returns>临时密钥信息</returns>
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
};
}
/// <summary>
/// 生成预签名URL
/// </summary>
/// <param name="key">对象键</param>
/// <returns>预签名URL</returns>
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;
}
}
/// <summary>
/// 验证是否为有效的COS URL
/// </summary>
/// <param name="url">URL地址</param>
/// <returns>是否有效</returns>
public static bool IsValidCosUrl(string url)
{
if (string.IsNullOrWhiteSpace(url))
return false;
return url.StartsWith(_config.DomainUrl + "/" + _config.Prefixes + "/");
}
/// <summary>
/// 获取COS域名
/// </summary>
/// <returns>COS域名</returns>
public static string GetDomainUrl()
{
return _config.DomainUrl;
}
/// <summary>
/// 获取路径前缀
/// </summary>
/// <returns>路径前缀</returns>
public static string GetPrefixes()
{
return _config.Prefixes;
}
}
}