using System.IO.Compression; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Aliyun.OSS; using Microsoft.Extensions.Options; using OssTJiaUploaderService; namespace OssZipUploaderService { public class Worker : BackgroundService { private readonly ILogger _logger; private readonly OssOptions _oss; private DateTime lastUploadDate = DateTime.MinValue; private readonly DingTalkNotifier _notifier; private readonly OssClientFactory _ossClientFactory; public Worker(IOptions ossOpt, ILogger logger, DingTalkNotifier notifier, OssClientFactory ossClientFactory) { _oss = ossOpt.Value; _logger = logger; _notifier = notifier; _ossClientFactory = ossClientFactory; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { Directory.CreateDirectory(Path.GetDirectoryName(_oss.logFile)!); while (!stoppingToken.IsCancellationRequested) { var now = DateTime.Now; await WriteLogAndNotifyAsync("开始执行,检查时间点"); if (now.Hour >= _oss.BgTime && now.Hour < _oss.EdTime && lastUploadDate.Date != now.Date) { await WriteLogAndNotifyAsync("尝试将备份目录打包并上传到 OSS..."); bool success = false; try { success = await UploadBackupZip(); } catch (Exception ex) { await WriteLogAndNotifyAsync($"打包或上传异常:{ex.Message}"); success = false; } if (success) { lastUploadDate = now.Date; await WriteLogAndNotifyAsync("上传成功,今日后续不再尝试。"); } else { await WriteLogAndNotifyAsync("上传失败,等待下一个周期重试。"); } } else { if (now.Hour >= _oss.BgTime && now.Hour < _oss.EdTime) { await WriteLogAndNotifyAsync($"当天已执行"); } else { await WriteLogAndNotifyAsync($"未到执行时间点:{_oss.BgTime}到{_oss.EdTime}"); } } await WriteLogAndNotifyAsync("执行结束"); if (_oss.TimeSpanType == 1) { await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken); } else // 默认每小时检查 { await Task.Delay(TimeSpan.FromHours(1), stoppingToken); } } } /// /// 将整个备份目录压缩为 ZIP 并上传,成功返回 true,否则 false /// private async Task UploadBackupZip() { if (!Directory.Exists(_oss.backupFolderPath)) { await WriteLogAndNotifyAsync("备份目录不存在。"); return false; } // 构建 ZIP 文件路径:F:\自动备份.zip var root = Path.GetPathRoot(_oss.backupFolderPath)!; var folderName = new DirectoryInfo(_oss.backupFolderPath).Name; var zipFileName = folderName + ".zip"; var zipFilePath = Path.Combine(root, zipFileName); try { // 删除旧 ZIP if (File.Exists(zipFilePath)) File.Delete(zipFilePath); // 创建 ZIP ZipFile.CreateFromDirectory( _oss.backupFolderPath, zipFilePath, CompressionLevel.Optimal, includeBaseDirectory: false); await WriteLogAndNotifyAsync($"已生成 ZIP:{zipFilePath},正在上传oss..."); // 上传到 OSS using var fs = File.OpenRead(zipFilePath); string objectKey = $"backupTJia/{zipFileName}"; var client = _ossClientFactory.CreateClient(); var result = client.PutObject(_oss.Bucket, objectKey, fs); if (result.HttpStatusCode == System.Net.HttpStatusCode.OK) { await WriteLogAndNotifyAsync($"上传成功:{zipFileName} -> https://{_oss.Bucket}.{_oss.Endpoint}/{objectKey}"); return true; } else { await WriteLogAndNotifyAsync($"上传失败,HTTP 状态码:{result.HttpStatusCode}"); return false; } } catch (Exception ex) { await WriteLogAndNotifyAsync($"打包或上传时发生异常:{ex.Message}"); return false; } } //private void WriteLog(string message) //{ // string log = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] {message}"; // File.AppendAllText(_oss.logFile, log + Environment.NewLine); // _logger.LogInformation(log); // SendMsg(log); //} //private async void SendMsg(string msg) //{ // await _notifier.SendTextAsync(_oss.WebhookUrl, $"备份说明:{_oss.Text}" + msg); //} private async Task WriteLogAndNotifyAsync(string message) { string log = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] {message}"; File.AppendAllText(_oss.logFile, log + Environment.NewLine); _logger.LogInformation(log); try { await _notifier.SendTextAsync(_oss.WebhookUrl, $"备份说明:{_oss.Text} {message}"); } catch (Exception ex) { string failMsg = $"发送钉钉消息失败:{ex.Message}"; File.AppendAllText(_oss.logFile, $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] {failMsg}" + Environment.NewLine); _logger.LogError(failMsg); } } } }