parking-webapi/WebApi_data_value/Services/BackgroundService.cs

234 lines
8.8 KiB
C#
Raw Permalink Normal View History

2024-09-28 01:25:42 +08:00
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.EntityFrameworkCore;
using System;
2024-10-01 02:30:08 +08:00
using System.Globalization;
2024-09-28 01:25:42 +08:00
using System.Threading;
using System.Threading.Tasks;
using Parking_space_WebAPI.Services;
2024-10-25 00:59:31 +08:00
using WebApi_data_value.Models;
using Microsoft.Extensions.Logging; // 確保引用
using System.Linq;
#region
public class ParkingService : BackgroundService
{
private readonly IServiceScopeFactory _scopeFactory;
private readonly ILogger<ParkingService> _logger;
public ParkingService(IServiceScopeFactory scopeFactory, ILogger<ParkingService> logger)
{
_scopeFactory = scopeFactory;
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await PerformParkingCheckAsync(stoppingToken);
while (!stoppingToken.IsCancellationRequested)
{
2024-10-25 23:59:12 +08:00
await Task.Delay(TimeSpan.FromSeconds(60), stoppingToken); // 每60秒執行
2024-10-25 00:59:31 +08:00
await PerformParkingCheckAsync(stoppingToken);
}
}
private async Task PerformParkingCheckAsync(CancellationToken stoppingToken)
{
using (var scope = _scopeFactory.CreateScope())
{
var _context = scope.ServiceProvider.GetRequiredService<SqlContext>();
var now = DateTime.Now;
2024-10-25 23:54:13 +08:00
var startTime = now.AddDays(-2); // 獲取最近兩天內進入的車輛
2024-10-25 00:59:31 +08:00
var inCars = await _context.yuntech_in_car_table
.Where(car => car.in_time >= startTime)
.ToListAsync(stoppingToken);
// 獲取月租名單
var monthlyUsers = await _context.yuntech_parking_user_list.ToListAsync(stoppingToken);
2024-10-25 23:54:13 +08:00
int monthlycar = 0;
int temporarycar = 0;
2024-10-25 00:59:31 +08:00
foreach (var car in inCars)
{
2024-10-25 23:54:13 +08:00
bool isMonthlyUser = monthlyUsers.Any(user => user.user_license_plate_number == car.license_plate_number);
2024-10-25 00:59:31 +08:00
2024-10-25 23:54:13 +08:00
if (isMonthlyUser)
2024-10-25 00:59:31 +08:00
{
2024-10-25 23:54:13 +08:00
int monthlyNum = 0;
if (car.in_time.HasValue && !car.out_time.HasValue)
2024-10-25 00:59:31 +08:00
{
2024-10-25 23:54:13 +08:00
if ((now - car.in_time.Value).TotalHours > 15)
{
monthlyNum = 0;
}
else
{
int countWithin15Hours = inCars.Count(c => c.license_plate_number == car.license_plate_number
&& c.in_time.HasValue
&& (now - c.in_time.Value).TotalHours <= 15);
monthlyNum = countWithin15Hours % 2 == 1 ? 1 : 0;
}
2024-10-25 00:59:31 +08:00
}
2024-10-25 23:54:13 +08:00
else if (car.out_time.HasValue)
2024-10-25 00:59:31 +08:00
{
2024-10-25 23:54:13 +08:00
monthlyNum = 0;
2024-10-25 00:59:31 +08:00
}
2024-10-25 23:54:13 +08:00
monthlycar += monthlyNum;
2024-10-25 00:59:31 +08:00
}
2024-10-25 23:54:13 +08:00
else // 臨停車輛
2024-10-25 00:59:31 +08:00
{
2024-10-25 23:54:13 +08:00
int temporaryNum = 0;
if (car.in_time.HasValue && !car.out_time.HasValue)
2024-10-25 03:25:06 +08:00
{
2024-10-25 23:54:13 +08:00
if ((now - car.in_time.Value).TotalHours > 15)
{
temporaryNum = 0;
}
else
{
int countWithin15Hours = inCars.Count(c => c.license_plate_number == car.license_plate_number
&& c.in_time.HasValue
&& (now - c.in_time.Value).TotalHours <= 15);
temporaryNum = countWithin15Hours % 2 == 1 ? 1 : 0;
}
2024-10-25 03:25:06 +08:00
}
2024-10-25 23:54:13 +08:00
else if (car.out_time.HasValue)
2024-10-25 03:25:06 +08:00
{
2024-10-25 23:54:13 +08:00
temporaryNum = 0;
2024-10-25 03:25:06 +08:00
}
2024-10-25 23:54:13 +08:00
temporarycar += temporaryNum;
2024-10-25 00:59:31 +08:00
}
}
2024-10-25 23:54:13 +08:00
// 絕對值
2024-10-25 03:25:06 +08:00
monthlycar = Math.Abs(monthlycar);
2024-10-25 23:54:13 +08:00
temporarycar = Math.Abs(temporarycar);
2024-10-25 03:25:06 +08:00
2024-10-25 00:59:31 +08:00
_logger.LogInformation($"月租車位數量: {monthlycar}");
_logger.LogInformation($"臨停車位數量: {temporarycar}");
2024-10-25 23:54:13 +08:00
await UpdateMonthly(_context, monthlycar, temporarycar, stoppingToken);
2024-10-25 00:59:31 +08:00
}
}
private async Task UpdateMonthly(SqlContext context, int monthlycar, int temporarycar, CancellationToken stoppingToken)
{
var monthlyRentData = await context.yuntech_monthly_rent_number
.FirstOrDefaultAsync(rent => rent.category == "月租", stoppingToken);
if (monthlyRentData != null)
{
monthlyRentData.number = monthlycar.ToString();
}
2024-10-25 23:54:13 +08:00
2024-10-25 00:59:31 +08:00
var temporaryRentData = await context.yuntech_monthly_rent_number
.FirstOrDefaultAsync(rent => rent.category == "臨停", stoppingToken);
if (temporaryRentData != null)
{
temporaryRentData.number = temporarycar.ToString();
}
await context.SaveChangesAsync(stoppingToken);
}
}
2024-10-25 23:54:13 +08:00
2024-10-25 00:59:31 +08:00
#endregion
#region ParkingLogs
2024-09-28 01:25:42 +08:00
public class ParkingUpdateService : BackgroundService
{
private readonly IServiceScopeFactory _scopeFactory;
public ParkingUpdateService(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
using (var scope = _scopeFactory.CreateScope())
{
var _context = scope.ServiceProvider.GetRequiredService<SqlContext>();
try
{
var yuntech_parking = await _context.yuntech_parking.FirstOrDefaultAsync();
if (yuntech_parking != null)
{
2024-10-25 00:59:31 +08:00
2024-09-28 01:25:42 +08:00
if (Int32.TryParse(yuntech_parking.all_num, out int totalParkingSpaces))
{
2024-10-25 00:59:31 +08:00
2024-09-28 01:25:42 +08:00
var monthly_rent_data = await _context.yuntech_monthly_rent_number
.FirstOrDefaultAsync(rent => rent.category == "月租");
int monthlyRentNumber = 0;
if (monthly_rent_data != null)
{
Int32.TryParse(monthly_rent_data.number, out monthlyRentNumber);
}
2024-10-25 00:59:31 +08:00
2024-09-28 01:25:42 +08:00
var temporary_rent_data = await _context.yuntech_monthly_rent_number
.FirstOrDefaultAsync(rent => rent.category == "臨停");
int temporaryRentNumber = 0;
if (temporary_rent_data != null)
{
Int32.TryParse(temporary_rent_data.number, out temporaryRentNumber);
}
2024-10-25 00:59:31 +08:00
2024-10-01 02:30:08 +08:00
int totalOccupiedSpaces = monthlyRentNumber + Math.Abs(temporaryRentNumber); //確保絕對值
2024-09-28 01:25:42 +08:00
int remainingSpaces = totalParkingSpaces - totalOccupiedSpaces;
// 確保剩餘車位數不為負數
yuntech_parking.now_num = Math.Max(remainingSpaces, 0).ToString();
2024-10-25 00:59:31 +08:00
2024-10-01 02:30:08 +08:00
await _context.SaveChangesAsync();
2024-10-25 00:59:31 +08:00
2024-10-01 02:30:08 +08:00
var log = new ParkingLog
{
Timestamp = DateTime.Now,
TotalParkingSpaces = totalParkingSpaces,
2024-10-01 15:02:36 +08:00
RemainingSpaces = Math.Max(remainingSpaces, 0), // 確保儲存時不為負數
2024-10-01 02:30:08 +08:00
MonthlyRentSpaces = monthlyRentNumber,
TemporaryRentSpaces = Math.Abs(temporaryRentNumber),
DayOfWeek = DateTime.Now.ToString("dddd", new CultureInfo("zh-TW"))
};
// 儲存資料庫ParkingLogs
_context.ParkingLogs.Add(log);
2024-09-28 01:25:42 +08:00
await _context.SaveChangesAsync();
}
}
}
catch (Exception ex)
{
2024-10-01 02:30:08 +08:00
// 錯誤顯示
2024-09-28 01:25:42 +08:00
Console.WriteLine($"An error occurred: {ex.Message}");
}
}
2024-10-02 00:30:22 +08:00
// 每 30 秒執行一次
await Task.Delay(TimeSpan.FromSeconds(30), stoppingToken);
2024-09-28 01:25:42 +08:00
}
}
}
2024-10-25 00:59:31 +08:00
#endregion