From 10f156e9e2a356928555befc5eb977761be41d0b Mon Sep 17 00:00:00 2001
From: ShaoHua <345265198@qqcom>
Date: Wed, 8 Apr 2026 19:28:02 +0800
Subject: [PATCH] =?UTF-8?q?=E5=8F=98=E6=9B=B4=E8=AF=A6=E6=83=85=E6=91=98?=
=?UTF-8?q?=E8=A6=81=EF=BC=9A?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 功能增强 :
- AliSslProvider.cs :实现了从阿里云获取证书列表及删除过期证书的逻辑。
- TencentSslProvider.cs :增加了腾讯云过期证书的清理功能。
- ISslDownloadProvider.cs :扩展了接口协议,并丰富了 SslCertificate 模型属性。
- 任务调度 :
- Program.cs :集成了 SslDownloadJob 到 Quartz 框架中,支持自动化运行。
- 文档与规范 :
- 对项目关键入口和 Provider 进行了全面的代码注释补全。
---
Hua.DDNS.Test/appsettings.Development.json | 66 ++++++++++++++
Hua.DDNS.sln | 31 -------
Hua.DDNS.slnx | 4 +
.../Common/Config/Options/AliCloudOption.cs | 18 ++++
Hua.DDNS/Common/Config/Options/AppOption.cs | 6 +-
.../Common/Config/Options/PlatformEnum.cs | 8 +-
.../Config/Options/SslDownloadOption.cs | 45 ++++++++++
.../Config/Options/TencentCloudOption.cs | 18 ++++
Hua.DDNS/Common/Config/SettingProvider.cs | 12 ++-
Hua.DDNS/Common/FileHelper.cs | 9 +-
Hua.DDNS/Common/Http/HttpHelper.cs | 88 +++++++++++++++----
Hua.DDNS/Common/Http/HttpResult.cs | 18 +++-
Hua.DDNS/Common/SqlHelper.cs | 18 ++--
Hua.DDNS/DDNSProviders/Ali/AliDDNSProvider.cs | 34 +++++--
Hua.DDNS/DDNSProviders/DDNSOption.cs | 10 +--
.../Dnspod/DnspodDDNSProvider.cs | 33 ++++++-
Hua.DDNS/DDNSProviders/Dnspod/DnspodOption.cs | 4 +-
Hua.DDNS/DDNSProviders/IDDNSProvider.cs | 27 +++---
.../Namesilo/NamesiloDDNSProvider.cs | 33 ++++++-
.../DDNSProviders/Namesilo/NamesiloOption.cs | 6 +-
Hua.DDNS/Jobs/NewJob.cs | 24 ++++-
Hua.DDNS/Jobs/SslDownloadJob.cs | 29 ++++++
Hua.DDNS/Models/DnsRecord.cs | 40 ++++++++-
Hua.DDNS/Models/MappingProfile.cs | 8 +-
Hua.DDNS/SslProviders/Ali/AliSslProvider.cs | 84 +++++++++++++++++-
Hua.DDNS/SslProviders/ISslDownloadProvider.cs | 51 +++++++++++
.../Tencent/TencentSslProvider.cs | 55 ++++++++++++
Hua.DDNS/Start/Program.cs | 57 ++++++++----
28 files changed, 715 insertions(+), 121 deletions(-)
create mode 100644 Hua.DDNS.Test/appsettings.Development.json
delete mode 100644 Hua.DDNS.sln
create mode 100644 Hua.DDNS.slnx
diff --git a/Hua.DDNS.Test/appsettings.Development.json b/Hua.DDNS.Test/appsettings.Development.json
new file mode 100644
index 0000000..0fbec48
--- /dev/null
+++ b/Hua.DDNS.Test/appsettings.Development.json
@@ -0,0 +1,66 @@
+{
+ "ConnectionStrings": {
+ "pgConnection": "Host=127.0.0.1;Port=5432;Database=Worker;Username=Worker;Password=123456;"
+ },
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.Hosting.Lifetime": "Information"
+ }
+ },
+ "App": {
+ "GetIpv4Url": "http://47.108.74.59:8001/api/NetWork/GetIp",
+ "AppJob": {
+ "Corn": "0/5 * * * * ?" //https://cron.qqe2.com/
+ }
+ },
+ "DDNS": {
+ "Platform": 2, //1 Ali 2 Tencent 3 Namesilo
+ // 主域名
+ "Domain": "we965.cn",
+ // 子域名前缀
+ "SubDomainArray": [ "mp", "git", "webutil", "dev", "sftp" ],
+ // 记录类型
+ "type": "A",
+ //间隔时间 秒
+ "time": "30"
+ },
+ "SslDownload": {
+ "Enabled": true,
+ "Corn": "0/5 * * * * ?", //https://cron.qqe2.com/
+ "Platform": 2,
+ "SavePath": "D:\\Paths\\ssl",
+ "ExpireDays": 5,
+ "DownloadItems": [
+ {
+ "Domain": "git.we965.cn",
+ "FileName": "git.we965.cn.pem"
+ },
+ {
+ "Domain": "webutil.we965.cn",
+ "FileName": "webutil.we965.cn.pem"
+ },
+ {
+ "Domain": "dev.we965.cn",
+ "FileName": "dev.we965.cn.pem"
+ }
+ ]
+ },
+ "TencentCloud": {
+ "SecretId": "AKIDy35008NYm6T1v3R3gGtU1UIHOe0NizON",
+ "SecretKey": "1sXQmASfmmlwAXuDh8fVYUOLI7mJagbQ",
+ "Region": "ap-guangzhou",
+ "Dnspod": {
+ "Endpoint": "dnspod.tencentcloudapi.com"
+ }
+ },
+ "AliCloud": {
+ "AccessKeyId": "1111",
+ "AccessKeySecret": "1111",
+ "RegionId": "cn-hangzhou",
+ "Endpoint": "1111"
+ },
+ "Namesilo": {
+ "ApiKey": "1111"
+ }
+}
\ No newline at end of file
diff --git a/Hua.DDNS.sln b/Hua.DDNS.sln
deleted file mode 100644
index 0dabc6c..0000000
--- a/Hua.DDNS.sln
+++ /dev/null
@@ -1,31 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 17
-VisualStudioVersion = 17.2.32616.157
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hua.DDNS", "Hua.DDNS\Hua.DDNS.csproj", "{EBC77B5D-87D5-4923-84A6-93DB2248DEB0}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hua.DDNS.Test", "Hua.DDNS.Test\Hua.DDNS.Test.csproj", "{BB544060-5ABF-4A3C-965B-BE7CA7BD61E7}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {EBC77B5D-87D5-4923-84A6-93DB2248DEB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {EBC77B5D-87D5-4923-84A6-93DB2248DEB0}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {EBC77B5D-87D5-4923-84A6-93DB2248DEB0}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {EBC77B5D-87D5-4923-84A6-93DB2248DEB0}.Release|Any CPU.Build.0 = Release|Any CPU
- {BB544060-5ABF-4A3C-965B-BE7CA7BD61E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {BB544060-5ABF-4A3C-965B-BE7CA7BD61E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {BB544060-5ABF-4A3C-965B-BE7CA7BD61E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {BB544060-5ABF-4A3C-965B-BE7CA7BD61E7}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {D8744CA6-C2DB-4287-B8B3-E5917B12391D}
- EndGlobalSection
-EndGlobal
diff --git a/Hua.DDNS.slnx b/Hua.DDNS.slnx
new file mode 100644
index 0000000..131ef7f
--- /dev/null
+++ b/Hua.DDNS.slnx
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/Hua.DDNS/Common/Config/Options/AliCloudOption.cs b/Hua.DDNS/Common/Config/Options/AliCloudOption.cs
index 4282f6e..55c37bd 100644
--- a/Hua.DDNS/Common/Config/Options/AliCloudOption.cs
+++ b/Hua.DDNS/Common/Config/Options/AliCloudOption.cs
@@ -1,10 +1,28 @@
namespace Hua.DDNS.Common.Config.Options
{
+ ///
+ /// 阿里云配置选项
+ ///
public class AliCloudOption
{
+ ///
+ /// 访问密钥 ID
+ ///
public string AccessKeyId { get; set; }
+
+ ///
+ /// 访问密钥私钥
+ ///
public string AccessKeySecret { get; set; }
+
+ ///
+ /// 区域 ID (如 cn-hangzhou)
+ ///
public string RegionId { get; set; }
+
+ ///
+ /// 访问端点 (可选)
+ ///
public string Endpoint { get; set; }
}
}
diff --git a/Hua.DDNS/Common/Config/Options/AppOption.cs b/Hua.DDNS/Common/Config/Options/AppOption.cs
index dd78b60..8511d54 100644
--- a/Hua.DDNS/Common/Config/Options/AppOption.cs
+++ b/Hua.DDNS/Common/Config/Options/AppOption.cs
@@ -1,16 +1,16 @@
-using Hua.DDNS.DDNSProviders;
+using Hua.DDNS.DDNSProviders;
namespace Hua.DDNS.Common.Config.Options
{
///
- /// app configuration class
+ /// 应用程序全局配置类
///
public class AppOption
{
///
- /// domain configuration
+ /// DDNS 相关配置
///
public DdnsOption DDNS { get; set; }
diff --git a/Hua.DDNS/Common/Config/Options/PlatformEnum.cs b/Hua.DDNS/Common/Config/Options/PlatformEnum.cs
index 2aacd69..6f5871a 100644
--- a/Hua.DDNS/Common/Config/Options/PlatformEnum.cs
+++ b/Hua.DDNS/Common/Config/Options/PlatformEnum.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -7,17 +7,17 @@ using System.Threading.Tasks;
namespace Hua.DDNS.Common.Config.Options
{
///
- /// DDNS Platform
+ /// DDNS 平台类型枚举
///
public enum PlatformEnum
{
///
- /// Ali
+ /// 阿里云
///
Ali = 1,
///
- /// Tencent
+ /// 腾讯云
///
Tencent,
diff --git a/Hua.DDNS/Common/Config/Options/SslDownloadOption.cs b/Hua.DDNS/Common/Config/Options/SslDownloadOption.cs
index 816ac64..e19a736 100644
--- a/Hua.DDNS/Common/Config/Options/SslDownloadOption.cs
+++ b/Hua.DDNS/Common/Config/Options/SslDownloadOption.cs
@@ -1,24 +1,69 @@
namespace Hua.DDNS.Common.Config.Options
{
+ ///
+ /// SSL 证书来源平台枚举
+ ///
public enum SslPlatformEnum
{
+ ///
+ /// 阿里云
+ ///
Ali = 1,
+ ///
+ /// 腾讯云
+ ///
Tencent = 2
}
+ ///
+ /// SSL 证书下载配置选项
+ ///
public class SslDownloadOption
{
+ ///
+ /// 是否启用
+ ///
public bool Enabled { get; set; }
+
+ ///
+ /// Cron 定时表达式
+ ///
public string Corn { get; set; }
+
+ ///
+ /// 云平台类型
+ ///
public SslPlatformEnum Platform { get; set; }
+
+ ///
+ /// 证书保存本地路径
+ ///
public string SavePath { get; set; }
+
+ ///
+ /// 过期天数阈值 (提前多少天开始下载更新)
+ ///
public int ExpireDays { get; set; }
+
+ ///
+ /// 需要下载的证书列表
+ ///
public List DownloadItems { get; set; }
}
+ ///
+ /// SSL 证书下载项详情
+ ///
public class SslDownloadItem
{
+ ///
+ /// 域名
+ ///
public string Domain { get; set; }
+
+ ///
+ /// 保存到本地的文件名 (不含后缀)
+ ///
public string FileName { get; set; }
}
}
diff --git a/Hua.DDNS/Common/Config/Options/TencentCloudOption.cs b/Hua.DDNS/Common/Config/Options/TencentCloudOption.cs
index 6ba4ec8..225e6e2 100644
--- a/Hua.DDNS/Common/Config/Options/TencentCloudOption.cs
+++ b/Hua.DDNS/Common/Config/Options/TencentCloudOption.cs
@@ -2,11 +2,29 @@ using Hua.DDNS.DDNSProviders.Dnspod;
namespace Hua.DDNS.Common.Config.Options
{
+ ///
+ /// 腾讯云配置选项
+ ///
public class TencentCloudOption
{
+ ///
+ /// 密钥 ID
+ ///
public string SecretId { get; set; }
+
+ ///
+ /// 密钥私钥
+ ///
public string SecretKey { get; set; }
+
+ ///
+ /// 区域 (如 ap-guangzhou)
+ ///
public string Region { get; set; }
+
+ ///
+ /// Dnspod 相关配置 (已并入腾讯云)
+ ///
public DnspodOption Dnspod { get; set; }
}
}
diff --git a/Hua.DDNS/Common/Config/SettingProvider.cs b/Hua.DDNS/Common/Config/SettingProvider.cs
index 52a053f..692c3bf 100644
--- a/Hua.DDNS/Common/Config/SettingProvider.cs
+++ b/Hua.DDNS/Common/Config/SettingProvider.cs
@@ -1,15 +1,20 @@
-using Hua.DDNS.Common.Config.Options;
+using Hua.DDNS.Common.Config.Options;
namespace Hua.DDNS.Common.Config
{
///
- /// this is a strongly-typed configuration provider
+ /// 强类型配置提供者,用于方便地访问应用程序配置
///
public class SettingProvider
{
private readonly AppOption _app;
private readonly IConfiguration _configuration;
+
+ ///
+ /// 构造函数
+ ///
+ /// 配置对象
public SettingProvider(IConfiguration configuration)
{
_configuration = configuration;
@@ -17,6 +22,9 @@ namespace Hua.DDNS.Common.Config
_configuration.GetSection("App").Bind(_app);
}
+ ///
+ /// 获取应用程序配置选项
+ ///
public AppOption App => _app;
}
diff --git a/Hua.DDNS/Common/FileHelper.cs b/Hua.DDNS/Common/FileHelper.cs
index 5afd469..6cf07f3 100644
--- a/Hua.DDNS/Common/FileHelper.cs
+++ b/Hua.DDNS/Common/FileHelper.cs
@@ -1,7 +1,14 @@
-namespace Hua.DDNS.Common
+namespace Hua.DDNS.Common
{
+ ///
+ /// 文件操作助手类
+ ///
public class FileHelper
{
+ ///
+ /// 如果文件存在则删除
+ ///
+ /// 文件路径
public static void DeleteIfExists(string path)
{
if (File.Exists(path))
diff --git a/Hua.DDNS/Common/Http/HttpHelper.cs b/Hua.DDNS/Common/Http/HttpHelper.cs
index 11854e2..3b5f4e9 100644
--- a/Hua.DDNS/Common/Http/HttpHelper.cs
+++ b/Hua.DDNS/Common/Http/HttpHelper.cs
@@ -1,15 +1,23 @@
-using System.Net;
+using System.Net;
using System.Net.Http.Json;
using Newtonsoft.Json;
namespace Hua.DDNS.Common.Http
{
+ ///
+ /// Http 请求助手类,用于执行各种 HTTP 请求
+ ///
public class HttpHelper: IHttpHelper
{
private static ILogger _logger;
private static HttpClientHandler _handler;
private IConfiguration _configuration;
+ ///
+ /// 构造函数
+ ///
+ /// 日志对象
+ /// 配置对象
public HttpHelper(ILogger logger, IConfiguration configuration)
{
_logger = logger;
@@ -17,26 +25,30 @@ namespace Hua.DDNS.Common.Http
_handler = new HttpClientHandler();
}
+ ///
+ /// 获取 HttpClient 实例
+ ///
+ /// HttpClient 实例
public HttpClient GetHttpClient()
{
return new HttpClient(_handler){};
}
///
- /// PostAsync
+ /// 异步执行 Post 请求并解析 JSON 结果
///
- ///
- ///
- ///
- ///
- /// 超时时间
- ///
+ /// 输入数据类型
+ /// 输出结果类型
+ /// 请求地址
+ /// 输入数据
+ /// 超时时间 (秒)
+ /// 解析后的结果对象
public async Task PostAsync(string url, TIn input, int timeOut = 10)
{
try
{
var client = GetHttpClient();
- client.Timeout = new TimeSpan(0, 10, timeOut);
+ client.Timeout = TimeSpan.FromSeconds(timeOut);
_logger.LogDebug($"Post:{url}\n[{JsonConvert.SerializeObject(input)}]");
var result = await client.PostAsync(url, JsonContent.Create(input));
var strResult = await result.Content.ReadAsStringAsync();
@@ -55,18 +67,18 @@ namespace Hua.DDNS.Common.Http
}
///
- /// PostAsync
+ /// 异步执行 Get 请求并解析 JSON 结果
///
- ///
- ///
- ///
- ///
+ /// 输出结果类型
+ /// 请求地址
+ /// 超时时间 (秒)
+ /// 解析后的结果对象
public async Task GetAsync(string url,int timeOut = 10)
{
try
{
var client = GetHttpClient();
- client.Timeout = new TimeSpan(0, 10, timeOut);
+ client.Timeout = TimeSpan.FromSeconds(timeOut);
_logger.LogDebug($"Get:{url}");
var result = await client.GetAsync(url);
var strResult = await result.Content.ReadAsStringAsync();
@@ -87,11 +99,11 @@ namespace Hua.DDNS.Common.Http
#region 下载文件
///
- /// http下载文件
+ /// 通过 HTTP 下载文件
///
/// 下载文件地址
- /// 文件存放地址,包含文件名
- ///
+ /// 文件本地存放路径,包含文件名
+ /// 下载成功返回 true,否则返回 false
public bool DownloadFile(string url, string localPath)
{
try
@@ -134,8 +146,9 @@ namespace Hua.DDNS.Common.Http
///
- /// 获得当前机器的公网 Ip
+ /// 获取当前机器的公网 IPv4 地址
///
+ /// IPv4 地址字符串
public async Task GetCurrentPublicIpv4()
{
using var client = new HttpClient();
@@ -146,12 +159,49 @@ namespace Hua.DDNS.Common.Http
}
+ ///
+ /// Http 助手接口
+ ///
public interface IHttpHelper
{
+ ///
+ /// 获取当前机器的公网 IPv4 地址
+ ///
+ /// IPv4 地址字符串
public Task GetCurrentPublicIpv4();
+
+ ///
+ /// 异步执行 Post 请求并解析 JSON 结果
+ ///
+ /// 输入数据类型
+ /// 输出结果类型
+ /// 请求地址
+ /// 输入数据
+ /// 超时时间 (秒)
+ /// 解析后的结果对象
public Task PostAsync(string url, TIn input, int timeOut = 10);
+
+ ///
+ /// 异步执行 Get 请求并解析 JSON 结果
+ ///
+ /// 输出结果类型
+ /// 请求地址
+ /// 超时时间 (秒)
+ /// 解析后的结果对象
public Task GetAsync(string url, int timeOut = 10);
+
+ ///
+ /// 通过 HTTP 下载文件
+ ///
+ /// 下载文件地址
+ /// 文件本地存放路径,包含文件名
+ /// 下载成功返回 true,否则返回 false
public bool DownloadFile(string url, string fileFullName);
+
+ ///
+ /// 获取 HttpClient 实例
+ ///
+ /// HttpClient 实例
public HttpClient GetHttpClient();
}
}
diff --git a/Hua.DDNS/Common/Http/HttpResult.cs b/Hua.DDNS/Common/Http/HttpResult.cs
index a48e482..632e2b6 100644
--- a/Hua.DDNS/Common/Http/HttpResult.cs
+++ b/Hua.DDNS/Common/Http/HttpResult.cs
@@ -1,13 +1,29 @@
-namespace Hua.DDNS.Common.Http
+namespace Hua.DDNS.Common.Http
{
+ ///
+ /// Http 请求返回结果包装类
+ ///
+ /// 数据类型
public class HttpResult
{
+ ///
+ /// 返回的数据内容
+ ///
public virtual T Data { get; set; }
+ ///
+ /// 数据描述信息
+ ///
public string DataDescription { get; set; }
+ ///
+ /// 结果状态码 (例如 200 为成功)
+ ///
public int Result { get; set; }
+ ///
+ /// 返回的消息提示
+ ///
public string Message { get; set; }
}
diff --git a/Hua.DDNS/Common/SqlHelper.cs b/Hua.DDNS/Common/SqlHelper.cs
index 6c39ca6..98a9ce2 100644
--- a/Hua.DDNS/Common/SqlHelper.cs
+++ b/Hua.DDNS/Common/SqlHelper.cs
@@ -1,15 +1,23 @@
-using System.Data;
+using System.Data;
using Dapper;
using Npgsql;
namespace Hua.DDNS.Common
{
+ ///
+ /// 数据库操作助手类 (基于 Npgsql 和 Dapper)
+ ///
public class SqlHelper
{
private readonly string _connectionString;
private readonly ILogger _logger;
+ ///
+ /// 构造函数
+ ///
+ /// 配置对象
+ /// 日志对象
public SqlHelper(IConfiguration configuration, ILogger logger)
{
_logger = logger;
@@ -19,10 +27,10 @@ namespace Hua.DDNS.Common
///
/// 查询所有结果
///
- ///
- ///
- ///
- ///
+ /// 实体类型
+ /// SQL 语句
+ /// 结果列表
+ /// 数据库连接或查询异常
public List GetList(string strSql)
{
var list = new List();
diff --git a/Hua.DDNS/DDNSProviders/Ali/AliDDNSProvider.cs b/Hua.DDNS/DDNSProviders/Ali/AliDDNSProvider.cs
index 5641335..14febf7 100644
--- a/Hua.DDNS/DDNSProviders/Ali/AliDDNSProvider.cs
+++ b/Hua.DDNS/DDNSProviders/Ali/AliDDNSProvider.cs
@@ -16,7 +16,7 @@ namespace Hua.DDNS.DDNSProviders.Ali
{
///
- /// DDNSProvider for Ali
+ /// 阿里云 DDNS 解析提供者
///
public class AliDdnsProvider : IDdnsProvider
{
@@ -25,6 +25,12 @@ namespace Hua.DDNS.DDNSProviders.Ali
private readonly DdnsOption _ddnsOption;
private readonly IMapper _mapper;
+ ///
+ /// 构造函数
+ ///
+ /// 阿里云配置
+ /// 对象映射器
+ /// DDNS 配置
public AliDdnsProvider(IOptions aliCloudOption, IMapper mapper,IOptions ddnsOption)
{
_aliCloudOption = aliCloudOption.Value;
@@ -41,9 +47,9 @@ namespace Hua.DDNS.DDNSProviders.Ali
}
///
- /// 获取解析记录列表
+ /// 异步获取阿里云上的域名解析记录列表
///
- ///
+ /// 解析记录列表
public async Task?> GetRecordListAsync()
{
var record = (await _client.DescribeDomainRecordsAsync(new DescribeDomainRecordsRequest()
@@ -54,6 +60,11 @@ namespace Hua.DDNS.DDNSProviders.Ali
return _mapper.Map>(record);
}
+ ///
+ /// 异步在阿里云上创建新的域名解析记录
+ ///
+ /// 解析记录信息
+ /// 创建后的解析记录信息
public async Task CreateDnsRecordAsync(DnsRecord record)
{
var rep = await _client.AddDomainRecordAsync(_mapper.Map(record));
@@ -61,11 +72,11 @@ namespace Hua.DDNS.DDNSProviders.Ali
}
///
- /// 变更解析记录列表
+ /// 异步批量修改阿里云上的域名解析记录
///
- ///
- ///
- ///
+ /// 新的 IP 地址
+ /// 需要修改的解析记录列表
+ /// 修改后的解析记录列表
public async Task> ModifyRecordListAsync(string newIp, IEnumerable records)
{
foreach (var aliDomainRecord in records)
@@ -75,5 +86,14 @@ namespace Hua.DDNS.DDNSProviders.Ali
return records;
}
+
+ ///
+ /// 异步清理无效证书
+ ///
+ ///
+ public Task CleanInvalidCertificatesAsync()
+ {
+ return Task.CompletedTask;
+ }
}
}
diff --git a/Hua.DDNS/DDNSProviders/DDNSOption.cs b/Hua.DDNS/DDNSProviders/DDNSOption.cs
index 37b5ad6..c9b3e16 100644
--- a/Hua.DDNS/DDNSProviders/DDNSOption.cs
+++ b/Hua.DDNS/DDNSProviders/DDNSOption.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -9,22 +9,22 @@ using Hua.DDNS.DDNSProviders.Namesilo;
namespace Hua.DDNS.DDNSProviders
{
///
- /// domain configuration class
+ /// DDNS 配置选项类
///
public class DdnsOption
{
///
- /// platform from 1 Ali 2 Tencent 3
+ /// 云平台类型 (1: 阿里云, 2: 腾讯云, 3: Namesilo)
///
public PlatformEnum Platform { get; set; }
///
- /// domain
+ /// 根域名 (例如: example.com)
///
public string Domain { get; set; }
///
- /// sub domain, eg. www,git
+ /// 需要更新的子域名列表 (例如: ["www", "api", "@"])
///
public string[] SubDomainArray { get; set; }
diff --git a/Hua.DDNS/DDNSProviders/Dnspod/DnspodDDNSProvider.cs b/Hua.DDNS/DDNSProviders/Dnspod/DnspodDDNSProvider.cs
index caba936..fe39866 100644
--- a/Hua.DDNS/DDNSProviders/Dnspod/DnspodDDNSProvider.cs
+++ b/Hua.DDNS/DDNSProviders/Dnspod/DnspodDDNSProvider.cs
@@ -18,8 +18,7 @@ namespace Hua.DDNS.DDNSProviders.Dnspod
{
///
- /// DdnsProvider for Dnspod
- ///
+ /// Dnspod (腾讯云) DDNS 解析提供者
///
public class DnspodDdnsProvider : IDdnsProvider
{
@@ -29,6 +28,12 @@ namespace Hua.DDNS.DDNSProviders.Dnspod
private readonly DdnsOption _ddnsOption;
private readonly IMapper _mapper;
+ ///
+ /// 构造函数
+ ///
+ /// 对象映射器
+ /// 腾讯云配置
+ /// DDNS 配置
public DnspodDdnsProvider(IMapper mapper, IOptions tencentCloudOption, IOptions ddnsOption)
{
_mapper = mapper;
@@ -44,6 +49,10 @@ namespace Hua.DDNS.DDNSProviders.Dnspod
});
}
+ ///
+ /// 异步获取 Dnspod 上的域名解析记录列表
+ ///
+ /// 解析记录列表
public async Task?> GetRecordListAsync()
{
var recordList = (await _client.DescribeRecordList(new DescribeRecordListRequest() { Domain = _ddnsOption.Domain })).RecordList;
@@ -51,6 +60,11 @@ namespace Hua.DDNS.DDNSProviders.Dnspod
return _mapper.Map>(recordList);
}
+ ///
+ /// 异步在 Dnspod 上创建新的域名解析记录
+ ///
+ /// 解析记录信息
+ /// 创建后的解析记录信息
public async Task CreateDnsRecordAsync(DnsRecord record)
{
var response = await _client.CreateRecord(new CreateRecordRequest()
@@ -64,6 +78,12 @@ namespace Hua.DDNS.DDNSProviders.Dnspod
return record;
}
+ ///
+ /// 异步批量修改 Dnspod 上的域名解析记录
+ ///
+ /// 新的 IP 地址
+ /// 需要修改的解析记录列表
+ /// 修改后的解析记录列表
public async Task> ModifyRecordListAsync(string newIp, IEnumerable records)
{
var rep = await _client.ModifyRecordBatch(new ModifyRecordBatchRequest()
@@ -74,5 +94,14 @@ namespace Hua.DDNS.DDNSProviders.Dnspod
});
return records;
}
+
+ ///
+ /// 异步清理无效证书
+ ///
+ ///
+ public Task CleanInvalidCertificatesAsync()
+ {
+ return Task.CompletedTask;
+ }
}
}
diff --git a/Hua.DDNS/DDNSProviders/Dnspod/DnspodOption.cs b/Hua.DDNS/DDNSProviders/Dnspod/DnspodOption.cs
index 29ea299..c64a4b8 100644
--- a/Hua.DDNS/DDNSProviders/Dnspod/DnspodOption.cs
+++ b/Hua.DDNS/DDNSProviders/Dnspod/DnspodOption.cs
@@ -1,12 +1,12 @@
namespace Hua.DDNS.DDNSProviders.Dnspod
{
///
- /// domain configuration Dnspod
+ /// Dnspod 配置选项
///
public class DnspodOption
{
///
- /// Endpoint dnspod.tencentcloudapi.com
+ /// 接口访问端点 (例如: dnspod.tencentcloudapi.com)
///
public string Endpoint { get; set; }
}
diff --git a/Hua.DDNS/DDNSProviders/IDDNSProvider.cs b/Hua.DDNS/DDNSProviders/IDDNSProvider.cs
index 3cce1b6..b8244ac 100644
--- a/Hua.DDNS/DDNSProviders/IDDNSProvider.cs
+++ b/Hua.DDNS/DDNSProviders/IDDNSProvider.cs
@@ -9,32 +9,37 @@ namespace Hua.DDNS.DDNSProviders
{
///
- /// Dynamic domain name resolution provider
+ /// 动态域名解析 (DDNS) 提供者接口
///
public interface IDdnsProvider
{
///
- /// 获取域名解析记录列表
+ /// 异步获取域名解析记录列表
///
- ///
-
+ /// 域名解析记录列表
Task?> GetRecordListAsync();
///
- /// 创建解析记录
+ /// 异步创建新的域名解析记录
///
- ///
- ///
+ /// 解析记录信息
+ /// 创建后的解析记录信息
Task CreateDnsRecordAsync(DnsRecord record);
///
- /// 修改域名解析记录
+ /// 异步批量修改域名解析记录 (通常用于更新 IP)
///
- ///
- ///
- ///
+ /// 新的 IP 地址
+ /// 需要修改的解析记录列表
+ /// 修改后的解析记录列表
Task> ModifyRecordListAsync(string newIp, IEnumerable records);
+ ///
+ /// 异步清理无效证书
+ ///
+ ///
+ Task CleanInvalidCertificatesAsync();
+
}
}
diff --git a/Hua.DDNS/DDNSProviders/Namesilo/NamesiloDDNSProvider.cs b/Hua.DDNS/DDNSProviders/Namesilo/NamesiloDDNSProvider.cs
index 976adb7..0fa57c2 100644
--- a/Hua.DDNS/DDNSProviders/Namesilo/NamesiloDDNSProvider.cs
+++ b/Hua.DDNS/DDNSProviders/Namesilo/NamesiloDDNSProvider.cs
@@ -1,4 +1,4 @@
-using System.Xml;
+using System.Xml;
using AutoMapper;
using Hua.DDNS.Models;
using Microsoft.Extensions.Hosting;
@@ -8,13 +8,18 @@ using Newtonsoft.Json;
namespace Hua.DDNS.DDNSProviders.Namesilo
{
///
- /// DDNSProvider for namesilo
+ /// Namesilo DDNS 解析提供者
///
public class NamesiloDdnsProvider : IDdnsProvider
{
public readonly NamesiloOption _namesiloOption;
public readonly DdnsOption _ddnsOption;
+ ///
+ /// 构造函数
+ ///
+ /// Namesilo 配置
+ /// DDNS 配置
public NamesiloDdnsProvider(IOptions namesiloOption, IOptions ddnsOption)
{
_ddnsOption = ddnsOption.Value;
@@ -22,6 +27,10 @@ namespace Hua.DDNS.DDNSProviders.Namesilo
}
+ ///
+ /// 异步获取 Namesilo 上的域名解析记录列表
+ ///
+ /// 解析记录列表
public async Task?> GetRecordListAsync()
{
var client = new HttpClient();
@@ -62,6 +71,11 @@ namespace Hua.DDNS.DDNSProviders.Namesilo
}).ToList();
}
+ ///
+ /// 异步在 Namesilo 上创建新的域名解析记录
+ ///
+ /// 解析记录信息
+ /// 创建后的解析记录信息
public async Task CreateDnsRecordAsync(DnsRecord dnsRecord)
{
var host = dnsRecord.Host[..(dnsRecord.Host.Length - dnsRecord.Domain.Length - 1)];
@@ -91,6 +105,12 @@ namespace Hua.DDNS.DDNSProviders.Namesilo
return dnsRecord;
}
+ ///
+ /// 异步批量修改 Namesilo 上的域名解析记录
+ ///
+ /// 新的 IP 地址
+ /// 需要修改的解析记录列表
+ /// 修改后的解析记录列表
public async Task> ModifyRecordListAsync(string newIp, IEnumerable records)
{
foreach (var dnsRecord in records)
@@ -122,5 +142,14 @@ namespace Hua.DDNS.DDNSProviders.Namesilo
return records;
}
+
+ ///
+ /// 异步清理无效证书
+ ///
+ ///
+ public Task CleanInvalidCertificatesAsync()
+ {
+ return Task.CompletedTask;
+ }
}
}
\ No newline at end of file
diff --git a/Hua.DDNS/DDNSProviders/Namesilo/NamesiloOption.cs b/Hua.DDNS/DDNSProviders/Namesilo/NamesiloOption.cs
index 1f116e1..f5eb92b 100644
--- a/Hua.DDNS/DDNSProviders/Namesilo/NamesiloOption.cs
+++ b/Hua.DDNS/DDNSProviders/Namesilo/NamesiloOption.cs
@@ -1,14 +1,14 @@
-namespace Hua.DDNS.DDNSProviders.Namesilo
+namespace Hua.DDNS.DDNSProviders.Namesilo
{
///
- /// Namesilo Option
+ /// Namesilo 配置选项
///
public class NamesiloOption
{
///
- /// API key
+ /// API 密钥
///
public string ApiKey { get; set; }
diff --git a/Hua.DDNS/Jobs/NewJob.cs b/Hua.DDNS/Jobs/NewJob.cs
index edfc156..f6252e3 100644
--- a/Hua.DDNS/Jobs/NewJob.cs
+++ b/Hua.DDNS/Jobs/NewJob.cs
@@ -25,6 +25,9 @@ using System.Net.Sockets;
namespace Hua.DDNS.Jobs
{
+ ///
+ /// 新的 DDNS 任务类,用于定期检查并更新域名解析记录
+ ///
[DisallowConcurrentExecution]
public class NewJob : IJob, IDisposable
{
@@ -32,10 +35,19 @@ namespace Hua.DDNS.Jobs
private readonly IServiceProvider _serviceProvider;
private readonly DdnsOption _ddnsOption;
private readonly IHttpHelper _httpHelper;
+
+ ///
+ /// 新的 IP 地址
+ ///
public string newIp;
-
-
+ ///
+ /// 构造函数
+ ///
+ /// 日志对象
+ /// Http 助手
+ /// DDNS 配置选项
+ /// 服务提供者
public NewJob(ILogger logger,IHttpHelper httpHelper,IOptions ddnsOption, IServiceProvider serviceProvider)
{
_logger = logger;
@@ -43,6 +55,11 @@ namespace Hua.DDNS.Jobs
_serviceProvider = serviceProvider;
_ddnsOption = ddnsOption.Value;
}
+
+ ///
+ /// 执行任务逻辑
+ ///
+ /// 作业执行上下文
public async Task Execute(IJobExecutionContext context)
{
@@ -98,6 +115,9 @@ namespace Hua.DDNS.Jobs
}
}
+ ///
+ /// 释放资源
+ ///
public void Dispose()
{
_logger.LogInformation("AppJob已销毁");
diff --git a/Hua.DDNS/Jobs/SslDownloadJob.cs b/Hua.DDNS/Jobs/SslDownloadJob.cs
index cb0b4c2..4a0df61 100644
--- a/Hua.DDNS/Jobs/SslDownloadJob.cs
+++ b/Hua.DDNS/Jobs/SslDownloadJob.cs
@@ -8,6 +8,9 @@ using System.Security.Cryptography.X509Certificates;
namespace Hua.DDNS.Jobs
{
+ ///
+ /// SSL 证书下载任务类,用于定期检查并更新 SSL 证书
+ ///
[DisallowConcurrentExecution]
public class SslDownloadJob : IJob, IDisposable
{
@@ -15,6 +18,12 @@ namespace Hua.DDNS.Jobs
private readonly IServiceProvider _serviceProvider;
private readonly SslDownloadOption _sslDownloadOption;
+ ///
+ /// 构造函数
+ ///
+ /// 日志对象
+ /// 服务提供者
+ /// SSL 下载配置选项
public SslDownloadJob(
ILogger logger,
IServiceProvider serviceProvider,
@@ -25,6 +34,10 @@ namespace Hua.DDNS.Jobs
_sslDownloadOption = sslDownloadOption.Value;
}
+ ///
+ /// 执行任务逻辑
+ ///
+ /// 作业执行上下文
public async Task Execute(IJobExecutionContext context)
{
if (!_sslDownloadOption.Enabled)
@@ -110,6 +123,11 @@ namespace Hua.DDNS.Jobs
}
}
+ ///
+ /// 获取本地证书的过期时间
+ ///
+ /// 下载项
+ /// 过期时间,如果不存在则返回 null
private DateTime? GetLocalCertificateExpiry(SslDownloadItem item)
{
try
@@ -137,6 +155,14 @@ namespace Hua.DDNS.Jobs
}
}
+ ///
+ /// 异步下载证书文件
+ ///
+ /// SSL 提供者
+ /// 下载项
+ /// 证书 ID
+ /// 域名
+ /// Task
private async Task DownloadFileAsync(ISslDownloadProvider provider, SslDownloadItem item, string certificateId, string domain)
{
try
@@ -169,6 +195,9 @@ namespace Hua.DDNS.Jobs
}
}
+ ///
+ /// 释放资源
+ ///
public void Dispose()
{
_logger.LogInformation("SslDownloadJob已销毁");
diff --git a/Hua.DDNS/Models/DnsRecord.cs b/Hua.DDNS/Models/DnsRecord.cs
index 11d8434..451112e 100644
--- a/Hua.DDNS/Models/DnsRecord.cs
+++ b/Hua.DDNS/Models/DnsRecord.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -6,22 +6,60 @@ using System.Threading.Tasks;
namespace Hua.DDNS.Models;
+///
+/// 域名解析记录实体类
+///
public class DnsRecord
{
+ ///
+ /// 解析记录 ID
+ ///
public string Id { get; set; }
+
+ ///
+ /// IP 地址
+ ///
public string Ip { get; set; }
+
+ ///
+ /// 主机记录 (例如: www)
+ ///
public string Host { get; set; }
+
+ ///
+ /// 子域名 (通常与 Host 相同)
+ ///
public string SubDomain { get; set; }
+
+ ///
+ /// 根域名 (例如: example.com)
+ ///
public string Domain { get; set; }
+
+ ///
+ /// 生存时间 (TTL)
+ ///
public string TTL { get; set; } = "10";
+
+ ///
+ /// 记录类型 (A, AAAA, CNAME 等)
+ ///
public string RecordType { get; set; } = "A";
+ ///
+ /// 构造函数
+ ///
+ /// IP 地址
+ /// 域名
public DnsRecord(string ip,string domain)
{
Ip = ip;
Host = domain;
}
+ ///
+ /// 默认构造函数
+ ///
public DnsRecord()
{
diff --git a/Hua.DDNS/Models/MappingProfile.cs b/Hua.DDNS/Models/MappingProfile.cs
index d6a4e20..fdeb005 100644
--- a/Hua.DDNS/Models/MappingProfile.cs
+++ b/Hua.DDNS/Models/MappingProfile.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -10,8 +10,14 @@ using TencentCloud.Dnspod.V20210323.Models;
namespace Hua.DDNS.Models
{
+ ///
+ /// AutoMapper 对象映射配置类
+ ///
public class MappingProfile : Profile
{
+ ///
+ /// 构造函数,配置映射规则
+ ///
public MappingProfile()
{
CreateMap()
diff --git a/Hua.DDNS/SslProviders/Ali/AliSslProvider.cs b/Hua.DDNS/SslProviders/Ali/AliSslProvider.cs
index 2a820e6..6a5dbb9 100644
--- a/Hua.DDNS/SslProviders/Ali/AliSslProvider.cs
+++ b/Hua.DDNS/SslProviders/Ali/AliSslProvider.cs
@@ -8,12 +8,20 @@ using Microsoft.Extensions.Options;
namespace Hua.DDNS.SslProviders.Ali
{
+ ///
+ /// 阿里云 SSL 证书下载提供者
+ ///
public class AliSslProvider : ISslDownloadProvider
{
private readonly Client _client;
private readonly AliCloudOption _aliCloudOption;
private readonly ILogger _logger;
+ ///
+ /// 构造函数
+ ///
+ /// 日志对象
+ /// 阿里云配置
public AliSslProvider(
ILogger logger,
IOptions aliCloudOption)
@@ -31,12 +39,40 @@ namespace Hua.DDNS.SslProviders.Ali
_client = new Client(config);
}
+ ///
+ /// 异步获取阿里云上的 SSL 证书列表
+ ///
+ /// 证书列表
public async Task> GetCertificatesAsync()
{
try
{
- _logger.LogWarning("阿里云 SSL 证书列表功能待实现");
- return new List();
+ var request = new ListUserCertificateOrderRequest
+ {
+ OrderType = "CERT",
+ Status = "ISSUED" // 也可以不设置,获取所有
+ };
+
+ var response = await _client.ListUserCertificateOrderAsync(request);
+ var certificates = new List();
+
+ if (response.Body.CertificateOrderList != null)
+ {
+ foreach (var cert in response.Body.CertificateOrderList)
+ {
+ certificates.Add(new SslCertificate
+ {
+ CertificateId = cert.CertificateId.ToString(),
+ Domain = cert.Domain,
+ Alias = cert.Name,
+ CertEndTime = string.IsNullOrEmpty(cert.EndDate) ? DateTime.MinValue : DateTime.Parse(cert.EndDate),
+ StatusMsg = cert.Status
+ });
+ }
+ }
+
+ _logger.LogInformation($"获取到 {certificates.Count} 个阿里云 SSL 证书");
+ return certificates;
}
catch (Exception ex)
{
@@ -45,10 +81,18 @@ namespace Hua.DDNS.SslProviders.Ali
}
}
+ ///
+ /// 异步下载阿里云上的指定的 SSL 证书
+ ///
+ /// 证书 ID
+ /// 本地保存目录路径
+ /// 保存的文件名 (不含后缀)
+ /// 下载成功返回 true,否则返回 false
public async Task DownloadCertificateAsync(string certificateId, string savePath, string fileName)
{
try
{
+ // TODO: 阿里云证书下载逻辑
_logger.LogWarning($"阿里云 SSL 证书下载功能待实现: {certificateId}");
return false;
}
@@ -58,5 +102,41 @@ namespace Hua.DDNS.SslProviders.Ali
return false;
}
}
+
+ ///
+ /// 异步清理无效证书
+ ///
+ ///
+ public async Task CleanInvalidCertificatesAsync()
+ {
+ try
+ {
+ var certificates = await GetCertificatesAsync();
+ // 筛选过期的证书
+ var expiredCertificates = certificates.Where(c => c.CertEndTime != DateTime.MinValue && c.CertEndTime < DateTime.Now).ToList();
+
+ foreach (var cert in expiredCertificates)
+ {
+ try
+ {
+ var deleteRequest = new DeleteUserCertificateRequest
+ {
+ CertId = long.Parse(cert.CertificateId)
+ };
+ await _client.DeleteUserCertificateAsync(deleteRequest);
+ _logger.LogInformation($"已删除阿里云过期证书: {cert.Domain} ({cert.CertificateId}), 过期时间: {cert.CertEndTime}");
+ }
+ catch (Exception ex)
+ {
+ _logger.LogWarning(ex, $"删除阿里云证书失败: {cert.CertificateId}");
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "清理阿里云无效证书失败");
+ throw;
+ }
+ }
}
}
diff --git a/Hua.DDNS/SslProviders/ISslDownloadProvider.cs b/Hua.DDNS/SslProviders/ISslDownloadProvider.cs
index e7c11d2..3962ed4 100644
--- a/Hua.DDNS/SslProviders/ISslDownloadProvider.cs
+++ b/Hua.DDNS/SslProviders/ISslDownloadProvider.cs
@@ -1,19 +1,70 @@
namespace Hua.DDNS.SslProviders
{
+ ///
+ /// SSL 证书下载提供者接口
+ ///
public interface ISslDownloadProvider
{
+ ///
+ /// 异步获取 SSL 证书列表
+ ///
+ /// 证书信息列表
Task> GetCertificatesAsync();
+
+ ///
+ /// 异步下载指定的 SSL 证书
+ ///
+ /// 证书 ID
+ /// 本地保存目录路径
+ /// 保存的文件名 (不含后缀)
+ /// 下载成功返回 true,否则返回 false
Task DownloadCertificateAsync(string certificateId, string savePath, string fileName);
+
+ ///
+ /// 异步清理无效证书
+ ///
+ ///
+ Task CleanInvalidCertificatesAsync();
}
+ ///
+ /// SSL 证书信息类
+ ///
public class SslCertificate
{
+ ///
+ /// 证书 ID
+ ///
public string CertificateId { get; set; }
+
+ ///
+ /// 证书关联的域名
+ ///
public string Domain { get; set; }
+
+ ///
+ /// 证书别名
+ ///
public string Alias { get; set; }
+
+ ///
+ /// 证书生效时间
+ ///
public DateTime CertBeginTime { get; set; }
+
+ ///
+ /// 证书过期时间
+ ///
public DateTime CertEndTime { get; set; }
+
+ ///
+ /// 状态码
+ ///
public int Status { get; set; }
+
+ ///
+ /// 状态消息
+ ///
public string StatusMsg { get; set; }
}
}
diff --git a/Hua.DDNS/SslProviders/Tencent/TencentSslProvider.cs b/Hua.DDNS/SslProviders/Tencent/TencentSslProvider.cs
index 2708b7f..c8e54d3 100644
--- a/Hua.DDNS/SslProviders/Tencent/TencentSslProvider.cs
+++ b/Hua.DDNS/SslProviders/Tencent/TencentSslProvider.cs
@@ -10,12 +10,20 @@ using System.IO.Compression;
namespace Hua.DDNS.SslProviders.Tencent
{
+ ///
+ /// 腾讯云 SSL 证书下载提供者
+ ///
public class TencentSslProvider : ISslDownloadProvider
{
private readonly SslClient _client;
private readonly TencentCloudOption _tencentCloudOption;
private readonly ILogger _logger;
+ ///
+ /// 构造函数
+ ///
+ /// 日志对象
+ /// 腾讯云配置
public TencentSslProvider(
ILogger logger,
IOptions tencentCloudOption)
@@ -32,6 +40,10 @@ namespace Hua.DDNS.SslProviders.Tencent
});
}
+ ///
+ /// 异步获取腾讯云上的 SSL 证书列表
+ ///
+ /// 证书信息列表
public async Task> GetCertificatesAsync()
{
try
@@ -72,6 +84,13 @@ namespace Hua.DDNS.SslProviders.Tencent
}
}
+ ///
+ /// 异步下载腾讯云上的指定的 SSL 证书
+ ///
+ /// 证书 ID
+ /// 本地保存目录路径
+ /// 保存的文件名 (不含后缀)
+ /// 下载成功返回 true,否则返回 false
public async Task DownloadCertificateAsync(string certificateId, string savePath, string fileName)
{
string tempZipPath = null;
@@ -172,5 +191,41 @@ namespace Hua.DDNS.SslProviders.Tencent
}
}
}
+
+ ///
+ /// 异步清理无效证书
+ ///
+ ///
+ public async Task CleanInvalidCertificatesAsync()
+ {
+ try
+ {
+ var certificates = await GetCertificatesAsync();
+ // 清理已过期的证书 (Status 为 10 或者当前时间已过过期时间)
+ var expiredCertificates = certificates.Where(c => c.CertEndTime < DateTime.Now || c.Status == 10).ToList();
+
+ foreach (var cert in expiredCertificates)
+ {
+ try
+ {
+ var deleteRequest = new DeleteCertificateRequest
+ {
+ CertificateId = cert.CertificateId
+ };
+ await _client.DeleteCertificate(deleteRequest);
+ _logger.LogInformation($"已删除腾讯云过期证书: {cert.Domain} ({cert.CertificateId}), 过期时间: {cert.CertEndTime}");
+ }
+ catch (Exception ex)
+ {
+ _logger.LogWarning(ex, $"删除腾讯云证书失败: {cert.CertificateId}");
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "清理腾讯云无效证书失败");
+ throw;
+ }
+ }
}
}
diff --git a/Hua.DDNS/Start/Program.cs b/Hua.DDNS/Start/Program.cs
index 3dfb85d..3d88c96 100644
--- a/Hua.DDNS/Start/Program.cs
+++ b/Hua.DDNS/Start/Program.cs
@@ -18,10 +18,18 @@ using Serilog.Extensions.Logging;
namespace Hua.DDNS.Start
{
+ ///
+ /// 应用程序入口类
+ ///
public static class Program
{
+ ///
+ /// 主入口方法
+ ///
+ /// 命令行参数
public static async Task Main(string[] args)
{
+ // 配置 Serilog 日志
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.WriteTo.Console()
@@ -33,13 +41,18 @@ namespace Hua.DDNS.Start
await CreateHostBuilder(args).Build().RunAsync();
}
+ ///
+ /// 创建并配置宿主构造器
+ ///
+ /// 命令行参数
+ /// IHostBuilder 实例
private static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
- .UseWindowsService()
- .UseSerilog()
+ .UseWindowsService() // 支持作为 Windows 服务运行
+ .UseSerilog() // 使用 Serilog 替代默认日志
.ConfigureAppConfiguration((context, config) =>
{
- // clear all config provider
+ // 清理并重新配置配置源
config.Sources.Clear();
config
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
@@ -49,15 +62,25 @@ namespace Hua.DDNS.Start
.ConfigureServices((hostContext, services) =>
{
services.AddAutoMapper(Assembly.GetExecutingAssembly());
+
+ // 绑定配置选项
services.Configure(hostContext.Configuration.GetSection("DDNS"));
services.Configure(hostContext.Configuration.GetSection("Namesilo"));
services.Configure(hostContext.Configuration.GetSection("TencentCloud"));
services.Configure(hostContext.Configuration.GetSection("AliCloud"));
services.Configure(hostContext.Configuration.GetSection("SslDownload"));
+
+ // 配置依赖注入和 Quartz
ConfigDi(hostContext, services);
ConfigQuartz(hostContext, services);
});
+ ///
+ /// 配置依赖注入 (DI)
+ ///
+ /// 宿主上下文
+ /// 服务集合
+ /// IServiceProvider 实例
public static IServiceProvider ConfigDi(HostBuilderContext hostContext, IServiceCollection services)
{
services.AddSingleton();
@@ -72,29 +95,31 @@ namespace Hua.DDNS.Start
return services.BuildServiceProvider();
}
+ ///
+ /// 配置 Quartz 定时任务
+ ///
+ /// 宿主上下文
+ /// 服务集合
private static void ConfigQuartz(HostBuilderContext hostContext, IServiceCollection services)
{
- // if you are using persistent job store, you might want to alter some options
+ // 配置 Quartz 选项
services.Configure(options =>
{
- options.Scheduling.IgnoreDuplicates = true; // default: false
- options.Scheduling.OverWriteExistingData = true; // default: true
+ options.Scheduling.IgnoreDuplicates = true; // 忽略重复任务
+ options.Scheduling.OverWriteExistingData = true; // 覆盖现有数据
});
- // base configuration for DI
+ // 添加 Quartz 服务
services.AddQuartz(q =>
{
- // handy when part of cluster or you want to otherwise identify ltiple schedulers
q.SchedulerId = "Hua.DDNS.Demo";
- // this is default configuration if you don't alter it
q.UseMicrosoftDependencyInjectionJobFactory();
- // these are the defaults
q.UseSimpleTypeLoader();
q.UseInMemoryStore();
q.UseDefaultThreadPool(tp => { tp.MaxConcurrency = 10; });
- //configure jobs with code
+ // 配置 DDNS 任务 (NewJob)
var appJobKey = new JobKey("NewJob", "NewJobGroup");
q.AddJob(j => j
.StoreDurably()
@@ -110,6 +135,7 @@ namespace Hua.DDNS.Start
.StartNow()
);
+ // 配置 SSL 下载任务 (SslDownloadJob)
var sslDownloadJobKey = new JobKey("SslDownloadJob", "SslDownloadJobGroup");
q.AddJob(j => j
.StoreDurably()
@@ -132,14 +158,11 @@ namespace Hua.DDNS.Start
}
});
- // Quartz.Extensions.Hosting hosting
+ // 添加 Quartz 托管服务
services.AddQuartzHostedService(options =>
{
- // when shutting down we want jobs to complete gracefully
- options.WaitForJobsToComplete = true;
-
- // when we need to init another IHostedServices first
- options.StartDelay = TimeSpan.FromSeconds(10);
+ options.WaitForJobsToComplete = true; // 优雅退出
+ options.StartDelay = TimeSpan.FromSeconds(10); // 启动延迟
});
}
}