170 lines
6.3 KiB
C#
170 lines
6.3 KiB
C#
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);
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|