diff --git a/Ink Canvas/Windows/FeedbackPages/FeedbackPage1.xaml b/Ink Canvas/Windows/FeedbackPages/FeedbackPage1.xaml
new file mode 100644
index 00000000..429c8fe9
--- /dev/null
+++ b/Ink Canvas/Windows/FeedbackPages/FeedbackPage1.xaml
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ink Canvas/Windows/FeedbackPages/FeedbackPage1.xaml.cs b/Ink Canvas/Windows/FeedbackPages/FeedbackPage1.xaml.cs
new file mode 100644
index 00000000..eb57c9a0
--- /dev/null
+++ b/Ink Canvas/Windows/FeedbackPages/FeedbackPage1.xaml.cs
@@ -0,0 +1,24 @@
+using System.Windows;
+using System.Windows.Controls;
+
+namespace Ink_Canvas.Windows.FeedbackPages
+{
+ ///
+ /// 反馈页面1:环境信息选择页面。
+ /// 允许用户选择要包含在反馈中的系统环境信息。
+ ///
+ ///
+ /// 用户可以选择包含以下信息:
+ /// - 软件版本和更新通道
+ /// - 操作系统版本、.NET版本和触控支持
+ /// - 设备ID和遥测ID
+ /// - PPT联动设置和墨迹识别设置
+ ///
+ public partial class FeedbackPage1 : UserControl
+ {
+ public FeedbackPage1()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Ink Canvas/Windows/FeedbackPages/FeedbackPage2.xaml b/Ink Canvas/Windows/FeedbackPages/FeedbackPage2.xaml
new file mode 100644
index 00000000..44175f64
--- /dev/null
+++ b/Ink Canvas/Windows/FeedbackPages/FeedbackPage2.xaml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ink Canvas/Windows/FeedbackPages/FeedbackPage2.xaml.cs b/Ink Canvas/Windows/FeedbackPages/FeedbackPage2.xaml.cs
new file mode 100644
index 00000000..1c14a3bf
--- /dev/null
+++ b/Ink Canvas/Windows/FeedbackPages/FeedbackPage2.xaml.cs
@@ -0,0 +1,24 @@
+using System.Windows;
+using System.Windows.Controls;
+
+namespace Ink_Canvas.Windows.FeedbackPages
+{
+ ///
+ /// 反馈页面2:环境信息预览页面。
+ /// 展示用户选择要包含在反馈中的系统环境信息。
+ ///
+ ///
+ /// 显示以下信息:
+ /// - 软件版本信息
+ /// - 系统信息(操作系统、.NET版本、触控支持)
+ /// - 设备信息(设备ID、遥测ID)
+ /// - 软件配置信息(PPT联动设置、墨迹识别设置)
+ ///
+ public partial class FeedbackPage2 : UserControl
+ {
+ public FeedbackPage2()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Ink Canvas/Windows/FeedbackPages/FeedbackPage3.xaml b/Ink Canvas/Windows/FeedbackPages/FeedbackPage3.xaml
new file mode 100644
index 00000000..5b9530d0
--- /dev/null
+++ b/Ink Canvas/Windows/FeedbackPages/FeedbackPage3.xaml
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ink Canvas/Windows/FeedbackPages/FeedbackPage3.xaml.cs b/Ink Canvas/Windows/FeedbackPages/FeedbackPage3.xaml.cs
new file mode 100644
index 00000000..ce1bc8b1
--- /dev/null
+++ b/Ink Canvas/Windows/FeedbackPages/FeedbackPage3.xaml.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace Ink_Canvas.Windows.FeedbackPages
+{
+ ///
+ /// 反馈页面3:反馈提交页面。
+ /// 提供Markdown模板并允许用户复制或直接打开GitHub Issue页面。
+ ///
+ ///
+ /// 页面提供以下功能:
+ /// - 显示生成的Markdown格式环境信息模板
+ /// - 复制Markdown模板到剪贴板
+ /// - 复制预填的GitHub Issue URL到剪贴板
+ /// - 直接在浏览器中打开GitHub Issue创建页面
+ ///
+ public partial class FeedbackPage3 : UserControl
+ {
+ public event EventHandler BtnOpenGitHubIssueClick;
+ public event EventHandler CardCopyIssueUrlClick;
+ public event EventHandler BtnCopyMarkdownClick;
+
+ public string MarkdownTemplate => TextBoxMarkdownTemplate.Text;
+
+ public FeedbackPage3()
+ {
+ InitializeComponent();
+ BtnOpenGitHubIssue.Click += (s, e) => BtnOpenGitHubIssueClick?.Invoke(this, e);
+ CardCopyIssueUrl.Click += (s, e) => CardCopyIssueUrlClick?.Invoke(this, e);
+ BtnCopyMarkdown.Click += (s, e) => BtnCopyMarkdownClick?.Invoke(this, e);
+ }
+ }
+}
diff --git a/Ink Canvas/Windows/FeedbackWindow.xaml b/Ink Canvas/Windows/FeedbackWindow.xaml
new file mode 100644
index 00000000..67c6ba52
--- /dev/null
+++ b/Ink Canvas/Windows/FeedbackWindow.xaml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ink Canvas/Windows/FeedbackWindow.xaml.cs b/Ink Canvas/Windows/FeedbackWindow.xaml.cs
new file mode 100644
index 00000000..a6cbf95e
--- /dev/null
+++ b/Ink Canvas/Windows/FeedbackWindow.xaml.cs
@@ -0,0 +1,752 @@
+using Ink_Canvas.Helpers;
+using Ink_Canvas.Windows.FeedbackPages;
+using iNKORE.UI.WPF.Modern.Media.Animation;
+using OSVersionExtension;
+using System;
+using System.Diagnostics;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Windows;
+
+namespace Ink_Canvas
+{
+ ///
+ /// 反馈窗口,提供用户反馈和问题报告功能。
+ /// 收集系统环境信息并生成GitHub Issue的Markdown模板。
+ ///
+ ///
+ /// 窗口包含三个页面:
+ /// - FeedbackPage1: 选择要包含的环境信息
+ /// - FeedbackPage2: 预览收集的环境信息
+ /// - FeedbackPage3: 生成并复制Markdown模板或打开GitHub Issue
+ ///
+ public partial class FeedbackWindow : Window
+ {
+ private string _appVersion = "";
+ private string _updateChannel = "";
+ private string _osVersion = "";
+ private string _netVersion = "";
+ private string _touchSupport = "";
+ private string _deviceId = "";
+ private string _telemetryId = "";
+ private string _pptLinkageSettings = "";
+ private string _inkRecognitionSettings = "";
+ private string _inkRecognitionEngine = "";
+
+ private FeedbackPage1 _page1;
+ private FeedbackPage2 _page2;
+ private FeedbackPage3 _page3;
+
+ private NavigationTransitionInfo _transitionInfo = new SlideNavigationTransitionInfo() { Effect = SlideNavigationTransitionEffect.FromRight };
+
+ ///
+ /// 构造函数,初始化反馈窗口并加载系统信息。
+ ///
+ ///
+ /// 初始化操作包括:
+ /// 1. 初始化UI组件
+ /// 2. 创建三个反馈页面实例
+ /// 3. 绑定页面3的事件处理器
+ /// 4. 加载系统环境信息(版本、系统、触控等)
+ /// 5. 检查遥测ID可用性
+ /// 6. 导航到第一页
+ ///
+ public FeedbackWindow()
+ {
+ InitializeComponent();
+ _page1 = new FeedbackPage1();
+ _page2 = new FeedbackPage2();
+ _page3 = new FeedbackPage3();
+
+ _page3.BtnOpenGitHubIssueClick += BtnOpenGitHubIssue_Click;
+ _page3.CardCopyIssueUrlClick += CardCopyIssueUrl_Click;
+ _page3.BtnCopyMarkdownClick += BtnCopyMarkdown_Click;
+
+ ContentFrame.Navigated += ContentFrame_Navigated;
+ LoadInformation();
+ CheckTelemetryIdAvailability();
+ ContentFrame.Navigate(_page1);
+ }
+
+ ///
+ /// 内容框架导航事件处理器,用于更新按钮可见性。
+ ///
+ /// 事件发送者
+ /// 导航事件参数
+ private void ContentFrame_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
+ {
+ UpdateButtonVisibility();
+ }
+
+ ///
+ /// 加载系统环境信息,包括软件版本、系统信息、设备信息等。
+ ///
+ ///
+ /// 收集的信息包括:
+ /// - 软件版本和更新通道
+ /// - 操作系统版本和.NET版本
+ /// - 触控支持情况和触摸设备数量
+ /// - 设备ID
+ /// - 遥测ID
+ /// - PPT联动设置
+ /// - 墨迹识别设置和识别引擎
+ ///
+ private void LoadInformation()
+ {
+ try
+ {
+ var assemblyVersion = Assembly.GetExecutingAssembly().GetName().Version;
+ _appVersion = $"v{assemblyVersion}";
+ }
+ catch (Exception ex)
+ {
+ _appVersion = "未知";
+ System.Diagnostics.Debug.WriteLine($"获取软件版本失败: {ex.Message}");
+ }
+
+ try
+ {
+ if (MainWindow.Settings?.Startup != null)
+ {
+ _updateChannel = MainWindow.Settings.Startup.UpdateChannel.ToString();
+ }
+ }
+ catch (Exception ex)
+ {
+ _updateChannel = "未知";
+ System.Diagnostics.Debug.WriteLine($"获取更新通道失败: {ex.Message}");
+ }
+
+ try
+ {
+ _osVersion = $"{OSVersion.GetOperatingSystem()} {OSVersion.GetOSVersion().Version}";
+ }
+ catch (Exception ex)
+ {
+ _osVersion = "未知";
+ System.Diagnostics.Debug.WriteLine($"获取系统版本失败: {ex.Message}");
+ }
+
+ try
+ {
+ _netVersion = RuntimeInformation.FrameworkDescription;
+ }
+ catch (Exception ex)
+ {
+ _netVersion = "未知";
+ System.Diagnostics.Debug.WriteLine($"获取.NET版本失败: {ex.Message}");
+ }
+
+ try
+ {
+ var support = Ink_Canvas.Windows.SettingsViews.AboutPanel.TouchTabletDetectHelper.IsTouchEnabled();
+ var touchcount = Ink_Canvas.Windows.SettingsViews.AboutPanel.TouchTabletDetectHelper.GetTouchTabletDevices().Count;
+ if (support)
+ {
+ if (touchcount > 0)
+ {
+ _touchSupport = $"支持({touchcount}个设备)";
+ }
+ else
+ {
+ _touchSupport = "支持";
+ }
+ }
+ else
+ {
+ _touchSupport = "不支持";
+ }
+ }
+ catch (Exception ex)
+ {
+ _touchSupport = "未知";
+ System.Diagnostics.Debug.WriteLine($"获取触控支持失败: {ex.Message}");
+ }
+
+ try
+ {
+ _deviceId = DeviceIdentifier.GetDeviceId();
+ }
+ catch (Exception ex)
+ {
+ _deviceId = "获取失败";
+ System.Diagnostics.Debug.WriteLine($"获取设备ID失败: {ex.Message}");
+ }
+
+ try
+ {
+ _telemetryId = GetTelemetryId();
+ }
+ catch (Exception ex)
+ {
+ _telemetryId = "获取失败";
+ System.Diagnostics.Debug.WriteLine($"获取遥测ID失败: {ex.Message}");
+ }
+
+ try
+ {
+ if (MainWindow.Settings?.PowerPointSettings != null)
+ {
+ _pptLinkageSettings = $"启用PPT联动: {MainWindow.Settings.PowerPointSettings.PowerPointSupport}\n";
+ _pptLinkageSettings += $"WPS支持: {MainWindow.Settings.PowerPointSettings.IsSupportWPS}\n";
+ _pptLinkageSettings += $"MSO支持: {MainWindow.Settings.PowerPointSettings.PowerPointSupport}\n";
+ _pptLinkageSettings += $"Rot联动: {MainWindow.Settings.PowerPointSettings.UseRotPptLink}\n";
+ }
+ else
+ {
+ _pptLinkageSettings = "未配置PPT联动设置";
+ }
+ }
+ catch (Exception ex)
+ {
+ _pptLinkageSettings = "获取PPT联动设置失败";
+ System.Diagnostics.Debug.WriteLine($"获取PPT联动设置失败: {ex.Message}");
+ }
+
+ try
+ {
+ if (MainWindow.Settings?.InkToShape != null)
+ {
+ _inkRecognitionSettings = $"启用墨迹识别: {MainWindow.Settings.InkToShape.IsInkToShapeEnabled}\n";
+ }
+ else
+ {
+ _inkRecognitionSettings = "未配置墨迹识别设置";
+ }
+ }
+ catch (Exception ex)
+ {
+ _inkRecognitionSettings = "获取墨迹识别设置失败";
+ System.Diagnostics.Debug.WriteLine($"获取墨迹识别设置失败: {ex.Message}");
+ }
+
+ try
+ {
+ if (MainWindow.Settings?.InkToShape != null)
+ {
+ var engineMode = Helpers.ShapeRecognitionRouter.FromSettingsInt(MainWindow.Settings.InkToShape.ShapeRecognitionEngine);
+ bool useWinRT = Helpers.ShapeRecognitionRouter.ResolveUseWinRt(engineMode);
+ _inkRecognitionEngine = useWinRT ? "WinRT" : "IACore";
+ _inkRecognitionSettings += $"识别引擎: {_inkRecognitionEngine}\n";
+ }
+ else
+ {
+ _inkRecognitionEngine = "未配置";
+ _inkRecognitionSettings += $"识别引擎: {_inkRecognitionEngine}\n";
+ }
+ }
+ catch (Exception ex)
+ {
+ _inkRecognitionEngine = "获取失败";
+ _inkRecognitionSettings += $"识别引擎: {_inkRecognitionEngine}\n";
+ System.Diagnostics.Debug.WriteLine($"获取墨迹识别引擎失败: {ex.Message}");
+ }
+ }
+
+ ///
+ /// 获取存储在文件中的遥测ID。
+ ///
+ /// 遥测ID字符串,如果不存在则返回空字符串
+ private string GetTelemetryId()
+ {
+ try
+ {
+ var telemetryIdFilePath = System.IO.Path.Combine(App.RootPath, "telemetry_id.dat");
+ if (System.IO.File.Exists(telemetryIdFilePath))
+ {
+ return System.IO.File.ReadAllText(telemetryIdFilePath).Trim();
+ }
+ return "";
+ }
+ catch
+ {
+ return "";
+ }
+ }
+
+ ///
+ /// 检查遥测ID是否可用,如果不可用则禁用相关复选框。
+ ///
+ ///
+ /// 检查telemetry_id.dat文件是否存在,如果不存在则禁用"包含遥测ID"选项
+ ///
+ private void CheckTelemetryIdAvailability()
+ {
+ try
+ {
+ bool hasTelemetryId = CheckTelemetryIdExists();
+ if (!hasTelemetryId)
+ {
+ _page1.CheckFanceId.IsChecked = false;
+ _page1.CheckFanceId.IsEnabled = false;
+ }
+ }
+ catch (Exception ex)
+ {
+ System.Diagnostics.Debug.WriteLine($"检查遥测ID可用性失败: {ex.Message}");
+ _page1.CheckFanceId.IsChecked = false;
+ _page1.CheckFanceId.IsEnabled = false;
+ }
+ }
+
+ ///
+ /// 检查遥测ID文件是否存在。
+ ///
+ /// 如果遥测ID文件存在返回true,否则返回false
+ private bool CheckTelemetryIdExists()
+ {
+ try
+ {
+ var telemetryIdFilePath = System.IO.Path.Combine(App.RootPath, "telemetry_id.dat");
+ return System.IO.File.Exists(telemetryIdFilePath);
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ ///
+ /// 取消按钮点击事件处理器,关闭反馈窗口。
+ ///
+ /// 事件发送者
+ /// 路由事件参数
+ private void ButtonCancel_Click(object sender, RoutedEventArgs e)
+ {
+ Close();
+ }
+
+ ///
+ /// 返回按钮点击事件处理器,返回上一页面。
+ ///
+ /// 事件发送者
+ /// 路由事件参数
+ private void ButtonBack_Click(object sender, RoutedEventArgs e)
+ {
+ if (ContentFrame.BackStackDepth > 0)
+ {
+ ContentFrame.GoBack();
+ UpdateButtonVisibility();
+ }
+ }
+
+ ///
+ /// 下一步按钮点击事件处理器,导航到第二页并更新页面信息。
+ ///
+ /// 事件发送者
+ /// 路由事件参数
+ private void ButtonNext_Click(object sender, RoutedEventArgs e)
+ {
+ UpdatePage2Info();
+ ContentFrame.Navigate(_page2, null, _transitionInfo);
+ UpdateButtonVisibility();
+ }
+
+ ///
+ /// 确认按钮点击事件处理器,生成Markdown模板并导航到第三页。
+ ///
+ /// 事件发送者
+ /// 路由事件参数
+ private void ButtonConfirm_Click(object sender, RoutedEventArgs e)
+ {
+ GenerateMarkdownTemplate();
+ ContentFrame.Navigate(_page3, null, _transitionInfo);
+ UpdateButtonVisibility();
+ }
+
+ ///
+ /// 根据当前页面更新按钮的可见性。
+ ///
+ ///
+ /// - 第一页:显示"取消"和"下一步"按钮
+ /// - 第二页:显示"返回"和"确认"按钮
+ /// - 第三页:显示"返回"按钮
+ ///
+ private void UpdateButtonVisibility()
+ {
+ if (ContentFrame.Content == _page1)
+ {
+ ButtonCancel.Visibility = Visibility.Visible;
+ ButtonNext.Visibility = Visibility.Visible;
+ ButtonBack.Visibility = Visibility.Collapsed;
+ ButtonConfirm.Visibility = Visibility.Collapsed;
+ }
+ else if (ContentFrame.Content == _page2)
+ {
+ ButtonCancel.Visibility = Visibility.Collapsed;
+ ButtonNext.Visibility = Visibility.Collapsed;
+ ButtonBack.Visibility = Visibility.Visible;
+ ButtonConfirm.Visibility = Visibility.Visible;
+ }
+ else if (ContentFrame.Content == _page3)
+ {
+ ButtonCancel.Visibility = Visibility.Collapsed;
+ ButtonNext.Visibility = Visibility.Collapsed;
+ ButtonBack.Visibility = Visibility.Visible;
+ ButtonConfirm.Visibility = Visibility.Collapsed;
+ }
+ }
+
+ ///
+ /// 更新第二页的显示信息,将用户选择的环境信息展示在页面上。
+ ///
+ ///
+ /// 根据第一页用户的复选框选择情况,更新以下信息:
+ /// - 软件版本信息
+ /// - 系统信息(操作系统、.NET版本、触控支持)
+ /// - 设备ID
+ /// - 遥测ID
+ /// - 软件配置信息(PPT联动设置、墨迹识别设置)
+ ///
+ private void UpdatePage2Info()
+ {
+ try
+ {
+ string versionInfo = "";
+ string systemInfo = "";
+
+ if (_page1.CheckAppVersion.IsChecked == true || _page1.CheckUpdateChannel.IsChecked == true)
+ {
+ if (_page1.CheckAppVersion.IsChecked == true)
+ {
+ versionInfo += _appVersion;
+ }
+ if (_page1.CheckUpdateChannel.IsChecked == true)
+ {
+ if (!string.IsNullOrEmpty(versionInfo))
+ {
+ versionInfo += " ";
+ }
+ versionInfo += $"({_updateChannel})";
+ }
+ }
+
+ if (_page1.CheckOSVersion.IsChecked == true || _page1.CheckNetVersion.IsChecked == true || _page1.CheckTouchSupport.IsChecked == true)
+ {
+ if (_page1.CheckOSVersion.IsChecked == true)
+ {
+ systemInfo += _osVersion;
+ }
+ if (_page1.CheckNetVersion.IsChecked == true)
+ {
+ if (!string.IsNullOrEmpty(systemInfo))
+ {
+ systemInfo += " | ";
+ }
+ systemInfo += _netVersion;
+ }
+ if (_page1.CheckTouchSupport.IsChecked == true)
+ {
+ if (!string.IsNullOrEmpty(systemInfo))
+ {
+ systemInfo += " | ";
+ }
+ systemInfo += $"触控:{_touchSupport}";
+ }
+ }
+
+ _page2.TextAppVersionInfo.Text = versionInfo;
+ _page2.TextSystemInfo.Text = systemInfo;
+
+ if (_page1.CheckDeviceId.IsChecked == true)
+ {
+ _page2.TextDeviceInfo.Text = $"设备ID: {_deviceId}";
+ }
+ else
+ {
+ _page2.TextDeviceInfo.Text = "设备ID: (不包含)";
+ }
+
+ if (_page1.CheckFanceId.IsChecked == true)
+ {
+ _page2.TextTelemetryInfo.Text = $"遥测ID: {_telemetryId}";
+ _page2.TextTelemetryInfo.Visibility = Visibility.Visible;
+ }
+ else
+ {
+ _page2.TextTelemetryInfo.Text = "遥测ID: (不包含)";
+ _page2.TextTelemetryInfo.Visibility = Visibility.Visible;
+ }
+
+ if (_page1.CheckPPTLinkage.IsChecked == true || _page1.CheckInkRecognition.IsChecked == true)
+ {
+ _page2.CardConfiguration.Visibility = Visibility.Visible;
+ _page2.TextConfigurationInfo.Text = "";
+ if (_page1.CheckPPTLinkage.IsChecked == true)
+ {
+ _page2.TextConfigurationInfo.Text += $"PPT联动设置:\n{_pptLinkageSettings.TrimEnd('\n', '\r')}";
+ }
+ if (_page1.CheckInkRecognition.IsChecked == true)
+ {
+ if (_page1.CheckPPTLinkage.IsChecked == true) _page2.TextConfigurationInfo.Text += "\n";
+ _page2.TextConfigurationInfo.Text += $"墨迹识别设置:\n{_inkRecognitionSettings.TrimEnd('\n', '\r')}";
+ }
+ }
+ else
+ {
+ _page2.CardConfiguration.Visibility = Visibility.Collapsed;
+ }
+ }
+ catch (Exception ex)
+ {
+ System.Diagnostics.Debug.WriteLine($"更新第二页信息失败: {ex.Message}");
+ }
+ }
+
+ ///
+ /// 生成Markdown格式的反馈信息模板,并填充到第三页的文本框中。
+ ///
+ ///
+ /// 生成的模板包含以下部分:
+ /// - 环境信息(软件版本、操作系统、.NET版本、触控支持)
+ /// - 设备信息(设备ID、遥测ID)
+ /// - 软件配置(PPT联动设置、墨迹识别设置)
+ ///
+ private void GenerateMarkdownTemplate()
+ {
+ string template = "## 环境信息\n";
+
+ if (_page1.CheckAppVersion.IsChecked == true)
+ {
+ template += $"- 软件版本: {_appVersion}\n";
+ }
+ if (_page1.CheckUpdateChannel.IsChecked == true)
+ {
+ template += $"- 更新通道: {_updateChannel}\n";
+ }
+ if (_page1.CheckOSVersion.IsChecked == true)
+ {
+ template += $"- 操作系统: {_osVersion}\n";
+ }
+ if (_page1.CheckNetVersion.IsChecked == true)
+ {
+ template += $"- .NET 版本: {_netVersion}\n";
+ }
+ if (_page1.CheckTouchSupport.IsChecked == true)
+ {
+ template += $"- 触控支持: {_touchSupport}\n";
+ }
+
+ template += "\n## 设备信息\n";
+ if (_page1.CheckDeviceId.IsChecked == true)
+ {
+ template += $"- 设备ID: {_deviceId}\n";
+ }
+ if (_page1.CheckFanceId.IsChecked == true && !string.IsNullOrEmpty(_telemetryId))
+ {
+ template += $"- 遥测ID: {_telemetryId}\n";
+ }
+
+ if (_page1.CheckPPTLinkage.IsChecked == true || _page1.CheckInkRecognition.IsChecked == true)
+ {
+ template += "\n## 软件配置\n";
+ if (_page1.CheckPPTLinkage.IsChecked == true)
+ {
+ template += "### PPT联动设置\n";
+ template += _pptLinkageSettings.TrimEnd('\n', '\r');
+ }
+ if (_page1.CheckInkRecognition.IsChecked == true)
+ {
+ if (_page1.CheckPPTLinkage.IsChecked == true) template += "\n";
+ template += "### 墨迹识别设置\n";
+ template += _inkRecognitionSettings.TrimEnd('\n', '\r');
+ }
+ }
+
+ _page3.TextBoxMarkdownTemplate.Text = template;
+ }
+
+ ///
+ /// 构建反馈信息元组,包含版本信息、系统信息和额外信息。
+ ///
+ /// 包含版本信息、系统信息和额外信息的元组
+ ///
+ /// 根据第一页用户的复选框选择情况,收集以下信息:
+ /// - versionInfo: 软件版本和更新通道
+ /// - systemInfo: 操作系统、.NET版本和触控支持
+ /// - extraInfo: 设备ID、遥测ID、PPT联动设置和墨迹识别设置
+ ///
+ private (string versionInfo, string systemInfo, string extraInfo) BuildFeedbackInfo()
+ {
+ string versionInfo = "";
+ string systemInfo = "";
+ string extraInfo = "";
+
+ if (_page1.CheckAppVersion.IsChecked == true || _page1.CheckUpdateChannel.IsChecked == true)
+ {
+ if (_page1.CheckAppVersion.IsChecked == true)
+ {
+ versionInfo += _appVersion;
+ }
+ if (_page1.CheckUpdateChannel.IsChecked == true)
+ {
+ if (!string.IsNullOrEmpty(versionInfo))
+ {
+ versionInfo += " ";
+ }
+ versionInfo += $"({_updateChannel})";
+ }
+ }
+
+ if (_page1.CheckOSVersion.IsChecked == true || _page1.CheckNetVersion.IsChecked == true || _page1.CheckTouchSupport.IsChecked == true)
+ {
+ if (_page1.CheckOSVersion.IsChecked == true)
+ {
+ systemInfo += _osVersion;
+ }
+ if (_page1.CheckNetVersion.IsChecked == true)
+ {
+ if (!string.IsNullOrEmpty(systemInfo))
+ {
+ systemInfo += " | ";
+ }
+ systemInfo += _netVersion;
+ }
+ if (_page1.CheckTouchSupport.IsChecked == true)
+ {
+ if (!string.IsNullOrEmpty(systemInfo))
+ {
+ systemInfo += " | ";
+ }
+ systemInfo += $"触控:{_touchSupport}";
+ }
+ }
+
+ if (_page1.CheckDeviceId.IsChecked == true)
+ {
+ extraInfo += $"设备ID: {_deviceId}\n";
+ }
+
+ if (_page1.CheckFanceId.IsChecked == true)
+ {
+ extraInfo += $"遥测ID: {_telemetryId}\n";
+ }
+
+ if (_page1.CheckPPTLinkage.IsChecked == true)
+ {
+ extraInfo += "\nPPT联动设置:\n";
+ extraInfo += _pptLinkageSettings.TrimEnd('\n', '\r');
+ }
+
+ if (_page1.CheckInkRecognition.IsChecked == true)
+ {
+ extraInfo += "\n墨迹识别设置:\n";
+ extraInfo += _inkRecognitionSettings.TrimEnd('\n', '\r');
+ }
+
+ return (versionInfo, systemInfo, extraInfo);
+ }
+
+ ///
+ /// 构建GitHub Issue创建页面的URL,包含预填的环境信息参数。
+ ///
+ /// 完整的GitHub Issue URL字符串
+ ///
+ /// URL基于模板01-bug_report.yml,并根据用户选择的信息添加以下查询参数:
+ /// - version: 版本信息
+ /// - os: 系统信息
+ /// - extra: 额外信息(设备ID、遥测ID、配置信息)
+ ///
+ private string BuildGitHubIssueUrl()
+ {
+ var (versionInfo, systemInfo, extraInfo) = BuildFeedbackInfo();
+
+ string url = "https://github.com/InkCanvasForClass/community/issues/new?template=01-bug_report.yml";
+
+ if (!string.IsNullOrEmpty(versionInfo))
+ {
+ url += $"&version={Uri.EscapeDataString(versionInfo)}";
+ }
+
+ if (!string.IsNullOrEmpty(systemInfo))
+ {
+ url += $"&os={Uri.EscapeDataString(systemInfo)}";
+ }
+
+ if (!string.IsNullOrEmpty(extraInfo))
+ {
+ url += $"&extra={Uri.EscapeDataString(extraInfo)}";
+ }
+
+ return url;
+ }
+
+ ///
+ /// 打开GitHub Issue页面按钮点击事件处理器。
+ ///
+ /// 事件发送者
+ /// 路由事件参数
+ ///
+ /// 1. 构建包含环境信息的GitHub Issue URL
+ /// 2. 使用系统默认浏览器打开该URL
+ /// 3. 关闭反馈窗口
+ ///
+ public void BtnOpenGitHubIssue_Click(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ string url = BuildGitHubIssueUrl();
+
+ Process.Start(new ProcessStartInfo
+ {
+ FileName = url,
+ UseShellExecute = true
+ });
+
+ Close();
+ }
+ catch (Exception ex)
+ {
+ System.Diagnostics.Debug.WriteLine($"打开反馈链接失败: {ex.Message}");
+ }
+ }
+
+ ///
+ /// 复制Issue链接按钮点击事件处理器,将GitHub Issue URL复制到剪贴板。
+ ///
+ /// 事件发送者
+ /// 路由事件参数
+ ///
+ /// 1. 构建包含环境信息的GitHub Issue URL
+ /// 2. 将URL复制到系统剪贴板
+ /// 3. 更新按钮显示为"已复制 ✓"
+ ///
+ public void CardCopyIssueUrl_Click(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ string url = BuildGitHubIssueUrl();
+
+ Clipboard.SetText(url);
+ _page3.CardCopyIssueUrl.Header = "已复制 ✓";
+ }
+ catch (Exception ex)
+ {
+ System.Diagnostics.Debug.WriteLine($"复制反馈链接失败: {ex.Message}");
+ }
+ }
+
+ ///
+ /// 复制Markdown模板按钮点击事件处理器,将Markdown模板复制到剪贴板。
+ ///
+ /// 事件发送者
+ /// 路由事件参数
+ ///
+ /// 1. 从第三页获取Markdown模板内容
+ /// 2. 将模板复制到系统剪贴板
+ /// 3. 更新按钮显示为"已复制 ✓"
+ ///
+ public void BtnCopyMarkdown_Click(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ Clipboard.SetText(_page3.MarkdownTemplate);
+ _page3.BtnCopyMarkdown.Content = "已复制 ✓";
+ }
+ catch (Exception ex)
+ {
+ System.Diagnostics.Debug.WriteLine($"复制Markdown模板失败: {ex.Message}");
+ }
+ }
+ }
+}
diff --git a/Ink Canvas/Windows/SettingsViews/SettingsViews/AboutPanel.xaml b/Ink Canvas/Windows/SettingsViews/SettingsViews/AboutPanel.xaml
index e9accf11..c49eece4 100644
--- a/Ink Canvas/Windows/SettingsViews/SettingsViews/AboutPanel.xaml
+++ b/Ink Canvas/Windows/SettingsViews/SettingsViews/AboutPanel.xaml
@@ -178,6 +178,41 @@
+
+
+
+
+
+
+
diff --git a/Ink Canvas/Windows/SettingsViews/SettingsViews/AboutPanel.xaml.cs b/Ink Canvas/Windows/SettingsViews/SettingsViews/AboutPanel.xaml.cs
index 7d56337f..05d4028b 100644
--- a/Ink Canvas/Windows/SettingsViews/SettingsViews/AboutPanel.xaml.cs
+++ b/Ink Canvas/Windows/SettingsViews/SettingsViews/AboutPanel.xaml.cs
@@ -460,6 +460,19 @@ private void LinkContributors_MouseLeftButtonDown(object sender, MouseButtonEven
}
}
+ private void BtnReportIssue_Click(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ var feedbackWindow = new FeedbackWindow();
+ feedbackWindow.ShowDialog();
+ }
+ catch (Exception ex)
+ {
+ System.Diagnostics.Debug.WriteLine($"打开反馈窗口失败: {ex.Message}");
+ }
+ }
+
///
/// 应用主题
///