using System; using System.Collections; using System.IO; using System.Threading; using System.Threading.Tasks; using UnityEngine; using Aliyun.OSS; using Aliyun.OSS.Common; using Base.Helper; // AlibabaCloud.SDK.OSS.V2 public class AliyunOSSClient : MonoBehaviour { [Header("OSS配置")] public string accessKeyId = "LTAI5t9AcXJm2BXwzLTie8Wa"; public string accessKeySecret = "RJhANJfNL7Xr8EmEZfMR12ED5nIp8c"; public string endpoint = "oss-cn-hongkong.aliyuncs.com"; public string bucketName = "dev-bucket-plugcustom"; public string objectKeyPrefix = "KioskUploads/FujifilmKiosk/"; private OssClient _ossClient; private static AliyunOSSClient _instance; public static AliyunOSSClient Instance { get { if (_instance == null) { _instance = FindObjectOfType(); if (_instance == null) { GameObject obj = new GameObject("AliyunOSSClient"); _instance = obj.AddComponent(); DontDestroyOnLoad(obj); } } return _instance; } } private void Awake() { try { // 初始化OSS客户端 _ossClient = new OssClient(endpoint, accessKeyId, accessKeySecret); Debug.Log("OSS客户端初始化成功"); } catch (Exception ex) { Debug.LogError($"OSS客户端初始化失败: {ex.Message}"); } } /// /// 上传文件到OSS /// public void UploadFile(string localFilePath, Action onComplete, Action onProgress = null) { if (_ossClient == null) { onComplete?.Invoke(null, "OSS客户端未初始化"); return; } string fileName = Path.GetFileName(localFilePath); var bytes = File.ReadAllBytes(localFilePath); UploadFile(bytes, fileName, onComplete, onProgress); } public void UploadFile(byte[] bytes, string fileName, Action onComplete, Action onProgress = null) { StartCoroutine(UploadFileAsync(bytes, fileName, onComplete, onProgress)); } // 递归上传目录 private void UploadDirectory(OssClient client, string ossDirectory, string localDirectory, string ossRelativePath) { // 上传目录下的所有文件 foreach (var filePath in Directory.GetFiles(localDirectory)) { string fileName = Path.GetFileName(filePath); string ossObjectKey = $"{ossDirectory}/{ossRelativePath}/{fileName}"; // 上传文件 client.PutObject(bucketName, ossObjectKey, filePath); Debug.Log($"已上传: {ossObjectKey}"); } // 递归上传子目录 foreach (var subDirectory in Directory.GetDirectories(localDirectory)) { string dirName = Path.GetFileName(subDirectory) + "/"; UploadDirectory(client, ossDirectory, subDirectory, ossRelativePath + dirName); } } /// /// 使用IEnumerator实现的异步上传(字节数组版本) /// private IEnumerator UploadFileAsync(byte[] bytes, string fileName, Action onComplete, Action onProgress = null) { if (_ossClient == null) { onComplete?.Invoke(null, "OSS客户端未初始化"); yield break; } Debug.Log("upload oss start"); string objectKey = $"{objectKeyPrefix}{fileName}"; bool isCompleted = false; string resultUrl = null; string errorMsg = null; // 使用Task在后台线程执行上传 Task.Run(() => { try { using (var bodyStream = new MemoryStream(bytes)) { var request = new PutObjectRequest(bucketName, objectKey, bodyStream); // 进度回调处理 request.StreamTransferProgress += (sender, args) => { // 转换为MB显示 float downloadedMB = NetHelper.BytesToMB(args.TransferredBytes); float totalMB = NetHelper.BytesToMB(args.TotalBytes); // 更新UI string mbInfo = $"{downloadedMB:F2}MB / {totalMB:F2}MB"; onProgress?.Invoke(args.TransferredBytes, args.TotalBytes); Debug.Log($"upload oss progress: {mbInfo}"); // // 立即在主线程中触发进度回调 // UnityMainThreadDispatcher.Instance.Enqueue(() => // { // }); }; // 执行上传 var result = _ossClient.PutObject(request); Debug.Log($"上传状态码: {result.HttpStatusCode}"); // 上传成功 resultUrl = $"https://{bucketName}.{endpoint}/{objectKey}"; Debug.Log($"上传成功: {resultUrl}"); } } catch (OssException ex) { errorMsg = $"OSS错误: {ex.ErrorCode} - {ex.Message}"; Debug.LogError(errorMsg); isCompleted = true; } catch (Exception ex) { errorMsg = $"上传失败: {ex.Message}"; Debug.LogError(errorMsg); isCompleted = true; } finally { isCompleted = true; } }); // 等待后台任务完成 while (!isCompleted) { yield return null; } // 触发完成回调 onComplete?.Invoke(resultUrl, errorMsg); Debug.Log("upload oss finish"); } // 获取上传进度。 private void streamProgressCallback(object sender, StreamTransferProgressArgs args) { Debug.Log( $"ProgressCallback - Progress: {args.TransferredBytes * 100 / args.TotalBytes}%, TotalBytes:{args.TotalBytes}, TransferredBytes:{args.TransferredBytes} "); } }