Phase 1: data models and local storage service
- Add Models: Category, ToolItem (IsValid runtime-only, not stored), AppConfig - Add Services: IDataService + JsonDataService (JSON load/save) - Path validation on Load(): File.Exists check, logs warning for missing paths - Startup: auto-calls dataService.Load() to load config
This commit is contained in:
24
PersonalToolBox/Services/IDataService.cs
Normal file
24
PersonalToolBox/Services/IDataService.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using PersonalToolBox.Models;
|
||||
|
||||
namespace PersonalToolBox.Services;
|
||||
|
||||
/// <summary>
|
||||
/// 数据持久化服务接口,负责配置的加载和保存
|
||||
/// </summary>
|
||||
public interface IDataService
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前加载的配置数据
|
||||
/// </summary>
|
||||
AppConfig Config { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 从 config.json 加载配置,验证工具路径有效性
|
||||
/// </summary>
|
||||
void Load();
|
||||
|
||||
/// <summary>
|
||||
/// 保存当前配置到 config.json
|
||||
/// </summary>
|
||||
void Save();
|
||||
}
|
||||
97
PersonalToolBox/Services/JsonDataService.cs
Normal file
97
PersonalToolBox/Services/JsonDataService.cs
Normal file
@@ -0,0 +1,97 @@
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using PersonalToolBox.Models;
|
||||
|
||||
namespace PersonalToolBox.Services;
|
||||
|
||||
/// <summary>
|
||||
/// 基于 JSON 文件的数据持久化服务
|
||||
/// 配置文件路径: 可执行程序目录/config.json
|
||||
/// </summary>
|
||||
public class JsonDataService : IDataService
|
||||
{
|
||||
private readonly ILogService _logService;
|
||||
private readonly string _filePath;
|
||||
|
||||
private static readonly JsonSerializerOptions JsonOptions = new()
|
||||
{
|
||||
WriteIndented = true,
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
public AppConfig Config { get; private set; } = new();
|
||||
|
||||
public JsonDataService(ILogService logService)
|
||||
{
|
||||
_logService = logService;
|
||||
_filePath = Path.Combine(AppContext.BaseDirectory, "config.json");
|
||||
}
|
||||
|
||||
public void Load()
|
||||
{
|
||||
if (!File.Exists(_filePath))
|
||||
{
|
||||
_logService.Info("配置文件不存在,使用默认配置");
|
||||
Config = new AppConfig();
|
||||
Save();
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var json = File.ReadAllText(_filePath);
|
||||
var config = JsonSerializer.Deserialize<AppConfig>(json, JsonOptions);
|
||||
|
||||
if (config == null)
|
||||
{
|
||||
_logService.Warning("配置文件解析结果为空,使用默认配置");
|
||||
Config = new AppConfig();
|
||||
return;
|
||||
}
|
||||
|
||||
Config = config;
|
||||
|
||||
// 核心容错逻辑:验证所有工具路径是否有效
|
||||
foreach (var tool in Config.Tools)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(tool.ExecutablePath))
|
||||
continue;
|
||||
|
||||
// URL 格式的路径(如 https://...)不需要检查本地文件是否存在
|
||||
if (Uri.TryCreate(tool.ExecutablePath, UriKind.Absolute, out var uri) &&
|
||||
(uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps))
|
||||
{
|
||||
tool.IsValid = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!File.Exists(tool.ExecutablePath))
|
||||
{
|
||||
tool.IsValid = false;
|
||||
_logService.Warning($"工具 \"{tool.Name}\" 路径失效,找不到文件: {tool.ExecutablePath}");
|
||||
}
|
||||
}
|
||||
|
||||
_logService.Info($"配置加载完成: {Config.Categories.Count} 个分类, {Config.Tools.Count} 个工具");
|
||||
}
|
||||
catch (JsonException ex)
|
||||
{
|
||||
_logService.Error($"配置文件 JSON 解析失败: {ex.Message}");
|
||||
Config = new AppConfig();
|
||||
}
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
try
|
||||
{
|
||||
var json = JsonSerializer.Serialize(Config, JsonOptions);
|
||||
File.WriteAllText(_filePath, json);
|
||||
_logService.Info("配置已保存");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logService.Error($"配置保存失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user