using Microsoft.Extensions.DependencyInjection; 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; using Microsoft.Extensions.Logging; // 確保引用 using System.Linq; #region 從進入車輛獲取最新的月租名單 public class ParkingService : BackgroundService { private readonly IServiceScopeFactory _scopeFactory; private readonly ILogger _logger; public ParkingService(IServiceScopeFactory scopeFactory, ILogger logger) { _scopeFactory = scopeFactory; _logger = logger; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { await PerformParkingCheckAsync(stoppingToken); while (!stoppingToken.IsCancellationRequested) { await Task.Delay(TimeSpan.FromSeconds(50), stoppingToken); //每50秒執行 await PerformParkingCheckAsync(stoppingToken); } } private async Task PerformParkingCheckAsync(CancellationToken stoppingToken) { using (var scope = _scopeFactory.CreateScope()) { var _context = scope.ServiceProvider.GetRequiredService(); var now = DateTime.Now; var startTime = now.AddHours(-12); // 獲取最近 12 小時進入的車輛 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); var monthlycar = 0; var temporarycar = 0; foreach (var car in inCars) { var matchedUsers = monthlyUsers .Where(user => user.user_license_plate_number == car.license_plate_number) .ToList(); if (matchedUsers.Count > 0) { if (matchedUsers.Count % 2 == 1) { monthlycar++; } else { monthlycar--; } } else { temporarycar++; } } _logger.LogInformation($"月租車位數量: {monthlycar}"); _logger.LogInformation($"臨停車位數量: {temporarycar}"); await UpdateMonthly(_context, monthlycar, temporarycar, stoppingToken); //更新月租跟臨停 } } 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(); } var temporaryRentData = await context.yuntech_monthly_rent_number .FirstOrDefaultAsync(rent => rent.category == "臨停", stoppingToken); if (temporaryRentData != null) { temporaryRentData.number = temporarycar.ToString(); } await context.SaveChangesAsync(stoppingToken); } } #endregion #region 執行計算剩餘車位並不為負數存入資料庫ParkingLogs 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(); 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; if (monthly_rent_data != null) { Int32.TryParse(monthly_rent_data.number, out monthlyRentNumber); } 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); } 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 = Math.Max(remainingSpaces, 0), // 確保儲存時不為負數 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}"); } } // 每 30 秒執行一次 await Task.Delay(TimeSpan.FromSeconds(30), stoppingToken); } } } #endregion