Second upload

This commit is contained in:
qi_0527 2024-10-01 02:30:08 +08:00
parent 7be4c0a162
commit 1d91254c61
10 changed files with 528 additions and 162 deletions

View File

@ -1,84 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using OfficeOpenXml; // 引入 EPPlus 套件
using WebApi_data_value.Models; // 更新為正確的命名空間
using Microsoft.EntityFrameworkCore;
using Parking_space_WebAPI.Services;
namespace WebApi_data_value.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ExcelController : ControllerBase
{
private readonly SqlContext _context;
public ExcelController(SqlContext context)
{
_context = context;
}
// GET: api/Excel/Download
[HttpGet("Download")]
public async Task<IActionResult> DownloadExcel()
{
// 從資料庫中讀取 yuntech_parking 表的數據
var parkingSpaces = await _context.yuntech_parking.ToListAsync();
if (parkingSpaces == null || !parkingSpaces.Any())
{
return NotFound("No parking spaces data found.");
}
// 從資料庫中讀取月租車與臨停車的數據
var monthlyRent = await _context.yuntech_monthly_rent_number
.FirstOrDefaultAsync(x => x.category == "月租");
var temporaryParking = await _context.yuntech_monthly_rent_number
.FirstOrDefaultAsync(x => x.category == "臨停");
if (monthlyRent == null || temporaryParking == null)
{
return NotFound("No data found for monthly rent or temporary parking.");
}
var file = GenerateExcel(parkingSpaces, monthlyRent, temporaryParking);
var fileName = $"ParkingSpaces_{DateTime.Now:yyyyMMddHHmmss}.xlsx";
return File(file, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fileName);
}
private byte[] GenerateExcel(IEnumerable<Yuntech_parking> parkingData, Yuntech_monthly_rent_number monthlyRent, Yuntech_monthly_rent_number temporaryParking)
{
using var package = new ExcelPackage();
var worksheet = package.Workbook.Worksheets.Add("Yuntech Parking");
// 設定標題
worksheet.Cells[1, 1].Value = "總車位";
worksheet.Cells[1, 2].Value = "剩餘車位";
worksheet.Cells[1, 3].Value = "月租車數量";
worksheet.Cells[1, 4].Value = "臨停數量";
// 添加下載時間
worksheet.Cells[1, 6].Value = "下載時間";
worksheet.Cells[2, 6].Value = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
var row = 2;
// 添加每一行的數據
foreach (var item in parkingData)
{
worksheet.Cells[2, 1].Value = item.all_num;
worksheet.Cells[2, 2].Value = item.now_num;
row++;
}
// 添加月租車與臨停車的數據
worksheet.Cells[2, 3].Value = monthlyRent.number;
worksheet.Cells[2, 4].Value = temporaryParking.number;
return package.GetAsByteArray();
}
}
}

View File

@ -0,0 +1,329 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using ClosedXML.Excel;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Parking_space_WebAPI.Services;
using WebApi_data_value.Models;
namespace WebApi_data_value.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ParkingLogsController : ControllerBase
{
private readonly SqlContext _context;
public ParkingLogsController(SqlContext context)
{
_context = context;
}
// 新增停車紀錄
[HttpPost]
public async Task<IActionResult> AddParkingLog([FromBody] ParkingLog parkingLog)
{
// 確認模型有效
if (!ModelState.IsValid)
{
return BadRequest(new { message = "請求的模型無效。" });
}
_context.ParkingLogs.Add(parkingLog);
// 儲存變更到資料庫
await _context.SaveChangesAsync();
return CreatedAtAction(nameof(GetParkingLogById), new { id = parkingLog.Id }, parkingLog);
}
// 根據 ID 獲取停車紀錄
[HttpGet("{id}")]
public async Task<IActionResult> GetParkingLogById(int id)
{
var parkingLog = await _context.ParkingLogs.FindAsync(id);
if (parkingLog == null)
{
return NotFound(new { message = "找不到該停車紀錄。" });
}
return Ok(parkingLog);
}
// 下載即時車位 Excel 檔案
[HttpGet("DownloadCurrentStatusExcel")]
public async Task<IActionResult> DownloadCurrentStatusExcel()
{
DateTime currentTime = DateTime.Now;
var parkingLog = await _context.ParkingLogs
.OrderByDescending(p => p.Timestamp)
.FirstOrDefaultAsync(p => p.Timestamp <= currentTime);
if (parkingLog == null)
{
return NotFound(new { message = "找不到即時車位資料。" });
}
using (var workbook = new XLWorkbook())
{
var worksheet = workbook.Worksheets.Add("即時車位資訊");
worksheet.Cell(1, 1).Value = "時間";
worksheet.Cell(1, 2).Value = "星期";
worksheet.Cell(1, 3).Value = "總車位";
worksheet.Cell(1, 4).Value = "剩餘車位";
worksheet.Cell(1, 5).Value = "月租車位";
worksheet.Cell(1, 6).Value = "臨停車位";
worksheet.Cell(1, 7).Value = "下載日期";
worksheet.Cell(2, 1).Value = parkingLog.Timestamp.ToString("yyyy/MM/dd HH:mm:ss");
worksheet.Cell(2, 2).Value = DateTime.Now.ToString("dddd", new CultureInfo("zh-TW"));
worksheet.Cell(2, 3).Value = parkingLog.TotalParkingSpaces;
worksheet.Cell(2, 4).Value = parkingLog.RemainingSpaces;
worksheet.Cell(2, 5).Value = parkingLog.MonthlyRentSpaces;
worksheet.Cell(2, 6).Value = parkingLog.TemporaryRentSpaces;
worksheet.Cell(2, 7).Value = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss dddd");
// 設定欄位寬度
worksheet.Column(1).Width = 25;
worksheet.Column(2).Width = 10;
worksheet.Column(3).Width = 15;
worksheet.Column(4).Width = 15;
worksheet.Column(5).Width = 15;
worksheet.Column(6).Width = 15;
worksheet.Column(7).Width = 25;
using (var stream = new MemoryStream())
{
workbook.SaveAs(stream);
var content = stream.ToArray();
// 生成檔案名稱
string currentDate = DateTime.Now.ToString("yyyy-MM-dd");
string weekDayDownload = DateTime.Now.ToString("dddd", new CultureInfo("zh-TW")); // 獲取當前星期幾
string fileName = $"即時車位-{currentDate}-{weekDayDownload}.xlsx";
return File(content, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fileName);
}
}
}
// 下載 Excel 檔案
[HttpGet("DownloadExcel")]
public async Task<IActionResult> DownloadExcel(DateTime startDate, DateTime endDate, string interval)
{
// 確保日期有效
if (startDate == default || endDate == default)
{
return BadRequest(new { message = "日期無效。" });
}
// 確保開始時間早於結束時間
if (startDate >= endDate)
{
return BadRequest(new { message = "結束日期必須晚於開始日期。" });
}
// 調用 GetHourlyParkingLogs 方法以獲取停車紀錄
var parkingLogsResult = await GetHourlyParkingLogs(startDate, endDate, interval);
if (parkingLogsResult is NotFoundResult)
{
return NotFound(new { message = "找不到該日期範圍的停車紀錄。" });
}
var logs = (parkingLogsResult as OkObjectResult).Value as dynamic;
var records = logs.logs; // 獲取停車紀錄
using (var workbook = new XLWorkbook())
{
var worksheet = workbook.Worksheets.Add("停車紀錄");
worksheet.Cell(1, 1).Value = "時間";
worksheet.Cell(1, 2).Value = "星期";
worksheet.Cell(1, 3).Value = "總車位";
worksheet.Cell(1, 4).Value = "剩餘車位";
worksheet.Cell(1, 5).Value = "月租車位";
worksheet.Cell(1, 6).Value = "臨停車位";
worksheet.Cell(1, 7).Value = "下載日期";
for (int i = 0; i < records.Count; i++)
{
var log = records[i];
worksheet.Cell(i + 2, 1).Value = log.Timestamp.ToString("yyyy/MM/dd HH:mm:ss");
worksheet.Cell(i + 2, 2).Value = log.DayOfWeek;
worksheet.Cell(i + 2, 3).Value = log.TotalParkingSpaces;
worksheet.Cell(i + 2, 4).Value = log.RemainingSpaces;
worksheet.Cell(i + 2, 5).Value = log.MonthlyRentSpaces;
worksheet.Cell(i + 2, 6).Value = log.TemporaryRentSpaces;
worksheet.Cell(2, 7).Value = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss dddd");
}
worksheet.Column(1).Width = 25;
worksheet.Column(2).Width = 10;
worksheet.Column(3).Width = 15;
worksheet.Column(4).Width = 15;
worksheet.Column(5).Width = 15;
worksheet.Column(6).Width = 15;
worksheet.Column(7).Width = 25;
using (var stream = new MemoryStream())
{
workbook.SaveAs(stream);
var content = stream.ToArray();
string currentDate = DateTime.Now.ToString("yyyy-MM-dd");
string weekDay = DateTime.Now.ToString("dddd", new CultureInfo("zh-TW"));
string fileName = $"停車紀錄-{currentDate}-{weekDay}.xlsx";
return File(content, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fileName);
}
}
}
// 獲取停車紀錄
private async Task<IActionResult> GetParkingLogs(DateTime startDate, DateTime endDate, int pageNumber, int pageSize)
{
if (startDate == default || endDate == default)
{
return BadRequest(new { message = "日期無效。" });
}
if (startDate >= endDate)
{
return BadRequest(new { message = "結束日期必須晚於開始日期。" });
}
var parkingLogs = await _context.ParkingLogs
.AsNoTracking()
.Where(p => p.Timestamp >= startDate && p.Timestamp <= endDate)
.OrderByDescending(p => p.Timestamp)
.Skip((pageNumber - 1) * pageSize)
.Take(pageSize)
.ToListAsync();
if (!parkingLogs.Any())
{
return NotFound(new { message = "找不到該日期範圍的停車紀錄。" });
}
return Ok(new
{
totalRecords = await _context.ParkingLogs.CountAsync(p => p.Timestamp >= startDate && p.Timestamp <= endDate), // 總紀錄數
records = parkingLogs
});
}
//獲取前端要查詢的時間 利用interval == "none" 不需要分間格 interval != 分間隔
[HttpGet("GetHourlyParkingLogs")]
public async Task<IActionResult> GetHourlyParkingLogs(DateTime startDate, DateTime endDate, string interval, int page = 1, int recordsPerPage = 20)
{
if (startDate == default || endDate == default)
{
return BadRequest(new { message = "日期無效。" });
}
if (startDate >= endDate)
{
return BadRequest(new { message = "結束日期必須晚於開始日期。" });
}
// 查詢指定時間範圍的停車紀錄
var parkingLogs = await _context.ParkingLogs
.AsNoTracking()
.Where(p => p.Timestamp >= startDate && p.Timestamp <= endDate)
.ToListAsync();
if (!parkingLogs.Any())
{
return NotFound(new { message = "找不到該日期範圍的停車紀錄。" });
}
// 設定時間間隔
if (interval == "none")
{
var formattedLogs = parkingLogs.Select(log => new
{
log.Timestamp,
DayOfWeek = log.Timestamp.ToString("dddd", new CultureInfo("zh-TW")),
log.TotalParkingSpaces,
log.RemainingSpaces,
log.MonthlyRentSpaces,
log.TemporaryRentSpaces
}).ToList();
var totalRecords = formattedLogs.Count;
var pagedLogs = formattedLogs.Skip((page - 1) * recordsPerPage).Take(recordsPerPage).ToList();
return Ok(new
{
totalRecords = totalRecords,
logs = pagedLogs
});
}
else
{
// 將 interval 轉換為整數
int hourInterval = int.Parse(interval);
// 轉換時間格式為可讀的格式,並獲取每小時的紀錄
var formattedLogs = new List<object>();
foreach (var logGroup in parkingLogs.GroupBy(log => new
{
log.Timestamp.Year,
log.Timestamp.Month,
log.Timestamp.Day,
HourGroup = log.Timestamp.Hour / hourInterval
}))
{
formattedLogs.Add(new
{
Timestamp = new DateTime(logGroup.Key.Year, logGroup.Key.Month, logGroup.Key.Day, logGroup.Key.HourGroup * hourInterval, 0, 0),
DayOfWeek = logGroup.First().Timestamp.ToString("dddd", new CultureInfo("zh-TW")),
TotalParkingSpaces = logGroup.First().TotalParkingSpaces,
RemainingSpaces = logGroup.First().RemainingSpaces,
MonthlyRentSpaces = logGroup.First().MonthlyRentSpaces,
TemporaryRentSpaces = logGroup.First().TemporaryRentSpaces
});
}
if (!formattedLogs.Any())
{
return NotFound(new { message = "找不到該日期範圍的整點停車紀錄。" });
}
// 分頁處理
var totalRecords = formattedLogs.Count;
var pagedLogs = formattedLogs.Skip((page - 1) * recordsPerPage).Take(recordsPerPage).ToList();
return Ok(new
{
totalRecords = totalRecords,
logs = pagedLogs
});
}
}
}
}

View File

@ -0,0 +1,29 @@
 using System.ComponentModel.DataAnnotations;
namespace WebApi_data_value.Models
{
public class ParkingLog
{
[Key] // 標示主鍵
public int Id { get; set; }
[Required]
public DateTime Timestamp { get; set; } // 儲存完整的時間
[Required]
public int TotalParkingSpaces { get; set; } // 總車位
[Required]
public int RemainingSpaces { get; set; } // 剩餘車位
[Required]
public int MonthlyRentSpaces { get; set; } // 月租車位
[Required]
public int TemporaryRentSpaces { get; set; } // 臨停車位
[Required]
[StringLength(10)]
public string? DayOfWeek { get; set; }
}
}

View File

@ -10,14 +10,18 @@ using System.Text;
using Parking_space_WebAPI.Authorization;
using Parking_space_WebAPI.Helpers;
using Parking_space_WebAPI.Services;
using DocumentFormat.OpenXml.Office2016.Drawing.ChartDrawing;
using Parking_space_WebAPI.BackgroundServices;
var builder = WebApplication.CreateBuilder(args);
//在 ASP.NET Core 中啟用 CORS (跨原始來源要求)
builder.Services.AddCors();
// Add services to the container.
builder.Services.AddControllers();
// 註冊 ExcelGenerationService 為 HostedService
builder.Services.AddHostedService<ExcelGenerationService>(); // 如果不要自動保存就不要加
//執行每日存取剩餘車位
builder.Services.AddScoped<ExcelGenerationService>(); // ExcelGenerationService 註冊為 Scoped
builder.Services.AddHostedService<DailyExcelGenerationService>(); // DailyExcelGenerationService 註冊為 HostedService
// 註冊 BackgroundService
builder.Services.AddHostedService<ParkingUpdateService>(); //執行每一分鐘更新剩餘車位

View File

@ -2,10 +2,12 @@
using Microsoft.Extensions.Hosting;
using Microsoft.EntityFrameworkCore;
using System;
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;
using Parking_space_WebAPI.Services;
using WebApi_data_value.Models;
// 執行計算剩餘車位並不為負數存入資料庫ParkingLogs
public class ParkingUpdateService : BackgroundService
{
private readonly IServiceScopeFactory _scopeFactory;
@ -25,14 +27,13 @@ public class ParkingUpdateService : BackgroundService
try
{
var yuntech_parking = await _context.yuntech_parking.FirstOrDefaultAsync();
if (yuntech_parking != null)
{
if (Int32.TryParse(yuntech_parking.all_num, out int totalParkingSpaces))
{
var monthly_rent_data = await _context.yuntech_monthly_rent_number
.FirstOrDefaultAsync(rent => rent.category == "月租");
int monthlyRentNumber = 0;
@ -51,25 +52,40 @@ public class ParkingUpdateService : BackgroundService
}
int totalOccupiedSpaces = monthlyRentNumber + Math.Abs(temporaryRentNumber); // 確保臨停車位數為絕對值
int totalOccupiedSpaces = monthlyRentNumber + Math.Abs(temporaryRentNumber); //確保絕對值
int remainingSpaces = totalParkingSpaces - totalOccupiedSpaces;
// 確保剩餘車位數不為負數
yuntech_parking.now_num = Math.Max(remainingSpaces, 0).ToString();
// 保存更改
await _context.SaveChangesAsync();
var log = new ParkingLog
{
Timestamp = DateTime.Now,
TotalParkingSpaces = totalParkingSpaces,
RemainingSpaces = remainingSpaces,
MonthlyRentSpaces = monthlyRentNumber,
TemporaryRentSpaces = Math.Abs(temporaryRentNumber),
DayOfWeek = DateTime.Now.ToString("dddd", new CultureInfo("zh-TW"))
};
// 儲存資料庫ParkingLogs
_context.ParkingLogs.Add(log);
await _context.SaveChangesAsync();
}
}
}
catch (Exception ex)
{
// 錯誤處理,這裡可以記錄錯誤或進行其他處理
// 錯誤顯示
Console.WriteLine($"An error occurred: {ex.Message}");
}
}
// 每 60 秒執行一次
// 每分鐘執行一次
await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
}
}

View File

@ -1,92 +1,87 @@
using System;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using OfficeOpenXml;
using WebApi_data_value.Models;
using ClosedXML.Excel;
using Microsoft.EntityFrameworkCore;
using Parking_space_WebAPI.Models;
namespace Parking_space_WebAPI.Services
{
public class ExcelGenerationService : BackgroundService
public class ExcelGenerationService
{
private readonly IServiceProvider _serviceProvider;
private readonly string _saveDirectory = @"C:\Users\ste92\Desktop\parking-e\excel"; // 指定儲存 Excel 的資料夾
private readonly SqlContext _context;
private readonly string _excelDirectory;
public ExcelGenerationService(IServiceProvider serviceProvider)
public ExcelGenerationService(SqlContext context)
{
_serviceProvider = serviceProvider;
_context = context;
_excelDirectory = @"C:\Users\ste92\Desktop\parking-e\excel"; // 設定 Excel 檔案存儲路徑
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
public async Task GenerateDailyExcel()
{
while (!stoppingToken.IsCancellationRequested)
{
await GenerateAndSaveExcel();
await Task.Delay(TimeSpan.FromHours(1), stoppingToken); // 每小時執行一次
//await Task.Delay(TimeSpan.FromMinutes(2), stoppingToken); // 每 2 分鐘執行一次
}
}
DateTime today = DateTime.Today;
private async Task GenerateAndSaveExcel()
{
using (var scope = _serviceProvider.CreateScope())
{
var _context = scope.ServiceProvider.GetRequiredService<SqlContext>();
// 從資料庫讀取數據
var parkingSpaces = await _context.yuntech_parking.ToListAsync();
var monthlyRent = await _context.yuntech_monthly_rent_number
.FirstOrDefaultAsync(x => x.category == "月租");
var temporaryParking = await _context.yuntech_monthly_rent_number
.FirstOrDefaultAsync(x => x.category == "臨停");
if (parkingSpaces != null && monthlyRent != null && temporaryParking != null)
// 查詢當天的停車紀錄,按小時分組
var parkingLogs = await _context.ParkingLogs
.Where(p => p.Timestamp.Date == today)
.GroupBy(p => new { p.Timestamp.Year, p.Timestamp.Month, p.Timestamp.Day, p.Timestamp.Hour })
.Select(g => new
{
// 生成 Excel 文件
var fileBytes = GenerateExcel(parkingSpaces, monthlyRent, temporaryParking);
Timestamp = new DateTime(g.Key.Year, g.Key.Month, g.Key.Day, g.Key.Hour, 0, 0),
TotalParkingSpaces = g.First().TotalParkingSpaces, // 取每小時第一筆的總車位
RemainingSpaces = g.First().RemainingSpaces, // 取每小時第一筆的剩餘車位
MonthlyRentSpaces = g.First().MonthlyRentSpaces, // 取每小時第一筆的月租車位
TemporaryRentSpaces = g.First().TemporaryRentSpaces // 取每小時第一筆的臨停車位
})
.ToListAsync();
// 文件名帶上當前時間
var fileName = $"ParkingSpaces_{DateTime.Now:yyyyMMddHHmmss}.xlsx";
var filePath = Path.Combine(_saveDirectory, fileName);
// 保存文件
await File.WriteAllBytesAsync(filePath, fileBytes);
}
}
}
private byte[] GenerateExcel(IEnumerable<Yuntech_parking> parkingData, Yuntech_monthly_rent_number monthlyRent, Yuntech_monthly_rent_number temporaryParking)
{
using var package = new ExcelPackage();
var worksheet = package.Workbook.Worksheets.Add("Yuntech Parking");
// 設定標題
worksheet.Cells[1, 1].Value = "總車位";
worksheet.Cells[1, 2].Value = "剩餘車位";
worksheet.Cells[1, 3].Value = "月租車數量";
worksheet.Cells[1, 4].Value = "臨停數量";
// 添加下載時間
worksheet.Cells[1, 6].Value = "下載時間";
worksheet.Cells[2, 6].Value = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
var row = 2;
foreach (var item in parkingData)
if (parkingLogs.Count == 0)
{
worksheet.Cells[row, 1].Value = item.all_num;
worksheet.Cells[row, 2].Value = item.now_num;
row++;
// 如果當天沒有紀錄,可以選擇不生成檔案或進行其他處理
return;
}
// 添加月租車與臨停車數據
worksheet.Cells[2, 3].Value = monthlyRent.number;
worksheet.Cells[2, 4].Value = temporaryParking.number;
using (var workbook = new XLWorkbook())
{
var worksheet = workbook.Worksheets.Add("當天停車紀錄");
worksheet.Cell(1, 1).Value = "時間";
worksheet.Cell(1, 2).Value = "總車位";
worksheet.Cell(1, 3).Value = "剩餘車位";
worksheet.Cell(1, 4).Value = "月租車位";
worksheet.Cell(1, 5).Value = "臨停車位";
worksheet.Cell(1, 6).Value = "生成日期";
worksheet.Cell(2, 6).Value = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss dddd"); // 填入當前生成時間
return package.GetAsByteArray();
for (int i = 0; i < parkingLogs.Count; i++)
{
var log = parkingLogs[i];
worksheet.Cell(i + 2, 1).Value = log.Timestamp.ToString("yyyy/MM/dd HH:mm:ss");
worksheet.Cell(i + 2, 2).Value = log.TotalParkingSpaces;
worksheet.Cell(i + 2, 3).Value = log.RemainingSpaces;
worksheet.Cell(i + 2, 4).Value = log.MonthlyRentSpaces;
worksheet.Cell(i + 2, 5).Value = log.TemporaryRentSpaces;
}
// 設定欄位寬度
worksheet.Column(1).Width = 25;
worksheet.Column(2).Width = 15;
worksheet.Column(3).Width = 15;
worksheet.Column(4).Width = 15;
worksheet.Column(5).Width = 15;
worksheet.Column(6).Width = 25;
// 生成檔案名稱
string fileName = $"整天車位數-{today:yyyy-MM-dd-dddd}.xlsx";
// 儲存檔案
var filePath = Path.Combine(_excelDirectory, fileName);
workbook.SaveAs(filePath);
}
}
}
}

View File

@ -0,0 +1,70 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;
using Parking_space_WebAPI.Services;
// 讓ExcelGenerationService執行每日固定存取
namespace Parking_space_WebAPI.BackgroundServices
{
public class DailyExcelGenerationService : IHostedService, IDisposable
{
private readonly ILogger<DailyExcelGenerationService> _logger;
private readonly IServiceProvider _serviceProvider;
private Timer _timer;
public DailyExcelGenerationService(ILogger<DailyExcelGenerationService> logger, IServiceProvider serviceProvider)
{
_logger = logger;
_serviceProvider = serviceProvider;
}
public Task StartAsync(CancellationToken cancellationToken)
{
TimeSpan scheduledTime = new TimeSpan(23, 59, 0); //設定固定每天存取的時間
var now = DateTime.Now;
var nextRunTime = DateTime.Today.Add(scheduledTime);
if (now > nextRunTime)
{
nextRunTime = nextRunTime.AddDays(1);
}
var timeToGo = nextRunTime - now;
_timer = new Timer(GenerateExcel, null, timeToGo, TimeSpan.FromDays(1));
return Task.CompletedTask;
}
private async void GenerateExcel(object state)
{
try
{
using (var scope = _serviceProvider.CreateScope())
{
var excelGenerationService = scope.ServiceProvider.GetRequiredService<ExcelGenerationService>();
await excelGenerationService.GenerateDailyExcel();
}
_logger.LogInformation("每日 Excel 檔案已生成。");
}
catch (Exception ex)
{
_logger.LogError(ex, "生成 Excel 檔案時出錯。");
}
}
public Task StopAsync(CancellationToken cancellationToken)
{
_timer?.Change(Timeout.Infinite, 0);
return Task.CompletedTask;
}
public void Dispose()
{
_timer?.Dispose();
}
}
}

View File

@ -64,6 +64,9 @@ namespace Parking_space_WebAPI.Services
//EL125車輛
public DbSet<El125_car_table> el125_car_table { get; set; } = null!;
// 新的剩餘車位與時間
public DbSet<ParkingLog> ParkingLogs { get; set; } = null!;
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
@ -100,6 +103,9 @@ namespace Parking_space_WebAPI.Services
builder.Entity<Yuntech_parking_user_list>().HasKey(o => new { o.user_license_plate_number });//Primary Key
builder.Entity<El125_car_table>().HasKey(o => new { o.license_plate_number });//Primary Key
builder.Entity<ParkingLog>().HasKey(o => new { o.Id }); // 設定 ParkingLog 的主鍵
}

View File

@ -19,6 +19,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ClosedXML" Version="0.102.3" />
<PackageReference Include="Emgu.CV" Version="4.8.0.5324" />
<PackageReference Include="EPPlus" Version="4.5.3.3" />
<PackageReference Include="FFmpeg.AutoGen" Version="6.0.0.2" />

View File

@ -10,7 +10,7 @@
},
"AllowedHosts": "*",
//MYSQL
//MYSQL PgSQL
"ConnectionStrings": {
"tarefasConnection": "server=140.125.21.65;port=3307;uid=leo;pwd=@Leo890808;database=leo"