using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using SolarPower.Models; using SolarPower.Repository.Interface; using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace SolarPower.Services.Implement { public class OperationScheduleBackgroundService : IHostedService, IDisposable { static Timer _timer; private int time_interval = 30; //查詢間隔(秒) private readonly ILogger _log; private int execCount = 0; private readonly IOperationRepository operationRepository; public OperationScheduleBackgroundService(ILogger log, IOperationRepository operationRepository ) { this.operationRepository = operationRepository; this._log = log; } public void Dispose() { _timer?.Dispose(); } public Task StartAsync(CancellationToken cancellationToken) { _timer = new Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromSeconds(time_interval)); return Task.CompletedTask; } public async void DoWork(object state) { //利用 Interlocked 計數防止重複執行 if (execCount <= 0) { Interlocked.Increment(ref execCount); } if (execCount == 1) { try { var getTime = await operationRepository.GetOperationSchedules(); foreach (OperationCreatePlanModal a in getTime) { DateTime Updatedtime; if (a.ScheduleType == 0)//日 { Updatedtime = Convert.ToDateTime(a.StartTime).AddDays(a.ScheduleNum); } else if (a.ScheduleType == 1)//周 { Updatedtime = Convert.ToDateTime(a.StartTime).AddDays(a.ScheduleNum * 7); } else if (a.ScheduleType == 2)//月 { Updatedtime = Convert.ToDateTime(a.StartTime).AddMonths(a.ScheduleNum); } else if (a.ScheduleType == 3)//季 { Updatedtime = Convert.ToDateTime(a.StartTime).AddMonths(a.ScheduleNum * 3); } else // 年 { Updatedtime = Convert.ToDateTime(a.StartTime).AddYears(a.ScheduleNum); } if (Updatedtime < DateTime.Now) { var now = DateTime.Now.ToString("yyyy-MM-dd"); var finalid = await operationRepository.GetCurrentSerialNumber("operation_plan_create", $"PowerStationId = {a.PowerStationId} AND CreatedAt LIKE '%{now}%'"); var newSerialNumber = GetLastSerialNumber(finalid); var OperationPlan = new OperationCreatePlan() { EmailType = a.EmailType, ScheduleNum = a.ScheduleNum, Description = a.Description, WorkDay = a.WorkDay, ScheduleType = a.ScheduleType, SerialNumber = newSerialNumber, StartTime = Updatedtime.ToString("yyyy-MM-dd hh:mm:ss"), PowerStationId = a.PowerStationId, Type = a.Type, PlanId = DateTime.Now.ToString("yyyyMMdd") + newSerialNumber, CreatedBy = a.CreatedBy }; List properties = new List() { "EmailType", "ScheduleNum", "Description", "WorkDay", "ScheduleType", "SerialNumber", "StartTime", "PowerStationId", "Type", "PlanId", "CreatedBy" }; await operationRepository.AddOperationPlan(OperationPlan, properties); var record = new PlanToRecord() { WorkType = a.Type, PowerStationId = a.PowerStationId, StartTime = Updatedtime.ToString("yyyy-MM-dd hh:mm:ss"), CreatedBy = a.CreatedBy, EndTime = Updatedtime.AddDays(a.WorkDay).ToString("yyyy-MM-dd hh:mm:ss") }; List properties2 = new List() { "WorkType", "PowerStationId", "StartTime", "CreatedBy", "EndTime" }; await operationRepository.AddToRecord(record, properties2); var operation = await operationRepository.GetOneOperation(a.Id); await operationRepository.DeleteOneByIdWithCustomTable(a.Id, "operation_plan_create"); } } } catch (Exception ex) { _log.LogError("【OperationScheduleService】 - " + ex.Message); } finally { Interlocked.Decrement(ref execCount); } } } public string GetLastSerialNumber(string current = "", int pad = 4, byte direction = 0) { var tempSerialNumber = 0; if (!string.IsNullOrEmpty(current)) { tempSerialNumber = Convert.ToInt32(current) + 1; } else { tempSerialNumber = 1; } if (direction == 0) { return tempSerialNumber.ToString().Trim().PadLeft(pad, '0'); } else { return tempSerialNumber.ToString().Trim().PadRight(pad, '0'); } } public Task StopAsync(CancellationToken cancellationToken) { //調整Timer為永不觸發,停用定期排程 _timer?.Change(Timeout.Infinite, 0); return Task.CompletedTask; } } }