212 lines
7.6 KiB
C#
212 lines
7.6 KiB
C#
using System.Text.Json;
|
|
using Microsoft.Extensions.Configuration;
|
|
using UtopiaCanteenSystem.Data;
|
|
using UtopiaCanteenSystem.Models;
|
|
using UtopiaCanteenSystem.Services;
|
|
|
|
namespace UtopiaCanteen.BackendService;
|
|
|
|
/// <summary>
|
|
/// Backend service configuration: appsettings.json + persisted JSON under LocalApplicationData.
|
|
/// </summary>
|
|
public sealed class BackendHostConfigService : IConfigService
|
|
{
|
|
private readonly IConfiguration _configuration;
|
|
private readonly string _persistedPath;
|
|
private PersistedConfig _persisted;
|
|
|
|
public BackendHostConfigService(IConfiguration configuration)
|
|
{
|
|
_configuration = configuration;
|
|
_persistedPath = Path.Combine(DatabasePath.GetAppDataFolder(), "backend-settings.json");
|
|
_persisted = LoadPersisted();
|
|
MergeFromAppSettingsIfNeeded();
|
|
}
|
|
|
|
public string GetListenUrls() =>
|
|
_configuration["ListenUrls"] ?? "http://0.0.0.0:5000";
|
|
|
|
public string GetSyncApiEndpoint() => _configuration["SyncApiEndpoint"] ?? _persisted.SyncApiEndpoint ?? string.Empty;
|
|
public void SetSyncApiEndpoint(string endpoint) { _persisted.SyncApiEndpoint = endpoint ?? string.Empty; SavePersisted(); }
|
|
|
|
public bool GetSyncServiceEnabled() =>
|
|
_configuration.GetValue("SyncServiceEnabled", _persisted.SyncServiceEnabled);
|
|
|
|
public void SetSyncServiceEnabled(bool enabled) { _persisted.SyncServiceEnabled = enabled; SavePersisted(); }
|
|
|
|
public bool GetScannerConnected() => false;
|
|
public void SetScannerConnected(bool connected) { }
|
|
|
|
public int GetScanIntervalDays() => 0;
|
|
public void SetScanIntervalDays(int value) { }
|
|
public int GetScanIntervalHours() => 0;
|
|
public void SetScanIntervalHours(int value) { }
|
|
public int GetScanIntervalMinutes() => 1;
|
|
public void SetScanIntervalMinutes(int value) { }
|
|
public int GetScanIntervalSeconds() => 0;
|
|
public void SetScanIntervalSeconds(int value) { }
|
|
public TimeSpan GetScanInterval() => TimeSpan.FromMinutes(1);
|
|
|
|
public string GetAdminCardId() => "ADMIN";
|
|
public void SetAdminCardId(string cardId) { }
|
|
|
|
public string GetSiteId() => _persisted.SiteId ?? "02";
|
|
public void SetSiteId(string siteId) { _persisted.SiteId = siteId ?? string.Empty; SavePersisted(); }
|
|
|
|
public void ApplyLocationSiteIdFromAuth(string? locationSiteId) { }
|
|
|
|
public string GetDeviceId()
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(_persisted.DeviceId))
|
|
return _persisted.DeviceId.Trim();
|
|
|
|
_persisted.DeviceId = ResolveMachineDeviceId();
|
|
SavePersisted();
|
|
return _persisted.DeviceId;
|
|
}
|
|
|
|
public void SetDeviceId(string deviceId)
|
|
{
|
|
_persisted.DeviceId = string.IsNullOrWhiteSpace(deviceId)
|
|
? ResolveMachineDeviceId()
|
|
: deviceId.Trim();
|
|
SavePersisted();
|
|
}
|
|
|
|
public bool GetRememberAdminCredentials() => false;
|
|
public void SetRememberAdminCredentials(bool remember) { }
|
|
public string GetSavedAdminUsername() => string.Empty;
|
|
public void SetSavedAdminUsername(string username) { }
|
|
public string GetSavedAdminPassword() => string.Empty;
|
|
public void SetSavedAdminPassword(string password) { }
|
|
|
|
public string GetMySqlConnectionString() =>
|
|
FirstNonEmpty(_configuration["MySqlConnectionString"], _persisted.MySqlConnectionString);
|
|
|
|
public void SetMySqlConnectionString(string connectionString)
|
|
{
|
|
_persisted.MySqlConnectionString = connectionString ?? string.Empty;
|
|
SavePersisted();
|
|
}
|
|
|
|
public string GetHrmsLookupConnectionString() =>
|
|
ConfigConnectionHelper.GetHrmsOrProductionConnectionString(
|
|
FirstNonEmpty(_configuration["HrmsLookupConnectionString"], _persisted.HrmsLookupConnectionString),
|
|
GetMySqlConnectionString());
|
|
|
|
public void SetHrmsLookupConnectionString(string connectionString)
|
|
{
|
|
_persisted.HrmsLookupConnectionString = connectionString ?? string.Empty;
|
|
SavePersisted();
|
|
}
|
|
|
|
public DateTime? GetLastEmployeeRfidCacheSyncUtc() => _persisted.LastEmployeeRfidCacheSyncUtc;
|
|
public void SetLastEmployeeRfidCacheSyncUtc(DateTime utc)
|
|
{
|
|
_persisted.LastEmployeeRfidCacheSyncUtc = utc;
|
|
SavePersisted();
|
|
}
|
|
|
|
public DateTime? GetLastMealMenuCacheSyncUtc() => _persisted.LastMealMenuCacheSyncUtc;
|
|
public void SetLastMealMenuCacheSyncUtc(DateTime utc)
|
|
{
|
|
_persisted.LastMealMenuCacheSyncUtc = utc;
|
|
SavePersisted();
|
|
}
|
|
|
|
public AppMode GetAppMode() => AppMode.Server;
|
|
public void SetAppMode(AppMode mode) { }
|
|
|
|
public string GetCentralServerBaseUrl() => string.Empty;
|
|
public void SetCentralServerBaseUrl(string url) { }
|
|
|
|
public string GetBackendBaseUrl() => DeriveLocalhostApiBaseUrl(GetListenUrls());
|
|
|
|
public string GetLocalServerListenUrls() => GetListenUrls();
|
|
public void SetLocalServerListenUrls(string urls) { }
|
|
|
|
private static string ResolveMachineDeviceId()
|
|
{
|
|
var machineName = Environment.MachineName;
|
|
return string.IsNullOrWhiteSpace(machineName)
|
|
? Guid.NewGuid().ToString("N")
|
|
: machineName.Trim();
|
|
}
|
|
|
|
private void MergeFromAppSettingsIfNeeded()
|
|
{
|
|
var mysql = _configuration["MySqlConnectionString"];
|
|
if (!string.IsNullOrWhiteSpace(mysql) && string.IsNullOrWhiteSpace(_persisted.MySqlConnectionString))
|
|
_persisted.MySqlConnectionString = mysql;
|
|
|
|
var hrms = _configuration["HrmsLookupConnectionString"];
|
|
if (!string.IsNullOrWhiteSpace(hrms) && string.IsNullOrWhiteSpace(_persisted.HrmsLookupConnectionString))
|
|
_persisted.HrmsLookupConnectionString = hrms;
|
|
|
|
SavePersisted();
|
|
}
|
|
|
|
private static string FirstNonEmpty(params string?[] values)
|
|
{
|
|
foreach (var v in values)
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(v))
|
|
return v!;
|
|
}
|
|
return string.Empty;
|
|
}
|
|
|
|
private static string DeriveLocalhostApiBaseUrl(string listenUrls)
|
|
{
|
|
var first = listenUrls
|
|
.Split(new[] { ';', ',' }, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
|
|
.FirstOrDefault() ?? "http://0.0.0.0:5000";
|
|
first = first.TrimEnd('/');
|
|
if (first.Contains("0.0.0.0", StringComparison.Ordinal))
|
|
first = first.Replace("0.0.0.0", "localhost", StringComparison.Ordinal);
|
|
if (first.Contains('+'))
|
|
first = first.Replace("+", "localhost", StringComparison.Ordinal);
|
|
return first;
|
|
}
|
|
|
|
private PersistedConfig LoadPersisted()
|
|
{
|
|
try
|
|
{
|
|
if (!File.Exists(_persistedPath))
|
|
return new PersistedConfig();
|
|
var json = File.ReadAllText(_persistedPath);
|
|
return JsonSerializer.Deserialize<PersistedConfig>(json) ?? new PersistedConfig();
|
|
}
|
|
catch
|
|
{
|
|
return new PersistedConfig();
|
|
}
|
|
}
|
|
|
|
private void SavePersisted()
|
|
{
|
|
try
|
|
{
|
|
var json = JsonSerializer.Serialize(_persisted, new JsonSerializerOptions { WriteIndented = true });
|
|
File.WriteAllText(_persistedPath, json);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Log(ex, "BackendHostConfigService.SavePersisted");
|
|
}
|
|
}
|
|
|
|
private sealed class PersistedConfig
|
|
{
|
|
public string? SyncApiEndpoint { get; set; }
|
|
public bool SyncServiceEnabled { get; set; } = true;
|
|
public string? MySqlConnectionString { get; set; }
|
|
public string? HrmsLookupConnectionString { get; set; }
|
|
public DateTime? LastEmployeeRfidCacheSyncUtc { get; set; }
|
|
public DateTime? LastMealMenuCacheSyncUtc { get; set; }
|
|
public string? SiteId { get; set; }
|
|
public string? DeviceId { get; set; }
|
|
}
|
|
}
|