236 lines
9.4 KiB
C#
236 lines
9.4 KiB
C#
using Microsoft.Extensions.Logging;
|
||
using Repository.BackendRepository.Implement;
|
||
using Repository.BackendRepository.Interface;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.ComponentModel;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
using NCrontab;
|
||
using static NCrontab.CrontabSchedule;
|
||
using Org.BouncyCastle.Utilities;
|
||
|
||
namespace BackendWorkerService.Quartz
|
||
{
|
||
/// <summary>
|
||
/// Job調度中間對象
|
||
/// </summary>
|
||
public class JobSchedule
|
||
{
|
||
public JobSchedule(Type jobType, string cronExpression)
|
||
{
|
||
this.JobType = jobType ?? throw new ArgumentNullException(nameof(jobType));
|
||
CronExpression = cronExpression ?? throw new ArgumentNullException(nameof(cronExpression));
|
||
}
|
||
/// <summary>
|
||
/// Job類型
|
||
/// </summary>
|
||
public Type JobType { get; private set; }
|
||
/// <summary>
|
||
/// Cron表達式
|
||
/// </summary>
|
||
public string CronExpression { get; private set; }
|
||
/// <summary>
|
||
/// Job狀態
|
||
/// </summary>
|
||
public JobStatus JobStatu { get; set; } = JobStatus.Init;
|
||
}
|
||
/// <summary>
|
||
/// Job運行狀態
|
||
/// </summary>
|
||
public enum JobStatus : byte
|
||
{
|
||
[Description("初始化")]
|
||
Init = 0,
|
||
[Description("運行中")]
|
||
Running = 1,
|
||
[Description("調度中")]
|
||
Scheduling = 2,
|
||
[Description("已停止")]
|
||
Stopped = 3,
|
||
}
|
||
|
||
public class Task_Detail
|
||
{
|
||
private readonly IBackendRepository backendRepository;
|
||
private readonly ILogger<Task_Detail> logger;
|
||
public Task_Detail(ILogger<Task_Detail> logger, IBackendRepository backendRepository)
|
||
{
|
||
this.logger = logger;
|
||
this.backendRepository = backendRepository;
|
||
}
|
||
/// <summary>
|
||
/// 取得時間規則
|
||
/// </summary>
|
||
/// <param name="task"></param>
|
||
/// <param name="task_item"></param>
|
||
/// <returns></returns>
|
||
private async Task<string> GetWorkRule(string task,string task_item)
|
||
{
|
||
string Times = null;
|
||
try
|
||
{
|
||
var sql = $@" select b.system_value from task_detail a
|
||
join variable b on a.variable_id = b.id
|
||
where a.task = '{task}' and a.task_item = '{task_item}'";
|
||
|
||
Times = await backendRepository.GetOneAsync<string>(sql);
|
||
|
||
#region when dont have data
|
||
if (string.IsNullOrWhiteSpace(Times))
|
||
{
|
||
Times = task_item.ToLower() == "hour" ? "0 0 0/1 * * *"
|
||
: task_item.ToLower() == "day" ? "0 0 0 1/1 * *"
|
||
: task_item.ToLower() == "month" ? "0 0 0 1 1/1 *"
|
||
: task_item.ToLower() == "year" ? "0 0 0 1 1 1/1"
|
||
: task.ToLower() == "weatherapi" ? "0 0/10 * * * *"
|
||
: "* * * * * *";
|
||
|
||
sql = @$"insert into variable (deleted, system_type, system_key, system_value, system_remark, system_priority, system_parent_id)
|
||
values (0, 'taskTime', '{task}_{task_item}', '{Times}', '歸檔', 0, 0);";
|
||
|
||
await backendRepository.ExecuteSql(sql);
|
||
|
||
sql = $@"select id from variable where system_type = 'taskTime' and system_key = '{task}_{task_item}'";
|
||
var id = await backendRepository.GetOneAsync<string>(sql);
|
||
|
||
sql = $"update task_detail set variable_id = {id} where task = '{task}' and task_item = '{task_item}'";
|
||
await backendRepository.ExecuteSql(sql);
|
||
}
|
||
#endregion
|
||
}
|
||
catch (Exception exception)
|
||
{
|
||
logger.LogError("【Task_Detail】【任務時間獲取失敗】");
|
||
logger.LogError("【Task_Detail】【任務時間獲取失敗】[Exception]:{0},Task:{1},task_item:{2}", exception.ToString(),task,task_item);
|
||
}
|
||
return Times;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 是否執行任務
|
||
/// </summary>
|
||
/// <param name="task"></param>
|
||
/// <param name="task_item"></param>
|
||
/// <returns></returns>
|
||
public async Task<bool> GetNeedWorkTask(string task, string task_item)
|
||
{
|
||
try
|
||
{
|
||
var sql = $@"select a.lastwork_time from task_detail a
|
||
where a.task = '{task}' and a.task_item = '{task_item}'";
|
||
|
||
var lastworkTime = await backendRepository.GetOneAsync<string>(sql);
|
||
if (task_item == "Compensate")
|
||
{
|
||
string ss = "";
|
||
}
|
||
|
||
if (lastworkTime == null)
|
||
{
|
||
sql = $"insert into task_detail (task, task_item, lastwork_time, created_at) values ('{task}', '{task_item}', now(), now());";
|
||
await backendRepository.ExecuteSql(sql, null);
|
||
}
|
||
|
||
DateTime dateTime = lastworkTime != null ? Convert.ToDateTime(lastworkTime) : Convert.ToDateTime("1970-01-01 00:00:01");
|
||
|
||
//取得 variable 中的 crob 時間設定 ex: 0 0/1 * * * *
|
||
var crobTime = await GetWorkRule(task, task_item);
|
||
var nextTime = CrontabSchedule.Parse(crobTime, new ParseOptions { IncludingSeconds = true } ).GetNextOccurrence(dateTime);
|
||
if (DateTime.Now >= nextTime)
|
||
{
|
||
return true;
|
||
}
|
||
}
|
||
catch(Exception exception)
|
||
{
|
||
logger.LogError("【Task_Detail】【時間解析失敗】[Exception]:{0},Task:{1},task_item:{2}", exception.ToString(), task, task_item);
|
||
}
|
||
return false;
|
||
}
|
||
/// <summary>
|
||
/// 紀錄任務開始執行時間
|
||
/// </summary>
|
||
/// <param name="task"></param>
|
||
/// <param name="task_item"></param>
|
||
/// <returns></returns>
|
||
public async Task InsertWorkTime(string task, string task_item ,string LoggerWord = null)
|
||
{
|
||
try
|
||
{
|
||
Dictionary<string, object> worktime = new Dictionary<string, object>()
|
||
{
|
||
{ "@lastwork_time", DateTime.Now.ToUniversalTime()},
|
||
{ "@success", 2},
|
||
{ "@updated_at", DateTime.Now.ToUniversalTime()},
|
||
};
|
||
|
||
await backendRepository.UpdateOneByCustomTable(worktime, "task_detail", $" task = '{task}' and task_item = '{task_item}'");
|
||
|
||
if(LoggerWord == null)
|
||
{
|
||
logger.LogInformation($"【Task_Detail】【開始{task},{task_item}任務】");
|
||
}
|
||
logger.LogInformation($"【Task_Detail】【{LoggerWord}】");
|
||
}
|
||
catch (Exception exception)
|
||
{
|
||
logger.LogError("【Task_Detail】【任務輸入開始時間】[Exception]:{0},Task:{1},task_item:{2}", exception.ToString(), task, task_item);
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 紀錄任務結束時間
|
||
/// </summary>
|
||
/// <param name="task"></param>
|
||
/// <param name="task_item"></param>
|
||
/// <returns></returns>
|
||
public async Task InsertWorkTime_End(string task, string task_item,string LoggerWord = null)
|
||
{
|
||
try
|
||
{
|
||
Dictionary<string, object> worktime = new Dictionary<string, object>()
|
||
{
|
||
{ "@success", 0},
|
||
{ "@lastwork_end_time", DateTime.Now.ToUniversalTime()},
|
||
{ "@updated_at", DateTime.Now.ToUniversalTime()},
|
||
};
|
||
await backendRepository.UpdateOneByCustomTable(worktime, "task_detail", $" task = '{task}' and task_item = '{task_item}'");
|
||
if (LoggerWord == null)
|
||
{
|
||
logger.LogInformation($"【Task_Detail】【結束{task},{task_item}任務】");
|
||
}
|
||
logger.LogInformation($"【Task_Detail】【{LoggerWord}】");
|
||
}
|
||
catch (Exception exception)
|
||
{
|
||
logger.LogError("【Task_Detail】【任務輸入結束時間】[Exception]:{0},Task:{1},task_item:{2}", exception.ToString(), task, task_item);
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 執行失敗紀錄
|
||
/// </summary>
|
||
/// <param name="task"></param>
|
||
/// <param name="task_item"></param>
|
||
/// <returns></returns>
|
||
public async Task WorkFail(string task, string task_item,string reason = "")
|
||
{
|
||
try
|
||
{
|
||
Dictionary<string, object> worktime = new Dictionary<string, object>()
|
||
{
|
||
{ "@success", 1},
|
||
{ "@updated_at", DateTime.Now.ToUniversalTime()},
|
||
};
|
||
await backendRepository.UpdateOneByCustomTable(worktime, "task_detail", $" task = '{task}' and task_item = '{task_item}'");
|
||
logger.LogError("【Task_Detail】【任務執行失敗】[Exception]:{0},Task:{1},task_item:{2}", reason, task, task_item);
|
||
}
|
||
catch (Exception exception)
|
||
{
|
||
logger.LogError("【Task_Detail】【任務執行失敗】[Exception]:{0},Task:{1},task_item:{2}", exception.ToString(), task, task_item);
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
}
|