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:
@@ -20,6 +20,10 @@ public partial class App : Application
|
|||||||
ConfigureServices(services);
|
ConfigureServices(services);
|
||||||
Services = services.BuildServiceProvider();
|
Services = services.BuildServiceProvider();
|
||||||
|
|
||||||
|
// 启动时加载配置文件(含路径验证与容错)
|
||||||
|
var dataService = Services.GetRequiredService<IDataService>();
|
||||||
|
dataService.Load();
|
||||||
|
|
||||||
var mainWindow = Services.GetRequiredService<MainWindow>();
|
var mainWindow = Services.GetRequiredService<MainWindow>();
|
||||||
mainWindow.Show();
|
mainWindow.Show();
|
||||||
}
|
}
|
||||||
@@ -32,6 +36,9 @@ public partial class App : Application
|
|||||||
// 日志服务
|
// 日志服务
|
||||||
services.AddSingleton<ILogService, LogService>();
|
services.AddSingleton<ILogService, LogService>();
|
||||||
|
|
||||||
|
// 数据持久化服务
|
||||||
|
services.AddSingleton<IDataService, JsonDataService>();
|
||||||
|
|
||||||
// 主窗口
|
// 主窗口
|
||||||
services.AddSingleton<MainWindow>();
|
services.AddSingleton<MainWindow>();
|
||||||
}
|
}
|
||||||
|
|||||||
27
PersonalToolBox/Models/AppConfig.cs
Normal file
27
PersonalToolBox/Models/AppConfig.cs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
namespace PersonalToolBox.Models;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 应用全局配置,对应 config.json 的顶层结构
|
||||||
|
/// </summary>
|
||||||
|
public class AppConfig
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 主题模式 (Dark / Light)
|
||||||
|
/// </summary>
|
||||||
|
public string Theme { get; set; } = "Dark";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否开机自启动
|
||||||
|
/// </summary>
|
||||||
|
public bool AutoStart { get; set; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 工具分类列表
|
||||||
|
/// </summary>
|
||||||
|
public List<Category> Categories { get; set; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 工具项列表
|
||||||
|
/// </summary>
|
||||||
|
public List<ToolItem> Tools { get; set; } = new();
|
||||||
|
}
|
||||||
17
PersonalToolBox/Models/Category.cs
Normal file
17
PersonalToolBox/Models/Category.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
namespace PersonalToolBox.Models;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 工具标签页分类
|
||||||
|
/// </summary>
|
||||||
|
public class Category
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 分类唯一标识
|
||||||
|
/// </summary>
|
||||||
|
public string Id { get; set; } = Guid.NewGuid().ToString();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 分类显示名称(如:开发工具、常用脚本)
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
50
PersonalToolBox/Models/ToolItem.cs
Normal file
50
PersonalToolBox/Models/ToolItem.cs
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace PersonalToolBox.Models;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 工具项模型,表示用户添加的一个可执行工具
|
||||||
|
/// </summary>
|
||||||
|
public class ToolItem
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 工具唯一标识 (UUID)
|
||||||
|
/// </summary>
|
||||||
|
public string Id { get; set; } = Guid.NewGuid().ToString();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 工具显示名称
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 内置图标库的字符编码
|
||||||
|
/// </summary>
|
||||||
|
public string IconCode { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 可执行文件路径或 URL
|
||||||
|
/// </summary>
|
||||||
|
public string ExecutablePath { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 运行参数(选填)
|
||||||
|
/// </summary>
|
||||||
|
public string Arguments { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 所属分类 ID
|
||||||
|
/// </summary>
|
||||||
|
public string CategoryId { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 全局快捷键(如 Ctrl+Alt+T),选填
|
||||||
|
/// </summary>
|
||||||
|
public string HotKey { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 路径是否有效(仅运行时计算,不存入 JSON)
|
||||||
|
/// </summary>
|
||||||
|
[JsonIgnore]
|
||||||
|
public bool IsValid { get; set; } = true;
|
||||||
|
}
|
||||||
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