Files
2026-10-29 11:52:09 +08:00

170 lines
6.3 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 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<Worker> _logger;
private readonly OssOptions _oss;
private DateTime lastUploadDate = DateTime.MinValue;
private readonly DingTalkNotifier _notifier;
private readonly OssClientFactory _ossClientFactory;
public Worker(IOptions<OssOptions> ossOpt, ILogger<Worker> 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);
}
}
}
/// <summary>
/// 将整个备份目录压缩为 ZIP 并上传,成功返回 true,否则 false
/// </summary>
private async Task<bool> 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);
}
}
}
}