diff --git a/MasstransferCommon/MasstransferCommon.csproj b/MasstransferCommon/MasstransferCommon.csproj
index 05a69b5..188e4da 100644
--- a/MasstransferCommon/MasstransferCommon.csproj
+++ b/MasstransferCommon/MasstransferCommon.csproj
@@ -8,7 +8,10 @@
+
+
+
@@ -36,4 +39,8 @@
+
+
+
+
diff --git a/MasstransferCommon/Model/Entity/Entity.cs b/MasstransferCommon/Model/Entity/Entity.cs
new file mode 100644
index 0000000..11e3c22
--- /dev/null
+++ b/MasstransferCommon/Model/Entity/Entity.cs
@@ -0,0 +1,15 @@
+using SQLite;
+
+namespace MasstransferCommon.Model.Entity;
+
+///
+/// 数据库实体的父类
+///
+public class Entity
+{
+ [PrimaryKey] public string? Id { get; set; }
+
+ [Column("create_time")] public DateTime CreateTime { get; set; } = DateTime.Now;
+
+ [Column("update_time")] public DateTime UpdateTime { get; set; } = DateTime.Now;
+}
\ No newline at end of file
diff --git a/MasstransferCommon/Model/Entity/LogParams.cs b/MasstransferCommon/Model/Entity/LogParams.cs
new file mode 100644
index 0000000..e5b8333
--- /dev/null
+++ b/MasstransferCommon/Model/Entity/LogParams.cs
@@ -0,0 +1,23 @@
+using System.ComponentModel;
+using SQLite;
+
+namespace MasstransferCommon.Model.Entity;
+
+///
+/// 日志参数
+///
+[Table("log_params")]
+[Description("日志参数")]
+public class LogParams : Entity
+{
+ [Column("level"), Description("日志级别")] public string? Level { get; set; }
+
+ [Column("path"), Description("日志存放路径")]
+ public string? Path { get; set; }
+
+ [Column("upload_corn"), Description("日志上传时间")]
+ public string? UploadCorn { get; set; }
+
+ [Column("upload_levels"), Description("日志上传级别")]
+ public string? UploadLevels { get; set; }
+}
\ No newline at end of file
diff --git a/MasstransferCommon/Scheduler/SchedulerHelper.cs b/MasstransferCommon/Scheduler/SchedulerHelper.cs
new file mode 100644
index 0000000..6f474c0
--- /dev/null
+++ b/MasstransferCommon/Scheduler/SchedulerHelper.cs
@@ -0,0 +1,98 @@
+using Quartz;
+using Quartz.Impl;
+using Serilog;
+
+namespace MasstransferCommon.scheduler;
+
+public class SchedulerHelper
+{
+ private static readonly Lazy lazyScheduler = new(() => InitSchedulerAsync().GetAwaiter().GetResult());
+
+ private static readonly Dictionary _jobDetails = new();
+
+ private static IScheduler Scheduler => lazyScheduler.Value;
+
+ private static async Task InitSchedulerAsync()
+ {
+ try
+ {
+ return await new StdSchedulerFactory().GetScheduler();
+ }
+ catch (Exception ex)
+ {
+ Log.Error($"Failed to initialize scheduler: {ex.Message}");
+ throw;
+ }
+ }
+
+ public static async Task Start()
+ {
+ await Scheduler.Start();
+ }
+
+ public static async Task SchedulerInterval(Dictionary? data, int interval,
+ string group = "defaultGroup") where T : IJob
+ {
+ var job = CreateJob(data, group);
+
+ var trigger = TriggerBuilder.Create()
+ .WithIdentity(typeof(T).Name, group)
+ .StartNow()
+ .WithSimpleSchedule(x => x.WithIntervalInSeconds(interval).RepeatForever())
+ .Build();
+
+ await Scheduler.ScheduleJob(job, trigger);
+ }
+
+ public static async Task SchedulerCorn(Dictionary? data, string? cronExpression,
+ string group = "defaultGroup") where T : IJob
+ {
+ var job = CreateJob(data, group);
+
+ var trigger = TriggerBuilder.Create()
+ .WithIdentity(typeof(T).Name, group)
+ .StartNow()
+ .WithSchedule(CronScheduleBuilder.CronSchedule(cronExpression))
+ .Build();
+
+ await Scheduler.ScheduleJob(job, trigger);
+ }
+
+ private static IJobDetail CreateJob(Dictionary? data, string group) where T : IJob
+ {
+ if (_jobDetails.ContainsKey(typeof(T).Name)) return _jobDetails[typeof(T).Name];
+
+ var job = JobBuilder.Create()
+ .WithIdentity(typeof(T).Name, group)
+ .Build();
+
+ if (data != null && data.Count > 0)
+ foreach (var item in data)
+ job.JobDataMap.Add(item.Key, item.Value);
+
+ _jobDetails[typeof(T).Name] = job;
+ return job;
+ }
+
+ public static async Task PauseJob(string group = "defaultGroup")
+ {
+ if (_jobDetails.ContainsKey(typeof(T).Name)) await Scheduler.PauseJob(JobKey.Create(typeof(T).Name, group));
+ }
+
+ public static async Task ResumeJob(string group = "defaultGroup")
+ {
+ if (_jobDetails.ContainsKey(typeof(T).Name)) await Scheduler.ResumeJob(JobKey.Create(typeof(T).Name, group));
+ }
+
+ public static async Task Shutdown()
+ {
+ if (!Scheduler.IsShutdown) await Scheduler.Shutdown();
+ }
+
+ public static async Task TriggerOnceImmediately(string group = "defaultGroup") where T : IJob
+ {
+ if (!_jobDetails.ContainsKey(typeof(T).Name)) return;
+
+ await Scheduler.TriggerJob(new JobKey(typeof(T).Name, group));
+ }
+}
\ No newline at end of file
diff --git a/MasstransferExporter/LogExporter/LogFileExporter.cs b/MasstransferExporter/LogExporter/LogFileExporter.cs
new file mode 100644
index 0000000..4d3195c
--- /dev/null
+++ b/MasstransferExporter/LogExporter/LogFileExporter.cs
@@ -0,0 +1,11 @@
+namespace MasstransferExporter.LogExporter;
+
+public class LogFileExporter
+{
+ public async Task Export(string logFilePath)
+ {
+
+
+
+ }
+}
\ No newline at end of file
diff --git a/MasstransferExporter/MasstransferExporter.csproj b/MasstransferExporter/MasstransferExporter.csproj
index 500d4d7..00b007c 100644
--- a/MasstransferExporter/MasstransferExporter.csproj
+++ b/MasstransferExporter/MasstransferExporter.csproj
@@ -34,4 +34,9 @@
+
+
+
+
+