diff --git a/Language/en_US.xaml b/Language/en_US.xaml
index a06848e..fbd1a3f 100644
--- a/Language/en_US.xaml
+++ b/Language/en_US.xaml
@@ -200,6 +200,9 @@
P021: Diamond requires cleaning
P011: No diamond detected
Please check if the cutting tool door is closed
+ The algorithm is running abnormally:
+ The test result is empty:
+
Application error:
diff --git a/Language/zh_CN.xaml b/Language/zh_CN.xaml
index 390a981..bcb4969 100644
--- a/Language/zh_CN.xaml
+++ b/Language/zh_CN.xaml
@@ -201,7 +201,9 @@
P004:JSON解析失败
P021:检测到钻石需进行清洁
P011:未检测到钻石
- S007:请检查切工仪设备舱门是否关闭
+ S007:请检查切工仪设备舱门是否关闭
+ 算法运行异常:
+ 检测结果为空:
应用程序出现错误:
diff --git a/Model/Attributes/LogAttribute.cs b/Model/Attributes/LogAttribute.cs
index 15690f3..db47fe7 100644
--- a/Model/Attributes/LogAttribute.cs
+++ b/Model/Attributes/LogAttribute.cs
@@ -4,6 +4,7 @@ using Rougamo;
using Rougamo.Context;
using System.Reflection;
using System.Text;
+using SparkClient.Model.Extension;
namespace SparkClient.Model.Attributes
{
@@ -28,17 +29,37 @@ namespace SparkClient.Model.Attributes
}
// 记录日志
- Logger.Debug($"Entering {context.Method.DeclaringType?.Name}.{context.Method.Name} with parameters: {parameterLog}");
+ //Logger.Debug($"Entering {context.Method.DeclaringType?.Name}.{context.Method.Name} with parameters: {parameterLog}");
}
public override void OnExit(MethodContext context)
{
//Logger.Debug($"Exiting {context.Method.DeclaringType?.Name}.{context.Method.Name}");
- // 获取返回值
var returnValue = context.ReturnValue;
+ // 获取返回值
+ if (context.Exception != null)
+ {
+ var parameters = context.Method.GetParameters();
+ var arguments = context.Arguments;
- // 记录日志
- Logger.Debug($"Exiting {context.Method.DeclaringType?.Name}.{context.Method.Name} with return value: {returnValue}");
+ // 构建参数字符串
+ var parameterLog = new StringBuilder();
+ for (int i = 0; i < parameters.Length; i++)
+ {
+ parameterLog.Append($"{parameters[i].Name} = {arguments[i].ToSafeAbundantString()}, ");
+ }
+
+ Logger.Error($"[METS]=============Method Exception Termination[MsgStart]=============");
+ Logger.Error($"Method: {context.Method.DeclaringType?.Name}.{context.Method.Name}");
+ Logger.Error($"Method Parameters: {parameterLog.ToString()}");
+ Logger.Error($"Exception: {context.Exception.Message} \r\n{context.Exception.StackTrace}");
+ Logger.Error($"[METE]=============Method Exception Termination[MsgEnd]===============");
+ }
+ else
+ {
+ // 记录日志
+ //Logger.Debug($"[MethodExiting] Exiting {context.Method.DeclaringType?.Name}.{context.Method.Name} with return value: {returnValue}");
+ }
}
}
}
diff --git a/Model/Helper/ClientHotKeyManager.cs b/Model/Helper/ClientHotKeyManager.cs
new file mode 100644
index 0000000..80e6596
--- /dev/null
+++ b/Model/Helper/ClientHotKeyManager.cs
@@ -0,0 +1,153 @@
+using System.Collections.Concurrent;
+using System.Diagnostics;
+using EnumsNET;
+using GlobalHotKey;
+using log4net;
+using SparkClient.Model.Extension;
+
+namespace SparkClient.Model.Helper;
+
+public sealed class ClientHotKeyManager
+{
+ private static readonly ILog Logger = LogManager.GetLogger(typeof(ClientHotKeyManager));
+ #region 单例模式
+ private static readonly Lazy _instance =
+ new Lazy(() => new ClientHotKeyManager());
+ public static ClientHotKeyManager Instance => _instance.Value;
+ private ClientHotKeyManager() { }
+ #endregion
+
+ #region 存储结构
+ private readonly ConcurrentDictionary _hotKeys =
+ new ConcurrentDictionary();
+ private readonly ConcurrentDictionary _manager =
+ new ConcurrentDictionary();
+ // private HotKeyManager _hotKeyManager = new HotKeyManager();
+ #endregion
+
+ #region 公共方法
+ ///
+ /// 注册热键
+ ///
+ /// 热键
+ /// 事件
+ /// 来源类
+ /// 非法参数
+ /// 重复注册
+ public void Register(HotKey hotKey, EventHandler handler, object registrant = null)
+ {
+ if (hotKey == null) throw new ArgumentNullException(nameof(hotKey));
+ if (handler == null) throw new ArgumentNullException(nameof(handler));
+ Logger.Info($"快捷键注册: [ Key = {hotKey.Key.GetName()}, Modifiers = {hotKey.Modifiers.ToSafeAbundantString()}, Handler = {handler.Method.Name}, From = {registrant.GetType().Name}]");
+ var record = new HotKeyRecord(hotKey, handler, registrant ?? GetDefaultRegistrant());
+
+ if (_hotKeys.TryAdd(hotKey, record))
+ {
+ HotKeyManager _hotKeyManager = new HotKeyManager();
+ _hotKeyManager.Register(hotKey);
+ _hotKeyManager.KeyPressed += handler;
+ _manager.TryAdd(hotKey, _hotKeyManager);
+ }
+ else
+ {
+ throw new InvalidOperationException($"HotKey {hotKey} already registered!");
+ }
+ }
+
+ ///
+ /// 释放热键
+ ///
+ ///
+ public void Unregister(HotKey hotKey)
+ {
+ if (_hotKeys.TryRemove(hotKey, out var record))
+ {
+ Logger.Info($"快捷键释放: {hotKey.ToSafeAbundantString()}");
+ HotKeyManager _hotKeyManager = _manager.ContainsKey(hotKey)? _manager[hotKey]: new HotKeyManager();
+ _hotKeyManager.Unregister(hotKey);
+ _hotKeyManager.KeyPressed -= record.Handler;
+ _manager.TryRemove(hotKey, out _);
+ }
+ }
+ ///
+ /// 热键是否注册
+ ///
+ ///
+ ///
+ public bool ContainsHotKey(HotKey hotKey) => _hotKeys.ContainsKey(hotKey);
+
+ ///
+ /// 刷新热键
+ ///
+ ///
+ ///
+ ///
+ ///
+ private void RefreshHotKey(HotKey hotKey, EventHandler newHandler, object newRegistrant = null)
+ {
+ if (hotKey == null || newHandler == null) throw new ArgumentNullException();
+
+ var registrant = newRegistrant ?? GetDefaultRegistrant();
+
+ if (!_manager.ContainsKey(hotKey))
+ {
+ HotKeyManager managerTemp = new HotKeyManager();
+ managerTemp.Register(hotKey);
+ managerTemp.KeyPressed += newHandler;
+ _manager.TryAdd(hotKey, managerTemp);
+ }
+ HotKeyManager _hotKeyManager = _manager.ContainsKey(hotKey)? _manager[hotKey]: null;
+ _hotKeys.AddOrUpdate(
+ hotKey,
+ key =>
+ {
+ _hotKeyManager.Register(key);
+ _hotKeyManager.KeyPressed += newHandler;
+ return new HotKeyRecord(hotKey, newHandler,newRegistrant);
+ },
+ (key, existingRecord) =>
+ {
+ _hotKeyManager.KeyPressed -= existingRecord.Handler;
+ _hotKeyManager.KeyPressed += newHandler;
+ return new HotKeyRecord(hotKey, newHandler,newRegistrant);
+ });
+ }
+ #endregion
+
+ #region 调试支持
+ [Conditional("DEBUG")]
+ public void PrintDebugInfo()
+ {
+ foreach (var kvp in _hotKeys)
+ {
+ Debug.WriteLine($"HotKey: {kvp.Key} | Registrant: {kvp.Value.Registrant}");
+ }
+ }
+ #endregion
+
+ #region 辅助方法
+ private object GetDefaultRegistrant()
+ {
+ // 获取调用堆栈中的注册者信息(例如:类名+方法名)
+ var stackTrace = new StackTrace(skipFrames: 2);
+ var frame = stackTrace.GetFrame(0);
+ return $"{frame.GetMethod().DeclaringType?.Name}.{frame.GetMethod().Name}";
+ }
+ #endregion
+
+ #region 内部记录类
+ private class HotKeyRecord
+ {
+ public HotKey HotKey { get; }
+ public EventHandler Handler { get; }
+ public object Registrant { get; }
+
+ public HotKeyRecord(HotKey hotKey, EventHandler handler, object registrant)
+ {
+ HotKey = hotKey;
+ Handler = handler;
+ Registrant = registrant;
+ }
+ }
+ #endregion
+}
\ No newline at end of file
diff --git a/Model/Helper/ClientHotKeys.cs b/Model/Helper/ClientHotKeys.cs
new file mode 100644
index 0000000..0a08787
--- /dev/null
+++ b/Model/Helper/ClientHotKeys.cs
@@ -0,0 +1,24 @@
+using System.Windows.Input;
+using GlobalHotKey;
+
+namespace SparkClient.Model.Helper;
+
+public class ClientHotKeys
+{
+ ///
+ /// 快速开始检测
+ ///
+ public static readonly HotKey QuickAnewDetectHotKey = new HotKey(Key.Q, ModifierKeys.Control | ModifierKeys.Alt);
+ ///
+ /// 关闭检测结果页
+ ///
+ public static readonly HotKey CloseResultHotKey = new HotKey(Key.E, ModifierKeys.Control | ModifierKeys.Alt);
+ ///
+ /// 检测结果页 切换详细数据页和数据模型页
+ ///
+ public static readonly HotKey SwitchPagesHotKey = new HotKey(Key.D1, ModifierKeys.Control);
+ ///
+ /// 心箭图渲染
+ ///
+ public static readonly HotKey ArrowAndHeartHotKey = new HotKey(Key.D2, ModifierKeys.Control);
+}
\ No newline at end of file
diff --git a/Model/Services/SOCClientService.cs b/Model/Services/SOCClientService.cs
index e0fbe0d..6ec502e 100644
--- a/Model/Services/SOCClientService.cs
+++ b/Model/Services/SOCClientService.cs
@@ -68,7 +68,7 @@ namespace SparkClient.Model.Services
{
Logger.Info($"Request sent to URL: {url}");
client.DefaultRequestHeaders.Add("Authorization", "Basic " + _authToken);
-
+ client.Timeout = new TimeSpan(0, 0, 5);
HttpResponseMessage result = await client.GetAsync(url);
// 提前读取内容并存储
diff --git a/ViewModel/BaseWindow/BaseControlVM.cs b/ViewModel/BaseWindow/BaseControlVM.cs
index 38218b3..be313e1 100644
--- a/ViewModel/BaseWindow/BaseControlVM.cs
+++ b/ViewModel/BaseWindow/BaseControlVM.cs
@@ -5,6 +5,7 @@ using HandyControl.Controls;
using SparkClient.Model.Helper;
using SparkClient.Model.Services;
using SparkClient.ViewModel.Grading;
+using SparkClient.Views.Grading;
using MessageBox = SparkClient.Views.Dialog.MessageBox;
namespace SparkClient.ViewModel.BaseWindow;
@@ -30,9 +31,6 @@ public class BaseControlVM : BaseViewModel
public ICommand NextCommand { get; }
-
-
-
///
/// 构造:创建一个带有子页面的模板,并指定子窗口标题,并指定右侧按钮事件内容
///
@@ -64,25 +62,32 @@ public class BaseControlVM : BaseViewModel
ShowFunctionButton = Visibility.Hidden;
if (vm.GetType().Equals(typeof(GradingResultVM)))
{
- Application.Current.Dispatcher.Invoke(() =>
- {
- try
- {
- HotKeyManager _hotKeyManager = new HotKeyManager();
- var hotKey = new HotKey(Key.Q, ModifierKeys.Control | ModifierKeys.Alt);
- _hotKeyManager.Register(hotKey);
- _hotKeyManager.KeyPressed += OnHotKeyPressed;
-
- HotKeyManager _hotKeyManagerClose = new HotKeyManager();
- var hotKeyClose = new HotKey(Key.E, ModifierKeys.Control | ModifierKeys.Alt);
- _hotKeyManagerClose.Register(hotKeyClose);
- _hotKeyManagerClose.KeyPressed += OnHotKeyPressedClose;
- }
- catch (Exception ex)
- {
- Logger.Info("设计缺陷:快捷键重复注册");
- }
- });
+ // Application.Current.Dispatcher.Invoke(() =>
+ // {
+ // try
+ // {
+ // if (_hkmQuickAnewDetect == null)
+ // {
+ // _hkmQuickAnewDetect = new HotKeyManager();
+ // _hkmQuickAnewDetect.Register(_hkQuickAnewDetect);
+ // _hkmQuickAnewDetect.KeyPressed += OnHotKeyPressed;
+ // }
+ //
+ // if (_hkmCloseResult == null)
+ // {
+ // _hkmCloseResult = new HotKeyManager();
+ // _hkmCloseResult.Register(_hkCloseResult);
+ // _hkmCloseResult.KeyPressed += OnHotKeyPressedClose;
+ // }
+ //
+ // }
+ // catch (Exception ex)
+ // {
+ // Logger.Info($"快捷键注册失败,静默处理:{ex.Message}");
+ // }
+ // });
+ ClientHotKeyManager.Instance.Register(ClientHotKeys.QuickAnewDetectHotKey, OnHotKeyPressed, this);
+ ClientHotKeyManager.Instance.Register(ClientHotKeys.CloseResultHotKey, OnHotKeyPressedClose, this);
}
else if(vm.GetType().Equals(typeof(GradingLoadingVM)))
{
@@ -150,6 +155,18 @@ public class BaseControlVM : BaseViewModel
WindowManager.PreviousVM();
WindowManager.mainViewModel.Content = WindowManager.PreviousVM();
await SOCClientService.Service.OpenPump(false);
+
+ try
+ {
+ ClientHotKeyManager.Instance.Unregister(ClientHotKeys.QuickAnewDetectHotKey);
+ ClientHotKeyManager.Instance.Unregister(ClientHotKeys.CloseResultHotKey);
+ ClientHotKeyManager.Instance.Unregister(ClientHotKeys.SwitchPagesHotKey);
+ ClientHotKeyManager.Instance.Unregister(ClientHotKeys.ArrowAndHeartHotKey);
+ }
+ catch (Exception ex)
+ {
+ Logger.Info($"快捷键释放失败,静默处理:{ex.Message}");
+ }
//bool isSaved = (Content as GradingResultVM).isSaved;
// if (isSaved)
// {
diff --git a/ViewModel/Grading/DiamondSelectVM.cs b/ViewModel/Grading/DiamondSelectVM.cs
index fe4f4fb..b2f1388 100644
--- a/ViewModel/Grading/DiamondSelectVM.cs
+++ b/ViewModel/Grading/DiamondSelectVM.cs
@@ -668,7 +668,7 @@ public class DiamondSelectVM : BaseViewModel
try
{
//WindowManager.mainViewModel.Content = WindowManager.PreviousVM();
- Logger.Info($"检测完毕,跳转至结果页面:{param.ToSafeAbundantString()}");
+ Logger.Info($"检测完毕,跳转至结果页面:");
BaseControlVM vm = new BaseControlVM(new GradingResultVM(param), MultilingualHelper.getString("DetectionResult"));
var ct = param.measurements.VOLUME / 57;
vm.WindowTitle = string.IsNullOrWhiteSpace(param.DiamondCode) ? vm.WindowTitle : $"{vm.WindowTitle} - {param.DiamondCode}({ct.ToString("F3")}ct)";
diff --git a/ViewModel/Grading/GradingLoadingVM.cs b/ViewModel/Grading/GradingLoadingVM.cs
index 8777520..d04cc24 100644
--- a/ViewModel/Grading/GradingLoadingVM.cs
+++ b/ViewModel/Grading/GradingLoadingVM.cs
@@ -314,7 +314,7 @@ public class GradingLoadingVM : BaseViewModel,IDisposable
{
bool hasErr = false;
Logger.Info($"算法运行完毕:{detectTask.Status}");
- Logger.Info($"算法运行结果:{detectTask.Result.ToSafeAbundantString()}");
+ Logger.Info($"算法运行结果:[Status = {detectTask.Result.Status}; Message = {detectTask.Result.ErrorMsg}]");
try
{
CompleteProgressQuicklyAsync();
@@ -339,6 +339,14 @@ public class GradingLoadingVM : BaseViewModel,IDisposable
new MessageBox().Show(MultilingualHelper.getString("NoDiamond"));
hasErr = true;
return -1;
+ case "DETECTING_EXCEPTION":
+ new MessageBox().Show(MultilingualHelper.getString("DETECTING_EXCEPTION") + detectTask.Result.ErrorMsg);
+ hasErr = true;
+ return -1;
+ case "DETECTING_RESULT_ISNULL":
+ new MessageBox().Show(MultilingualHelper.getString("DETECTING_RESULT_ISNULL") + detectTask.Result.ErrorMsg);
+ hasErr = true;
+ return -1;
}
Progress = (100.00);
diff --git a/Views/Grading/GradingResult.xaml.cs b/Views/Grading/GradingResult.xaml.cs
index 84dc182..92b4be6 100644
--- a/Views/Grading/GradingResult.xaml.cs
+++ b/Views/Grading/GradingResult.xaml.cs
@@ -5,7 +5,9 @@ using System.Windows.Forms.VisualStyles;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
+using GlobalHotKey;
using log4net;
+using SparkClient.Model.Helper;
using SparkClient.ViewModel.Grading;
using GeometryModel3D = HelixToolkit.Wpf.SharpDX.GeometryModel3D;
@@ -20,6 +22,10 @@ public partial class GradingResult
// 用于记录当前所有已存在的Popup
private List _allPopups = new List();
+
+ //快捷键
+ // private HotKeyManager? _hkmSwitchPages = null;
+ // public static readonly HotKey _hkSwitchPages = new HotKey(Key.D1, ModifierKeys.Control);
public GradingResult()
{
InitializeComponent();
@@ -27,6 +33,13 @@ public partial class GradingResult
// 在Window最外层捕获鼠标点击,判断是否点击在Popup之外,如果是则关闭所有Popup
this.PreviewMouseLeftButtonDown += Window_PreviewMouseLeftButtonDown;
//DataContext = new GradingResultVM(null);
+ ClientHotKeyManager.Instance.Register(ClientHotKeys.SwitchPagesHotKey, OnHotKeyPressed, this);
+ // if (_hkmSwitchPages == null)
+ // {
+ // _hkmSwitchPages = new HotKeyManager();
+ // _hkmSwitchPages.Register(_hkSwitchPages);
+ // _hkmSwitchPages.KeyPressed += OnHotKeyPressed;
+ // }
// this.Viewport3Dx.EffectsManager = new DefaultEffectsManager();
// this.Viewport3Dx.Camera = new PerspectiveCamera()
@@ -44,7 +57,13 @@ public partial class GradingResult
// triangles.AddRange(entities);
// };
}
+
+
+ private void OnHotKeyPressed(object sender, KeyPressedEventArgs e)
+ {
+ ButtonBase_OnClick(sender, null);
+ }
///
/// 点击模型
diff --git a/Views/UserControl/Viewport3D.xaml.cs b/Views/UserControl/Viewport3D.xaml.cs
index 628345c..baa61cc 100644
--- a/Views/UserControl/Viewport3D.xaml.cs
+++ b/Views/UserControl/Viewport3D.xaml.cs
@@ -17,6 +17,7 @@ using SharpDX.Direct3D11;
using SharpDX.DXGI;
using MathNet.Numerics;
using System.Windows.Media;
+using GlobalHotKey;
using NPOI.SS.Formula.Functions;
using SparkClient.Model.Services;
using MessageBox = SparkClient.Views.Dialog.MessageBox;
@@ -36,6 +37,8 @@ public partial class Viewport3D
Viewport3Dx.ShowViewCube = false;
Viewport3Dx.ShowCoordinateSystem = false;
ViewportManager.SetViewport3D(Viewport3Dx);
+
+ ClientHotKeyManager.Instance.Register(ClientHotKeys.ArrowAndHeartHotKey, ShowArrowAndHeart, this);
}
///
@@ -280,15 +283,8 @@ public partial class Viewport3D
break;
case "BtnShow3DView":
// ObjExporter.ExportToObj2(ViewportManager.ViewportTriangle, @"D:\id03.obj");
- try
- {
- RayHelper.GenerateRender(ViewportManager.ViewportTriangle.First().TriangleCode, "123");
- }
- catch (Exception ex)
- {
- new MessageBox().Show(ex.Message);
- }
+ ShowArrowAndHeart(sender, null);
break;
}
@@ -356,6 +352,18 @@ public partial class Viewport3D
}
+ private void ShowArrowAndHeart(object sender, KeyPressedEventArgs e)
+ {
+ try
+ {
+ RayHelper.GenerateRender(ViewportManager.ViewportTriangle.First().TriangleCode, "123");
+ }
+ catch (Exception ex)
+ {
+ new MessageBox().Show(ex.Message);
+ }
+ }
+
// private void BtnDirection_OnClick(object sender, RoutedEventArgs e)
// {
// var directionName = ((Button)sender).Name.ToString();