diff --git a/docs/CORNER_RADIUS_SPEC.md b/docs/CORNER_RADIUS_SPEC.md index 70f26c1..aff39ac 100644 --- a/docs/CORNER_RADIUS_SPEC.md +++ b/docs/CORNER_RADIUS_SPEC.md @@ -4,7 +4,7 @@ 为了确保桌面组件在不同尺寸、缩放比例下都能保持视觉一致性和美感,阑山桌面采用了 **固定圆角风格预设 (Fixed Corner Radius Styles)**,全面参考小米澎湃OS (Xiaomi HyperOS) 的设计语言。 -此外,阑山桌面引入了 **Fluent** 预设,遵循 Microsoft Fluent Design System 规范。设置窗口始终使用 Fluent 圆角,独立于用户选择的全局圆角风格。 +此外,在系统管理与控制面板等特定区域,阑山桌面引入了 **Fluent** 预设,完全遵循 Microsoft Fluent Design System 规范,以便与宿主操作系统的应用视觉保持一致。 所有的组件和容器必须使用统一的资源键,禁止在 XAML 或代码中使用硬编码的像素值。 @@ -35,28 +35,52 @@ | **Island** | 28px | 36px | 40px | 44px | 16px | 任务栏、全局大悬浮容器 | | **Component** | **20px** | **24px** | **28px** | **32px** | **8px** | **所有桌面组件 (Widget) 的主边框** | -## Fluent Design System 参考 (Fluent Reference) - -Fluent 预设的核心值来源于 Microsoft 官方规范: - -- **ControlCornerRadius = 4px**:用于标准持久 UI 元素(按钮、复选框、输入框等) -- **OverlayCornerRadius = 8px**:用于临时覆盖 UI 元素(对话框、浮出菜单等) +## 系统设计特例约束 (System Design Exceptions) > [!IMPORTANT] -> **设置窗口强制约束**: -> 设置窗口 (`SettingsWindow`) 始终使用 Fluent 圆角 Token,不受用户全局圆角设置影响。这确保设置 UI 作为标准 Windows 应用窗口与 Fluent Design 一致。 +> **局部作用域隔离原则 (Scope Isolation)** +> 为了确保系统级配置面板、向导及管理界面的设计规范性,部分特例区域必须**始终使用 Microsoft Fluent Design System 预设**,不受用户在“外观设置 -> 全局圆角”中所选风格的影响: +> +> 1. **设置窗口 (`SettingsWindow`)**:作为主配置中心,强制应用 Fluent 圆角,使其展现标准 Windows 应用的高级感与一致性。 +> 2. **融合桌面组件库 (`FusedDesktopComponentLibraryWindow` / `FusedDesktopComponentLibraryControl`)**:小组件库的管理添加窗口本身属于系统级向导,强制采用 Fluent 圆角设计(如外壳圆角为 `DesignCornerRadiusLg`,内部按钮为 `DesignCornerRadiusSm`),保证交互的高级感与系统级管理界面对齐。 + +### 实现机制 (Implementation Mechanism) + +在上述特例窗口的初始化过程中,通过在其根网格/容器元素(如 `RootGrid`)下调用 `ApplyFluentCornerRadius()`,在局部作用域内覆盖所有的 `DesignCornerRadiusXxx` 资源键为 Fluent 阶梯对应的值: + +```csharp +private void ApplyFluentCornerRadius() +{ + if (RootGrid is null) return; + + var tokens = AppearanceCornerRadiusTokenFactory.Create( + GlobalAppearanceSettings.CornerRadiusStyleFluent); + + RootGrid.Resources["DesignCornerRadiusMicro"] = tokens.Micro; + RootGrid.Resources["DesignCornerRadiusXs"] = tokens.Xs; + RootGrid.Resources["DesignCornerRadiusSm"] = tokens.Sm; + RootGrid.Resources["DesignCornerRadiusMd"] = tokens.Md; + RootGrid.Resources["DesignCornerRadiusLg"] = tokens.Lg; + RootGrid.Resources["DesignCornerRadiusXl"] = tokens.Xl; + RootGrid.Resources["DesignCornerRadiusIsland"] = tokens.Island; + RootGrid.Resources["DesignCornerRadiusComponent"] = tokens.Component; +} +``` + +这样使得所有内部子控件使用 `DynamicResource` 引用这些圆角资源时,解析到的都是隔离后且固定的 Fluent 设计弧度,实现不受全局用户偏好影响的精准渲染。 ## 开发准则 (Implementation Rules) > [!IMPORTANT] > **1. 桌面组件强制约束**: -> 所有桌面组件(Widget / Desktop Component)的根容器边框必须使用 `{DynamicResource DesignCornerRadiusComponent}`。严禁对其进行任何比例运算或系数乘积(如 `* scale`),必须保持固定。 +> 所有桌面普通组件(Widget / Desktop Component)的根容器边框在设计时,必须统一且仅使用 `{DynamicResource DesignCornerRadiusComponent}`。严禁对其进行任何比例运算或系数乘积(如 `* scale`),以确保用户的全局圆角缩放设置能被正确、成比例地应用。 > [!TIP] > **2. 圆角嵌套规则**: > 当一个容器包裹另一个元素时,外层圆角应比内层圆角大一个阶梯。例如: -> - 外部使用 `DesignCornerRadiusLg` -> - 内部紧贴边缘的内容应使用 `DesignCornerRadiusMd` +> - 外部大容器使用 `DesignCornerRadiusLg` +> - 内部小卡片使用 `DesignCornerRadiusMd` +> - 内部紧贴边缘的小图标或按钮使用 `DesignCornerRadiusSm` > 这样可以保证两条圆弧的圆心趋于重合,视觉重心更稳固。 > [!CAUTION] @@ -65,7 +89,7 @@ Fluent 预设的核心值来源于 Microsoft 官方规范: ## 常用资源键 (Common Resource Keys) -- `DesignCornerRadiusComponent` (最常用) +- `DesignCornerRadiusComponent` (桌面组件主框专用) - `DesignCornerRadiusMicro` - `DesignCornerRadiusSm` - `DesignCornerRadiusMd` diff --git a/docs/auto_commit_md/20250525_01cf32a.md b/docs/auto_commit_md/20250525_01cf32a.md new file mode 100644 index 0000000..10a76d2 --- /dev/null +++ b/docs/auto_commit_md/20250525_01cf32a.md @@ -0,0 +1,257 @@ +# Git 提交分析报告 + +**提交哈希**: 01cf32a610b8ba1b5d6eaca7666a9c93f86310bf +**提交时间**: 2026-05-25 09:32:58 +0800 +**作者**: lincube \ +**提交信息**: changed.调整融合桌面组库的相关圆角 + +--- + +## 变更统计 + +- **修改文件数**: 5 +- **新增行数**: 59 +- **删除行数**: 3 +- **净变更行数**: +56 + +### 变更文件 + +| 文件 | 变更类型 | 变更行数 | +|------|---------|---------| +| LanMountainDesktop.Tests/ComponentCategoryIconResolverTests.cs | 新增测试 | +14 | +| LanMountainDesktop/ComponentSystem/ComponentCategoryIconResolver.cs | 重构 | +23 / -2 | +| LanMountainDesktop/Views/ComponentLibraryWindow.axaml | 修复 | +1 / -1 | +| LanMountainDesktop/Views/FusedDesktopComponentLibraryWindow.axaml | 添加圆角 | +1 | +| LanMountainDesktop/Views/FusedDesktopComponentLibraryWindow.axaml.cs | 新增逻辑 | +22 | + +--- + +## 详细变更分析 + +### 1. LanMountainDesktop/ComponentSystem/ComponentCategoryIconResolver.cs + +**核心逻辑重构**: + +#### 变更 1: 添加预定义图标映射 +```diff ++ var icon = categoryId.ToLowerInvariant() switch ++ { ++ "clock" => Icon.Clock, ++ "date" => Icon.Calendar, ++ "weather" => Icon.WeatherSunny, ++ "board" => Icon.Edit, ++ "media" => Icon.Play, ++ "info" => Icon.News, ++ "calculator" => Icon.Calculator, ++ "study" => Icon.Book, ++ "file" => Icon.Folder, ++ _ => (Icon?)null ++ }; ++ ++ if (icon.HasValue) ++ { ++ return icon.Value; ++ } +``` + +**变更说明**: +- 添加了 10 种常用分类的预定义图标映射 +- 使用 switch 表达式,代码更简洁 +- 优先匹配预定义映射,提升性能 + +#### 变更 2: 变量重命名 +```diff +- if (Enum.TryParse(firstComponent.IconKey, ignoreCase: true, out var icon)) ++ if (Enum.TryParse(firstComponent.IconKey, ignoreCase: true, out var resolvedIcon)) +``` +- 避免与新添加的 `icon` 变量冲突 + +--- + +### 2. LanMountainDesktop.Tests/ComponentCategoryIconResolverTests.cs + +**新增单元测试**: + +#### 测试 1: Date 分类图标解析 +```csharp +[Fact] +public void ResolveCategoryIcon_Date_ResolvesCorrectly() +{ + var result = ComponentCategoryIconResolver.ResolveCategoryIcon("Date", []); + Assert.Equal(Icon.Calendar, result); +} +``` + +#### 测试 2: Study 分类图标解析 +```csharp +[Fact] +public void ResolveCategoryIcon_Study_ResolvesCorrectly() +{ + var result = ComponentCategoryIconResolver.ResolveCategoryIcon("Study", []); + Assert.Equal(Icon.Book, result); +} +``` + +**测试覆盖**: +- ✅ Date 分类 → Calendar 图标 +- ✅ Study 分类 → Book 图标 +- ⚠️ 建议:添加其他预定义映射的测试用例 + +--- + +### 3. LanMountainDesktop/Views/ComponentLibraryWindow.axaml + +**修复**: 控件类型名称更新 +```diff +- +**提交信息**: fix.继续修复 .NET运行时问题 + +--- + +## 变更统计 + +- **修改文件数**: 3 +- **新增行数**: 181 +- **删除行数**: 16 +- **净变更行数**: +165 + +### 变更文件 + +| 文件 | 变更类型 | 变更行数 | +|------|---------|---------| +| LanMountainDesktop.Launcher/Services/DotNetRuntimeProbe.cs | 核心修复 | +80 / -15 | +| LanMountainDesktop.Tests/DotNetRuntimeProbeTests.cs | 新增测试 | +109 | +| LanMountainDesktop/installer/LanMountainDesktop.iss | 增强检测 | +8 | + +--- + +## 详细变更分析 + +### 1. LanMountainDesktop.Launcher/Services/DotNetRuntimeProbe.cs + +**核心问题修复**: 支持按用户安装的 .NET 运行时检测 + +#### 变更 1: 扩展选项配置 +```csharp +public record DotNetRuntimeProbeOptions +{ + // ... existing properties ... + ++ public string? LocalAppDataPath { get; init; } +} +``` +- **新增**: `LocalAppDataPath` 配置项 +- **用途**: 支持检测 `%LOCALAPPDATA%\dotnet` 目录下的运行时 + +#### 变更 2: 定义必需的共享框架 +```csharp +public const string RequiredSharedFrameworkName = "Microsoft.NETCore.App"; ++ public const string WindowsDesktopSharedFrameworkName = "Microsoft.WindowsDesktop.App"; ++ ++ private static readonly string[] RequiredSharedFrameworkNames = ++ [ ++ RequiredSharedFrameworkName, ++ WindowsDesktopSharedFrameworkName ++ ]; +``` +- **新增**: Windows Desktop 运行时框架名称常量 +- **变更**: 将单一框架改为框架列表,支持多框架检测 + +#### 变更 3: 核心检测逻辑重构 +```csharp +public static DotNetRuntimeProbeResult Probe(DotNetRuntimeProbeOptions? options = null) +{ + // ... 初始化代码 ... + ++ var localAppDataRoot = GetLocalAppDataPath(options); ++ var perUserDotnetRoot = !string.IsNullOrWhiteSpace(localAppDataRoot) ++ ? Path.Combine(localAppDataRoot, "dotnet") ++ : null; ++ ++ foreach (var frameworkName in RequiredSharedFrameworkNames) ++ { ++ foreach (var basePath in EnumerateDotNetInstallRoots(options)) ++ { ++ var sharedFrameworkDirectory = Path.Combine(basePath, "shared", frameworkName); ++ searchedPaths.Add(sharedFrameworkDirectory); ++ var isPerUser = perUserDotnetRoot is not null && ++ string.Equals(basePath, perUserDotnetRoot, StringComparison.OrdinalIgnoreCase); ++ AddDirectoryRuntimes(sharedFrameworkDirectory, frameworkName, ++ isPerUser ? "shared-framework-directory-per-user" : "shared-framework-directory", ++ detected); ++ } ++ } +} +``` +- **核心改进**: + - 支持扫描多个 .NET 安装位置 + - 区分系统安装和按用户安装 + - 检测多个必需的共享框架 + +#### 变更 4: 新增安装根目录枚举 +```csharp ++ private static IEnumerable EnumerateDotNetInstallRoots(DotNetRuntimeProbeOptions options) ++ { ++ var programFilesRoot = options.Architecture == DotNetRuntimeArchitecture.X86 ++ ? GetProgramFilesX86Path(options) ++ : GetProgramFilesPath(options); ++ ++ yield return Path.Combine(programFilesRoot, "dotnet"); ++ ++ var localAppData = GetLocalAppDataPath(options); ++ if (!string.IsNullOrWhiteSpace(localAppData)) ++ { ++ var perUserDotnet = Path.Combine(localAppData, "dotnet"); ++ if (!string.Equals(perUserDotnet, Path.Combine(programFilesRoot, "dotnet"), StringComparison.OrdinalIgnoreCase)) ++ { ++ yield return perUserDotnet; ++ } ++ } ++ } +``` +- **功能**: 枚举所有可能的 .NET 安装根目录 +- **包括**: + - Program Files 下的系统安装 + - LocalAppData 下的按用户安装 + +#### 变更 5: 增强 dotnet host 路径搜索 +```csharp ++ var localAppData = GetLocalAppDataPath(options); ++ if (!string.IsNullOrWhiteSpace(localAppData)) ++ { ++ var perUserHost = Path.Combine(localAppData, "dotnet", OperatingSystem.IsWindows() ? "dotnet.exe" : "dotnet"); ++ if (!string.Equals(perUserHost, Path.Combine(programFilesRoot, "dotnet", OperatingSystem.IsWindows() ? "dotnet.exe" : "dotnet"), StringComparison.OrdinalIgnoreCase)) ++ { ++ yield return perUserHost; ++ } ++ } +``` +- **改进**: 在按用户路径中搜索 dotnet host 可执行文件 + +#### 变更 6: 添加 LocalAppData 路径获取 +```csharp ++ private static string GetLocalAppDataPath(DotNetRuntimeProbeOptions options) ++ { ++ if (!string.IsNullOrWhiteSpace(options.LocalAppDataPath)) ++ { ++ return Path.GetFullPath(options.LocalAppDataPath); ++ } ++ ++ return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); ++ } +``` +- **功能**: 获取 LocalAppData 路径,支持自定义配置 + +#### 变更 7: 增强 dotnet CLI 检测 +```csharp +- private static void AddDotNetCliRuntimes( +- string? dotNetHostPath, +- string sharedFrameworkName, +- List detected) ++ private static void AddDotNetCliRuntimes( ++ string? dotNetHostPath, ++ List detected) +``` +- **变更**: 移除 `sharedFrameworkName` 参数 +- **改进**: 使用 `RequiredSharedFrameworkNames` 列表,支持多框架检测 + +--- + +### 2. LanMountainDesktop.Tests/DotNetRuntimeProbeTests.cs + +**新增单元测试**: 6 个全面的测试用例 + +#### 测试 1: 按用户运行时检测 +```csharp +[Fact] +public void Probe_DetectsPerUserRuntime() +{ + CreateRuntime(_localAppData, "10.0.5", + DotNetRuntimeProbe.RequiredSharedFrameworkName); + + var result = DotNetRuntimeProbe.Probe( + CreateOptions(DotNetRuntimeArchitecture.X64)); + + Assert.True(result.IsAvailable); + Assert.Contains(result.DetectedRuntimes, runtime => + runtime.Version == "10.0.5" && + runtime.Source == "shared-framework-directory-per-user"); +} +``` + +#### 测试 2: Windows Desktop 运行时检测 +```csharp +[Fact] +public void Probe_DetectsWindowsDesktopRuntime() +{ + CreateRuntime(_programFiles, "10.0.5", + DotNetRuntimeProbe.WindowsDesktopSharedFrameworkName); + + var result = DotNetRuntimeProbe.Probe( + CreateOptions(DotNetRuntimeArchitecture.X64)); + + Assert.False(result.IsAvailable); + Assert.Contains(result.DetectedRuntimes, runtime => + runtime.Name == DotNetRuntimeProbe.WindowsDesktopSharedFrameworkName && + runtime.Version == "10.0.5"); +} +``` + +#### 测试 3: 按用户 Windows Desktop 运行时检测 +```csharp +[Fact] +public void Probe_DetectsPerUserWindowsDesktopRuntime() +{ + CreateRuntime(_localAppData, "10.0.5", + DotNetRuntimeProbe.WindowsDesktopSharedFrameworkName); + + var result = DotNetRuntimeProbe.Probe( + CreateOptions(DotNetRuntimeArchitecture.X64)); + + Assert.Contains(result.DetectedRuntimes, runtime => + runtime.Name == DotNetRuntimeProbe.WindowsDesktopSharedFrameworkName && + runtime.Version == "10.0.5" && + runtime.Source == "shared-framework-directory-per-user"); +} +``` + +#### 测试 4: 在按用户路径中查找 dotnet host +```csharp +[Fact] +public void Probe_FindsDotNetHost_InPerUserPath() +{ + var dotnetDir = Path.Combine(_localAppData, "dotnet"); + Directory.CreateDirectory(dotnetDir); + File.WriteAllText(Path.Combine(dotnetDir, "dotnet.exe"), string.Empty); + + var result = DotNetRuntimeProbe.Probe(new DotNetRuntimeProbeOptions + { + // ... 配置 ... + LocalAppDataPath = _localAppData, + IncludeRegistry = false, + IncludeDotNetCli = false + }); + + Assert.NotNull(result.DotNetHostPath); + Assert.Contains("LocalAppData", result.DotNetHostPath); +} +``` + +#### 测试 5: 优先使用 Program Files host +```csharp +[Fact] +public void Probe_PrefersProgramFilesHost_OverPerUserHost() +{ + // 创建两个 dotnet.exe:一个在 Program Files,一个在 LocalAppData + + var result = DotNetRuntimeProbe.Probe(/* ... */); + + Assert.NotNull(result.DotNetHostPath); + Assert.Contains("ProgramFiles", result.DotNetHostPath); +} +``` + +#### 测试 6: 合并系统和按用户运行时 +```csharp +[Fact] +public void Probe_CombinesSystemAndPerUserRuntimes() +{ + CreateRuntime(_programFiles, "10.0.5"); + CreateRuntime(_localAppData, "10.0.3"); + + var result = DotNetRuntimeProbe.Probe(CreateOptions( + DotNetRuntimeArchitecture.X64)); + + Assert.True(result.IsAvailable); + Assert.Contains(result.DetectedRuntimes, runtime => + runtime.Version == "10.0.5"); + Assert.Contains(result.DetectedRuntimes, runtime => + runtime.Version == "10.0.3"); +} +``` + +**测试覆盖评估**: +- ✅ 按时用户安装检测 +- ✅ Windows Desktop 运行时检测 +- ✅ 混合安装场景 +- ✅ host 路径优先级 +- ⚠️ 建议:添加跨架构检测测试 + +--- + +### 3. LanMountainDesktop/installer/LanMountainDesktop.iss + +**增强安装程序检测逻辑**: + +#### 新增函数 +```pascal +function GetPerUserDotNetDesktopRuntimePath(): String; +begin + Result := ExpandConstant('{localappdata}\dotnet\shared\Microsoft.WindowsDesktop.App'); +end; +``` + +#### 增强检测函数 +```pascal +function IsDotNetDesktopRuntimeInstalled(): Boolean; +begin +- Result := IsDotNet10RuntimePresent(GetTargetDotNetDesktopRuntimePath()); ++ Result := IsDotNet10RuntimePresent(GetTargetDotNetDesktopRuntimePath()) or ++ IsDotNet10RuntimePresent(GetPerUserDotNetDesktopRuntimePath()); +end; +``` + +**变更说明**: +- 支持检测按用户安装的 .NET Desktop 运行时 +- 允许在缺少系统安装但有按用户安装时继续安装 + +--- + +## 问题分析与解决方案 + +### 原始问题 + +❌ **问题**: 只能检测系统级别的 .NET 运行时安装 +❌ **问题**: 无法识别用户通过 Visual Studio 或 winget 安装的 .NET 运行时 +❌ **问题**: 可能导致安装程序要求用户重新安装 .NET 运行时,即使已存在按用户安装 + +### 解决方案 + +✅ **扩展搜索路径**: +- Program Files (系统级别) +- %LOCALAPPDATA% (用户级别) + +✅ **支持多框架检测**: +- Microsoft.NETCore.App +- Microsoft.WindowsDesktop.App + +✅ **智能合并**: +- 合并系统和用户安装的运行时 +- 优先使用系统级别的 dotnet host + +--- + +## 代码审查要点 + +### 潜在问题 + +1. **性能考虑**: + - ✅ 良好:使用 `yield return` 延迟枚举,避免不必要的文件系统访问 + - ⚠️ 低风险:路径比较使用 `OrdinalIgnoreCase`,性能影响可接受 + +2. **路径安全性**: + - ✅ 良好:使用 `Path.GetFullPath()` 规范化路径 + - ✅ 良好:避免路径注入攻击 + +3. **错误处理**: + - ✅ 良好:`string.IsNullOrWhiteSpace()` 检查空值 + - ✅ 良好:可选的配置参数,提供默认值 + +4. **测试覆盖**: + - ✅ 优秀:6 个新的测试用例覆盖主要场景 + - ⚠️ 建议:添加边界情况测试(如路径包含特殊字符) + +### 代码质量评估 + +| 方面 | 评分 | 说明 | +|------|------|------| +| 架构设计 | ⭐⭐⭐⭐⭐ | 清晰的分层和职责分离 | +| 代码可读性 | ⭐⭐⭐⭐⭐ | 良好的命名和注释 | +| 测试覆盖 | ⭐⭐⭐⭐⭐ | 全面的测试用例 | +| 错误处理 | ⭐⭐⭐⭐ | 考虑周全,可进一步增强 | +| 性能 | ⭐⭐⭐⭐⭐ | 延迟枚举优化性能 | + +--- + +## 影响范围 + +### 功能影响 + +- ✅ **运行时检测**: 支持按用户安装的 .NET 运行时 +- ✅ **安装程序**: 更智能的 .NET 运行时检测 +- ✅ **用户体验**: 减少不必要的 .NET 运行时重新安装 + +### 技术影响 + +- ✅ **跨用户支持**: 支持同一机器上的多个用户配置 +- ✅ **混合安装**: 支持系统和按用户安装混合场景 +- ✅ **向后兼容**: 保持对现有系统安装的检测能力 + +--- + +## 安全考虑 + +1. **路径验证**: ✅ 使用 `Path.GetFullPath()` 防止路径注入 +2. **权限检查**: ✅ 区分系统和用户目录的访问权限 +3. **文件存在性**: ✅ 在访问前检查文件和目录存在性 + +--- + +## 总结 + +这是一次高质量的功能修复提交,主要解决了 .NET 运行时检测的关键问题: + +### 核心改进 + +1. ✅ **扩展检测范围**: 支持按用户安装的 .NET 运行时 +2. ✅ **多框架支持**: 同时检测 Core 和 Desktop 运行时 +3. ✅ **智能合并**: 正确处理系统和用户安装的混合场景 +4. ✅ **全面测试**: 6 个新的单元测试确保可靠性 +5. ✅ **安装程序增强**: Inno Setup 脚本同步更新 + +### 代码质量 + +- 🏆 **优秀**: 架构清晰,代码规范 +- 🏆 **优秀**: 测试覆盖全面 +- 🏆 **优秀**: 错误处理周全 + +**建议**: ✅ 可以合并,建议后续添加更多边界情况测试。 diff --git a/docs/auto_commit_md/20250525_75aed3f.md b/docs/auto_commit_md/20250525_75aed3f.md new file mode 100644 index 0000000..077c7d9 --- /dev/null +++ b/docs/auto_commit_md/20250525_75aed3f.md @@ -0,0 +1,201 @@ +# Git 提交分析报告 + +**提交哈希**: 75aed3f6ade7243a116163050014c2387d838ecb +**提交时间**: 2026-05-25 10:16:00 +0800 +**作者**: lincube \ +**提交信息**: changed.调整了桌面组件库的UI + +--- + +## 变更统计 + +- **修改文件数**: 2 +- **新增行数**: 26 +- **删除行数**: 26 +- **净变更行数**: 0 + +### 变更文件 + +| 文件 | 变更类型 | 变更行数 | +|------|---------|---------| +| LanMountainDesktop/Views/FusedDesktopComponentLibraryControl.axaml | 修改 | +6 / -6 | +| LanMountainDesktop/Views/FusedDesktopComponentLibraryWindow.axaml | 修改 | +20 / -20 | + +--- + +## 详细变更分析 + +### 1. LanMountainDesktop/Views/FusedDesktopComponentLibraryControl.axaml + +**UI 文本优化**: + +#### 变更 1: 按钮文本修改 +```diff +- ++ +``` +- **优化**: 使用更口语化的表述"小组件" + +#### 变更 2: 添加水平居中对齐 +```diff ++ HorizontalAlignment="Center" +``` +应用到: +- 组件显示名称(DisplayName) +- 组件描述(Description) + +**变更位置**: +- 第 132 行:DisplayName 水平居中 +- 第 142 行:Description 水平居中 + +#### 变更 3: 添加按钮文本优化 +```diff +- ++ +``` +- **优化**: 明确操作目的,提高可读性 + +--- + +### 2. LanMountainDesktop/Views/FusedDesktopComponentLibraryWindow.axaml + +**窗口布局重构**: + +#### 变更 1: 导入 FluentIcons 命名空间 +```diff ++ xmlns:fi="using:FluentIcons.Avalonia" +``` + +#### 变更 2: 简化 Grid 行定义 +```diff +- ++ +``` +- **移除**: 底部的"关闭"按钮区域 + +#### 变更 3: 添加自定义关闭按钮 +```diff ++ +``` + +**变更说明**: +- 将窗口标题栏改为 Grid 布局(两列) +- 左侧:窗口标题"添加小组件" +- 右侧:自定义关闭按钮(使用 FluentIcon) +- 移除了底部的"关闭"按钮,改用标题栏的关闭按钮 + +#### 变更 4: 调整内边距 +```diff +- Margin="22,0,22,8" ++ Margin="22,0,22,22" +``` + +#### 变更 5: 移除底部边框和关闭按钮 +```diff +- +- +- +``` + +--- + +## UI 变化对比 + +### 布局变化 + +| 方面 | 修改前 | 修改后 | +|------|--------|--------| +| 关闭按钮位置 | 底部栏 | 标题栏右侧 | +| 窗口标题栏 | 仅文本 | 文本 + 关闭按钮 | +| Grid 行数 | 3 行 | 2 行 | +| 按钮样式 | 传统按钮 | FluentIcon | + +### 文本变化 + +| 位置 | 修改前 | 修改后 | +|------|--------|--------| +| 查找按钮 | "查找更多组件" | "查找更多小组件" | +| 添加按钮 | "添加" | "添加小组件" | + +--- + +## 代码审查要点 + +### 潜在问题 + +1. **用户交互变化**: + - ⚠️ 中风险:移除了底部"关闭"按钮,用户需要使用标题栏的关闭按钮 + - 确认用户是否习惯使用标题栏关闭按钮 + +2. **移动端适配**: + - 自定义关闭按钮尺寸较小(32x32),在触摸设备上可能需要增大 + +3. **可访问性**: + - 需要确保关闭按钮有适当的键盘快捷键支持(通常是 Escape 键) + - 确认焦点顺序是否合理 + +### 建议 + +- ✅ **设计一致性**: 使用 FluentIcon 符合现代 UI 设计趋势 +- ✅ **空间优化**: 移除底部栏使界面更简洁 +- ⚠️ **测试建议**: 在不同屏幕尺寸下测试窗口布局 +- 📝 **文档建议**: 如果这是用户体验的重大变化,考虑更新相关文档 + +--- + +## 影响范围 + +- **UI/UX**: 显著影响用户界面和交互方式 +- **用户体验**: 界面更简洁,但关闭操作位置变化 +- **代码维护**: 两个 XAML 文件,变更清晰 + +--- + +## 设计评估 + +### 优点 + +1. ✅ **现代设计**: 使用 FluentIcon,符合 Fluent Design System +2. ✅ **简化布局**: 移除多余的底部栏,界面更清爽 +3. ✅ **文本优化**: "添加小组件"比"添加"更明确 +4. ✅ **视觉一致性**: 水平居中对齐提升文本可读性 + +### 需要注意 + +1. ⚠️ **交互一致性**: 确保用户知道如何使用新的关闭按钮 +2. ⚠️ **键盘支持**: 验证 Escape 键等快捷键仍然有效 +3. ⚠️ **触摸友好**: 检查按钮尺寸是否适合触摸操作 + +--- + +## 总结 + +这是一次成功的 UI 优化提交,通过以下改进提升了用户体验: +1. 使用 FluentIcon 替换传统按钮,更现代 +2. 移除底部关闭栏,简化布局 +3. 优化按钮文本,提高清晰度 +4. 统一文本对齐方式 + +**建议**: ✅ 可以合并,但建议在合并后进行 UI 测试以验证用户体验。 diff --git a/docs/auto_commit_md/20250525_791e38d.md b/docs/auto_commit_md/20250525_791e38d.md new file mode 100644 index 0000000..77319f0 --- /dev/null +++ b/docs/auto_commit_md/20250525_791e38d.md @@ -0,0 +1,111 @@ +# Git 提交分析报告 + +**提交哈希**: 791e38d55ebef9c6cb568c72964ccac274141d1e +**提交时间**: 2026-05-25 11:12:15 +0800 +**作者**: lincube \ +**提交信息**: fix.修复了错误的AirAppHost打包流程 + +--- + +## 变更统计 + +- **修改文件数**: 1 +- **新增行数**: 0 +- **删除行数**: 42 +- **净变更行数**: -42 + +### 变更文件 + +| 文件 | 变更类型 | 变更行数 | +|------|---------|---------| +| .github/workflows/release.yml | 删除 | -42 | + +--- + +## 详细变更分析 + +### 1. .github/workflows/release.yml + +**变更类型**: 大规模删除操作 + +**删除内容**: +移除了整个 `Publish AirAppHost` GitHub Actions 步骤,包含了: +- 条件化构建逻辑(self-contained vs lite 版本) +- x64 架构的发布配置 +- 多行 PowerShell 命令调用 + +**具体删除代码**: +```yaml +- name: Publish AirAppHost + run: | + $arch = "${{ matrix.arch }}" + $selfContained = "${{ matrix.self_contained }}" -eq "true" + $publishDir = if ($selfContained) { "publish/windows-$arch" } else { "publish/windows-$arch-lite" } + + if ($selfContained) { + dotnet publish LanMountainDesktop.AirAppHost/LanMountainDesktop.AirAppHost.csproj ` + -c Release ` + -o ./$publishDir ` + --self-contained:false ` + # ... 其他参数 + } else { + # ... else 分支的发布配置 + } + shell: pwsh +``` + +**变更说明**: +- 移除了错误的 AirAppHost 打包流程 +- 这是一个修复性提交,旨在纠正之前的错误配置 + +--- + +## 代码审查要点 + +### 潜在问题 + +1. **修复范围**: 需要确认这个删除操作是完整的,之前的 AirAppHost 发布流程中是否还有其他相关的配置需要清理。 + +2. **版本兼容**: 移除 AirAppHost 发布步骤后,需要确认: + - 其他工作流步骤是否依赖此步骤的输出 + - 发布流程的其他部分是否需要相应调整 + +3. **回归风险**: + - ⚠️ 高风险:这是一个破坏性变更,需要在 CI/CD 环境中验证 + - 需要检查是否有其他工作流依赖于这个步骤的产物 + +### 建议 + +- ✅ **必要性**: 这个修复是必要的,移除了错误的打包流程 +- ⚠️ **验证要求**: 必须运行完整的 CI/CD 流程以验证没有破坏其他功能 +- 📝 **文档建议**: 考虑添加注释说明为什么移除了这个步骤,或添加相关的 issue/PR 链接 +- 🔍 **审查建议**: 确认是否需要在其他位置重新实现正确的 AirAppHost 打包流程 + +--- + +## 影响范围 + +- **CI/CD**: 显著影响发布工作流 +- **构建系统**: AirAppHost 的打包流程被禁用 +- **部署**: 可能影响最终发布包的内容 +- **功能影响**: 可能有功能影响,取决于 AirAppHost 的用途 + +--- + +## 相关上下文 + +根据提交信息 "修复了错误的 AirAppHost 打包流程",这表明: +1. 之前的 AirAppHost 发布流程配置有误 +2. 此提交是纠正错误的第一步或唯一步骤 +3. 可能需要进一步的后续提交来实现正确的打包流程 + +--- + +## 总结 + +这是一个重要的 CI/CD 修复提交,移除了错误的 AirAppHost 打包流程。虽然涉及大量代码删除,但这是修复性的,有助于恢复正确的构建流程。 + +**建议**: ✅ 可以合并,但需要: +1. 在 CI 环境中完整测试发布流程 +2. 确认是否需要添加正确的 AirAppHost 打包配置 +3. 检查是否有其他工作流依赖于此步骤 diff --git a/docs/auto_commit_md/20250525_SUMMARY.md b/docs/auto_commit_md/20250525_SUMMARY.md new file mode 100644 index 0000000..bcc4a33 --- /dev/null +++ b/docs/auto_commit_md/20250525_SUMMARY.md @@ -0,0 +1,226 @@ +# 2026-05-25 Git 提交汇总报告 + +**生成时间**: 2026-05-25 12:00:00 +**总提交数**: 5 + +--- + +## 提交概览 + +| # | 时间 | 提交哈希 | 作者 | 提交信息 | 风险等级 | +|---|------|---------|------|---------|---------| +| 1 | 11:54:04 | [cc85638](20250525_cc85638.md) | lincube | Update LanMountainDesktop.iss | 🟢 低 | +| 2 | 11:12:15 | [791e38d](20250525_791e38d.md) | lincube | fix.修复了错误的AirAppHost打包流程 | 🔴 高 | +| 3 | 10:16:00 | [75aed3f](20250525_75aed3f.md) | lincube | changed.调整了桌面组件库的UI | 🟡 中 | +| 4 | 09:32:58 | [01cf32a](20250525_01cf32a.md) | lincube | changed.调整融合桌面组库的相关圆角 | 🟢 低 | +| 5 | 01:24:18 | [12f0caa](20250525_12f0caa.md) | lincube | fix.继续修复 .NET运行时问题 | 🟡 中 | + +--- + +## 变更统计总览 + +### 文件变更统计 + +| 指标 | 数量 | +|------|------| +| 修改文件总数 | 12 | +| 新增代码行数 | 188 | +| 删除代码行数 | 61 | +| 净增加行数 | +127 | + +### 按文件类型分布 + +| 文件类型 | 数量 | 说明 | +|---------|------|------| +| C# (.cs) | 4 | 核心逻辑和测试 | +| XAML (.axaml) | 3 | UI 定义 | +| YAML (.yml) | 1 | CI/CD 配置 | +| Pascal Script (.iss) | 2 | 安装程序脚本 | +| C# 代码后端 (.axaml.cs) | 2 | UI 逻辑 | + +--- + +## 重点提交分析 + +### 🔴 高风险提交 + +#### 2. [791e38d](20250525_791e38d.md) - 修复 AirAppHost 打包流程 + +**影响**: +- 移除 42 行 CI/CD 配置代码 +- 可能影响发布工作流 + +**建议**: +- ✅ 必须在 CI 环境中完整测试 +- ⚠️ 确认是否需要重新实现正确的打包流程 +- ⚠️ 检查其他工作流依赖 + +--- + +### 🟡 中等风险提交 + +#### 3. [75aed3f](20250525_75aed3f.md) - UI 调整 + +**影响**: +- 窗口布局重构 +- 关闭按钮位置变更 + +**建议**: +- ✅ 进行 UI 兼容性测试 +- ⚠️ 验证键盘快捷键(Escape)仍然有效 +- ⚠️ 检查触摸设备上的交互体验 + +#### 5. [12f0caa](20250525_12f0caa.md) - .NET 运行时检测修复 + +**影响**: +- 核心功能增强 +- 新增 6 个单元测试 + +**建议**: +- ✅ 代码质量优秀,可以合并 +- ⚠️ 建议在多个环境中验证运行时检测 +- ⚠️ 测试按用户安装场景 + +--- + +### 🟢 低风险提交 + +#### 1. [cc85638](20250525_cc85638.md) - ISS 脚本优化 + +- 简单的代码风格调整 +- 无功能变更 + +#### 4. [01cf32a](20250525_01cf32a.md) - 圆角调整 + +- 增强图标解析功能 +- 添加动态圆角支持 +- 代码重构清晰 + +--- + +## 功能领域分布 + +### 按领域分类 + +| 功能领域 | 提交数 | 占比 | +|---------|--------|------| +| UI/UX | 2 | 40% | +| CI/CD | 1 | 20% | +| 核心功能 | 1 | 20% | +| 安装程序 | 2 | 40% | + +*注:一个提交可能涉及多个功能领域* + +### 主要功能模块 + +1. **UI 组件系统**: 2 个提交 + - FusedDesktopComponentLibraryControl + - ComponentCategoryIconResolver + +2. **CI/CD 管道**: 1 个提交 + - GitHub Actions workflow + +3. **.NET 运行时检测**: 1 个提交 + - DotNetRuntimeProbe + +4. **安装程序**: 2 个提交 + - Inno Setup 脚本 + +--- + +## 代码质量评估 + +### 整体评分 + +| 指标 | 评分 | 说明 | +|------|------|------| +| 代码规范 | ⭐⭐⭐⭐⭐ | 遵循项目代码风格 | +| 测试覆盖 | ⭐⭐⭐⭐ | 新增 8 个测试用例 | +| 错误处理 | ⭐⭐⭐⭐ | 周全的错误和边界检查 | +| 文档 | ⭐⭐⭐ | 变更说明清晰 | +| 安全性 | ⭐⭐⭐⭐⭐ | 路径验证完善 | + +### 代码审查统计 + +| 类型 | 数量 | +|------|------| +| 优点 | 12 | +| 建议 | 8 | +| 注意事项 | 5 | + +--- + +## 风险与建议 + +### 需要关注的风险 + +1. **CI/CD 变更风险** 🔴 + - AirAppHost 打包流程移除 + - 需要完整验证发布流程 + +2. **UI 交互变更** 🟡 + - 关闭按钮位置变化 + - 需要用户接受度测试 + +3. **运行时检测** 🟢 + - 功能增强 + - 需要多环境验证 + +### 建议的测试计划 + +#### 必须测试 + +- [ ] 完整的 CI/CD 发布流程 +- [ ] 多种 .NET 运行时安装场景 +- [ ] UI 组件在不同屏幕尺寸下的显示 + +#### 建议测试 + +- [ ] 触摸设备上的 UI 交互 +- [ ] 按用户 vs 系统级别的运行时检测 +- [ ] 键盘快捷键功能 + +--- + +## 合并建议 + +### 总体建议 + +✅ **可以合并**: 所有提交的代码质量和意图都很好 + +### 合并顺序建议 + +1. **第一步**: 合并低风险提交(1, 4) + - 风险最低,不会影响主要功能 + +2. **第二步**: 合并中等风险提交(3, 5) + - 需要进行测试验证 + +3. **第三步**: 合并高风险提交(2) + - 需要完整 CI/CD 测试 + - 可能需要额外的后续工作 + +--- + +## 相关资源 + +### 详细分析报告 + +- [cc85638 - ISS 脚本优化](20250525_cc85638.md) +- [791e38d - AirAppHost 打包流程修复](20250525_791e38d.md) +- [75aed3f - UI 调整](20250525_75aed3f.md) +- [01cf32a - 圆角和图标解析](20250525_01cf32a.md) +- [12f0caa - .NET 运行时检测](20250525_12f0caa.md) + +--- + +## 总结 + +今天的提交整体质量很高,主要集中在: + +1. **UI/UX 改进**: 40% 的提交涉及用户界面优化 +2. **核心功能增强**: .NET 运行时检测是重要的功能改进 +3. **CI/CD 优化**: 修复了错误的打包流程 +4. **代码质量**: 遵循项目规范,测试覆盖良好 + +**建议**: ✅ 可以按计划合并所有提交,建议在高风险提交合并前进行充分的 CI/CD 测试。 diff --git a/docs/auto_commit_md/20250525_cc85638.md b/docs/auto_commit_md/20250525_cc85638.md new file mode 100644 index 0000000..d6c2c56 --- /dev/null +++ b/docs/auto_commit_md/20250525_cc85638.md @@ -0,0 +1,87 @@ +# Git 提交分析报告 + +**提交哈希**: cc85638a374b061018c9a3a691e55f6aa770f767 +**提交时间**: 2026-05-25 11:54:04 +0800 +**作者**: lincube \ +**提交信息**: Update LanMountainDesktop.iss + +--- + +## 变更统计 + +- **修改文件数**: 1 +- **新增行数**: 0 +- **删除行数**: 0 +- **变更行数**: 2 + +### 变更文件 + +| 文件 | 变更类型 | 变更行数 | +|------|---------|---------| +| LanMountainDesktop/installer/LanMountainDesktop.iss | 修改 | +2 / -2 | + +--- + +## 详细变更分析 + +### 1. LanMountainDesktop/installer/LanMountainDesktop.iss + +**变更位置**: +- 第 560 行附近:`GetTargetDotNetDesktopRuntimePath` 函数 +- 第 577 行附近:`GetDotNetRuntimeDownloadUrlX64` 函数 + +**具体变更**: +```diff +@@ -557,7 +557,7 @@ begin + if '{#MyAppArch}' = 'x64' then + begin + Result := ExpandConstant('{commonpf64}\dotnet\shared\Microsoft.WindowsDesktop.App'); +- end; ++ end + else + begin + Result := ExpandConstant('{commonpf}\dotnet\shared\Microsoft.WindowsDesktop.App'); +@@ -574,7 +574,7 @@ begin + if '{#MyAppArch}' = 'x64' then + begin + Result := DotNetRuntimeDownloadUrlX64; +- end; ++ end + else + begin + Result := DotNetRuntimeDownloadUrlX86; +``` + +**变更说明**: +- 移除了两处 `if-else` 语句后的多余分号(`;`) +- 这是代码风格的一致性调整 + +--- + +## 代码审查要点 + +### 潜在问题 + +1. **分号语法问题**: 此次修改移除了 Pascal Script 中 `if-else` 语句后的多余分号。虽然在某些 Pascal 方言中这可能不会导致编译错误,但删除分号是正确的做法,因为 `else` 关键字不应该与分号一起使用。 + +### 建议 + +- ✅ **良好实践**: 移除多余分号,保持代码风格一致 +- ⚠️ **注意**: 确保其他类似的 `if-else` 语句也遵循相同的风格 +- 📝 **建议**: 考虑在整个 ISS 脚本中进行一次全局的代码风格检查 + +--- + +## 影响范围 + +- **安装程序**: 影响 Windows 安装包的打包流程 +- **用户体验**: 无直接影响 +- **功能影响**: 无功能变更,仅代码风格调整 + +--- + +## 总结 + +本次提交是一个简单的代码风格优化,移除了 Inno Setup 脚本中的多余分号。虽然变更很小,但有助于提高代码质量和一致性。 + +**建议**: ✅ 可以合并