diff --git a/App.config b/App.config index 52904f6..ae9b93b 100644 --- a/App.config +++ b/App.config @@ -2,7 +2,7 @@ - + @@ -18,7 +18,8 @@ - + + diff --git a/Model/Services/AlgorithmServer.cs b/Model/Services/AlgorithmServer.cs index c1fcc8b..0355348 100644 --- a/Model/Services/AlgorithmServer.cs +++ b/Model/Services/AlgorithmServer.cs @@ -39,6 +39,7 @@ namespace SparkClient.Model.Services bool half_circle = boolResult; //算法配置参数,初始化算法配置数据并获取 AlgorithmConfigJson + _algorithmConfigVM.InitAlgorithmData(null); string algo_config = _algorithmConfigVM.AlgorithmConfigJson; diff --git a/SparkClient.csproj b/SparkClient.csproj index 1bf995e..d323125 100644 --- a/SparkClient.csproj +++ b/SparkClient.csproj @@ -274,4 +274,10 @@ + + + bin\Debug\net8.0-windows\SparkDotNetCore.dll + + + diff --git a/SparkClient.sln.DotSettings.user b/SparkClient.sln.DotSettings.user index e25331f..322b3d7 100644 --- a/SparkClient.sln.DotSettings.user +++ b/SparkClient.sln.DotSettings.user @@ -1,9 +1,12 @@  + True ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded @@ -20,7 +23,9 @@ ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded @@ -33,7 +38,9 @@ ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded @@ -63,8 +70,11 @@ ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded + ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded @@ -80,8 +90,10 @@ ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded @@ -93,6 +105,7 @@ ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded diff --git a/ViewModel/Grading/DiamondSelectVM.cs b/ViewModel/Grading/DiamondSelectVM.cs index ce2934e..3eef198 100644 --- a/ViewModel/Grading/DiamondSelectVM.cs +++ b/ViewModel/Grading/DiamondSelectVM.cs @@ -145,204 +145,250 @@ public class DiamondSelectVM : BaseViewModel DiamondCode = ""; } - var loadingView = new GradingLoadingVM(param.ToString(), DiamondCode); - BaseControlVM vm = new BaseControlVM(loadingView, MultilingualHelper.getString("DetectionResult")); - vm.WindowTitle = string.IsNullOrWhiteSpace(DiamondCode) ? vm.WindowTitle : $"{vm.WindowTitle} - {DiamondCode}"; - WindowManager.mainViewModel.Content = vm; - WindowManager.openContent.Add(vm); - - int res = await loadingView.Start(); + string runModel = ConfigurationHelper.ReadConfigValue("RunModel")??"1"; - if (res < 0) + if("0".Equals(runModel)) + //json模式 + DoStartGrading(param); + else if ("1".Equals(runModel)) { - //返回 - loadingView.Dispose(); - WindowManager.mainViewModel.Content = WindowManager.PreviousVM(); - ; - return; + //Image模式 + var loadingView = new GradingLoadingVM(param.ToString(), DiamondCode); + BaseControlVM vm = new BaseControlVM(loadingView, MultilingualHelper.getString("wait")); + vm.WindowTitle = string.IsNullOrWhiteSpace(DiamondCode) ? vm.WindowTitle : $"{vm.WindowTitle} - {DiamondCode}"; + WindowManager.mainViewModel.Content = vm; + WindowManager.openContent.Add(vm); + + int res = await loadingView.Start(1); + + if (res > -100 && res < 0) + { + //返回 + loadingView.Dispose(); + WindowManager.mainViewModel.Content = WindowManager.PreviousVM(); + ; + return; + } + else if ( res <= -100) + { + return; + } + else + { + GradingResult(loadingView.Parameter); + loadingView.Dispose(); + } } else { - //获取结果,下一步 - } -#if DEBUG - //DoStartGrading(param); -//#else - LoadingDialog loading = new LoadingDialog(DiamondCode); - try - { - if (param != null) - { - string progTime = ConfigurationHelper.ReadConfigValue("ProgressTime"); - - int iProgTime = 50000; - int.TryParse(progTime, out iProgTime); - int setpTime = iProgTime / 97; - - var progressTask = Task.Run(() => Application.Current.Dispatcher.Invoke(() => loading.ShowDialog())); - await Task.Run(async () => - { - bool isEnd = false; - int progress = 0; - // 更新进度条的值(需要在UI线程上执行) - loading.Dispatcher.Invoke(async () => - { - for (int i = 0; i <= 97; i++) - { - if (isEnd) - { - break; - } - // 模拟耗时操作 - //System.Threading.Thread.Sleep(50); // 休眠50毫秒 - await Task.Delay(setpTime); - loading.setValue(i); - progress = i; - } - }); - - SocResultEntity socResolt = new SocResultEntity(); - AlgorithmResultEntity parameter = new AlgorithmResultEntity(); - parameter.Standard = "IGI 2024"; - string value = param.ToString() ?? ""; - if (value != null && value.Split(" ").Length == 3) - { - parameter.Shape = value.Split(" ")[0]; - parameter.CrownType = value.Split(" ")[1]; - parameter.PavType = value.Split(" ")[2]; - } - // 初始化SOC客户端服务,传入SOC端的地址和认证Token - _socClientService = new SOCClientService(); - // 启动soc - socResolt = await _socClientService.ProcessImageCollectionAsync(); - switch (socResolt.Status) - { - case StatusCodes.OpenOfTheHatch: - ShowErrorMessage(MultilingualHelper.getString("OpenOfTheHatch"), loading); - return; - case StatusCodes.DeviceNotFound: - ShowErrorMessage(MultilingualHelper.getString("DeviceNotFound"), loading); - return; - case StatusCodes.InProgress: - ShowErrorMessage(MultilingualHelper.getString("InProgress"), loading); - return; - case StatusCodes.CacheCleared: - ShowErrorMessage(MultilingualHelper.getString("CacheCleared"), loading); - return; - case StatusCodes.CannotSendCommand: - ShowErrorMessage(MultilingualHelper.getString("CannotSendCommand"), loading); - return; - case StatusCodes.MicrocontrollerTimeout: - ShowErrorMessage(MultilingualHelper.getString("MicrocontrollerTimeout"), loading); - return; - case StatusCodes.MicrocontrollerError: - ShowErrorMessage(MultilingualHelper.getString("MicrocontrollerError"), loading); - return; - case StatusCodes.CameraNotConnected: - ShowErrorMessage(MultilingualHelper.getString("CameraNotConnected"), loading); - return; - } - _algorithmServer = new AlgorithmServer(); - // //图片集合 - string image_files = JsonConvert.SerializeObject(socResolt.Images, Formatting.Indented); - // string image_files =$"[ \"image_0.bmp\", \"image_1.bmp\", \"image_2.bmp\", \"image_3.bmp\", \"image_4.bmp\", \"image_5.bmp\", \"image_6.bmp\", \"image_7.bmp\", \"image_8.bmp\", \"image_9.bmp\", \"image_10.bmp\", \"image_11.bmp\", \"image_12.bmp\", \"image_13.bmp\", \"image_14.bmp\", \"image_15.bmp\", \"image_16.bmp\", \"image_17.bmp\", \"image_18.bmp\", \"image_19.bmp\", \"image_20.bmp\", \"image_21.bmp\", \"image_22.bmp\", \"image_23.bmp\", \"image_24.bmp\", \"image_25.bmp\", \"image_26.bmp\", \"image_27.bmp\", \"image_28.bmp\", \"image_29.bmp\", \"image_30.bmp\", \"image_31.bmp\", \"image_32.bmp\", \"image_33.bmp\", \"image_34.bmp\", \"image_35.bmp\", \"image_36.bmp\", \"image_37.bmp\", \"image_38.bmp\", \"image_39.bmp\", \"image_40.bmp\", \"image_41.bmp\", \"image_42.bmp\", \"image_43.bmp\", \"image_44.bmp\", \"image_45.bmp\", \"image_46.bmp\", \"image_47.bmp\", \"image_48.bmp\", \"image_49.bmp\", \"image_50.bmp\", \"image_51.bmp\", \"image_52.bmp\", \"image_53.bmp\", \"image_54.bmp\", \"image_55.bmp\", \"image_56.bmp\", \"image_57.bmp\", \"image_58.bmp\", \"image_59.bmp\", \"image_60.bmp\", \"image_61.bmp\", \"image_62.bmp\", \"image_63.bmp\", \"image_64.bmp\", \"image_65.bmp\", \"image_66.bmp\", \"image_67.bmp\", \"image_68.bmp\", \"image_69.bmp\", \"image_70.bmp\", \"image_71.bmp\", \"image_72.bmp\", \"image_73.bmp\", \"image_74.bmp\", \"image_75.bmp\", \"image_76.bmp\", \"image_77.bmp\", \"image_78.bmp\", \"image_79.bmp\", \"image_80.bmp\", \"image_81.bmp\", \"image_82.bmp\", \"image_83.bmp\", \"image_84.bmp\", \"image_85.bmp\", \"image_86.bmp\", \"image_87.bmp\", \"image_88.bmp\", \"image_89.bmp\", \"image_90.bmp\", \"image_91.bmp\", \"image_92.bmp\", \"image_93.bmp\", \"image_94.bmp\", \"image_95.bmp\", \"image_96.bmp\", \"image_97.bmp\", \"image_98.bmp\", \"image_99.bmp\"]" ; - - // 保存图片到历史记录文件夹 - HandleAlgorithmFailure(image_files, DiamondCode); - - - // 启动算法 - parameter = _algorithmServer.CallParseJsonAndReturnActions(parameter.Shape, parameter.CrownType, image_files); - //机器号 - parameter.DeviceId = socResolt.DeviceId; - switch (parameter.status) - { - case StatusCodes.AlgorithmFailed: - ShowErrorMessage(MultilingualHelper.getString("AlgorithmFailed"), loading); - return; - case StatusCodes.ImageFileReadFailure: - ShowErrorMessage(MultilingualHelper.getString("ImageFileReadFailure"), loading); - return; - case StatusCodes.JsonParseFailure: - ShowErrorMessage(MultilingualHelper.getString("JsonParseFailure"), loading); - return; - case StatusCodes.NoDiamond: - ShowErrorMessage(MultilingualHelper.getString("NoDiamond"), loading); - return; - } - parameter.Standard = getStandardName(); - parameter.Shape = value.Split(" ")[0]; - parameter.CrownType = value.Split(" ")[1]; - parameter.PavType = value.Split(" ")[2]; - parameter.DiamondCode = DiamondCode; - - if (!parameter.status.Equals(StatusCodes.Ok)) - parameter.error_msg = MultilingualHelper.getString(StatusCodes.GetConstantNameByValue(parameter.status)); - //参数实体转json输出 - try - { - string parameterJson = JsonConvert.SerializeObject(parameter); - parameterJson = JToken.Parse(parameterJson).ToString(); - string outputPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "logs", "result"); - if (!Directory.Exists(outputPath)) - Directory.CreateDirectory(outputPath); - string outputFilePath = $"{outputPath}/{DiamondCode}-{DateTime.Now:yyyyMMdd_HHmmss}.json"; - using (var file = File.Create(outputFilePath)) - using (StreamWriter stream = new StreamWriter(file)) - { - stream.Write(parameterJson); - } - } - catch (Exception ex) - { - Logger.Error("output输出失败:"+ex.Message); - } + //正常模式 + var loadingView = new GradingLoadingVM(param.ToString(), DiamondCode); + BaseControlVM vm = new BaseControlVM(loadingView, MultilingualHelper.getString("wait")); + vm.WindowTitle = string.IsNullOrWhiteSpace(DiamondCode) ? vm.WindowTitle : $"{vm.WindowTitle} - {DiamondCode}"; + WindowManager.mainViewModel.Content = vm; + WindowManager.openContent.Add(vm); + + int res = await loadingView.Start(); - isEnd = true; - //GradingResult(parameter); - await loading.Dispatcher.Invoke(async () => - { - for (int i = progress; progress <= 100; i++) - { - Random random = new Random(); int minValue = 20; int maxValue = 100; // 生成50到150之间的随机整数 - int randomNumber = random.Next(minValue, maxValue + 1); - await Task.Delay(randomNumber); - loading.setValue(i); - if (loading.ProgressBar.Value == 98) - { - GradingResult(parameter); - } - if(loading.ProgressBar.Value >= 100) - { - - loading.Close(); - break; - } - } - // 检测到钻石需进行清洁 - if (parameter.status == StatusCodes.Recheck) - { - ShowErrorMessage(MultilingualHelper.getString("Recheck"), loading); - } - - }); - }); + if (res > -100 && res < 0) + { + //返回 + loadingView.Dispose(); + WindowManager.mainViewModel.Content = WindowManager.PreviousVM(); + ; + return; + } + else if ( res <= -100) + { + return; + } + else + { + GradingResult(loadingView.Parameter); + loadingView.Dispose(); } } - catch (DirectoryNotFoundException ex) - { - loading.Close(); - new MessageBox().Show(MultilingualHelper.getString("SavePathIsnotExists")); - } - catch (IOException ex) - { - loading.Close(); - new MessageBox().Show($"{MultilingualHelper.getString("FileOpened")}:{ex.Message}"); - } - finally { - - } -#endif + + + + +/** + + LoadingDialog loading = new LoadingDialog(DiamondCode); + try + { + if (param != null) + { + string progTime = ConfigurationHelper.ReadConfigValue("ProgressTime"); + + int iProgTime = 50000; + int.TryParse(progTime, out iProgTime); + int setpTime = iProgTime / 97; + + var progressTask = Task.Run(() => Application.Current.Dispatcher.Invoke(() => loading.ShowDialog())); + await Task.Run(async () => + { + bool isEnd = false; + int progress = 0; + // 更新进度条的值(需要在UI线程上执行) + loading.Dispatcher.Invoke(async () => + { + for (int i = 0; i <= 97; i++) + { + if (isEnd) + { + break; + } + // 模拟耗时操作 + //System.Threading.Thread.Sleep(50); // 休眠50毫秒 + await Task.Delay(setpTime); + loading.setValue(i); + progress = i; + } + }); + + SocResultEntity socResolt = new SocResultEntity(); + AlgorithmResultEntity parameter = new AlgorithmResultEntity(); + parameter.Standard = "IGI 2024"; + string value = param.ToString() ?? ""; + if (value != null && value.Split(" ").Length == 3) + { + parameter.Shape = value.Split(" ")[0]; + parameter.CrownType = value.Split(" ")[1]; + parameter.PavType = value.Split(" ")[2]; + } + // 初始化SOC客户端服务,传入SOC端的地址和认证Token + _socClientService = new SOCClientService(); + // 启动soc + socResolt = await _socClientService.ProcessImageCollectionAsync(); + switch (socResolt.Status) + { + case StatusCodes.OpenOfTheHatch: + ShowErrorMessage(MultilingualHelper.getString("OpenOfTheHatch"), loading); + return; + case StatusCodes.DeviceNotFound: + ShowErrorMessage(MultilingualHelper.getString("DeviceNotFound"), loading); + return; + case StatusCodes.InProgress: + ShowErrorMessage(MultilingualHelper.getString("InProgress"), loading); + return; + case StatusCodes.CacheCleared: + ShowErrorMessage(MultilingualHelper.getString("CacheCleared"), loading); + return; + case StatusCodes.CannotSendCommand: + ShowErrorMessage(MultilingualHelper.getString("CannotSendCommand"), loading); + return; + case StatusCodes.MicrocontrollerTimeout: + ShowErrorMessage(MultilingualHelper.getString("MicrocontrollerTimeout"), loading); + return; + case StatusCodes.MicrocontrollerError: + ShowErrorMessage(MultilingualHelper.getString("MicrocontrollerError"), loading); + return; + case StatusCodes.CameraNotConnected: + ShowErrorMessage(MultilingualHelper.getString("CameraNotConnected"), loading); + return; + } + _algorithmServer = new AlgorithmServer(); + // //图片集合 + string image_files = JsonConvert.SerializeObject(socResolt.Images, Formatting.Indented); + // string image_files =$"[ \"image_0.bmp\", \"image_1.bmp\", \"image_2.bmp\", \"image_3.bmp\", \"image_4.bmp\", \"image_5.bmp\", \"image_6.bmp\", \"image_7.bmp\", \"image_8.bmp\", \"image_9.bmp\", \"image_10.bmp\", \"image_11.bmp\", \"image_12.bmp\", \"image_13.bmp\", \"image_14.bmp\", \"image_15.bmp\", \"image_16.bmp\", \"image_17.bmp\", \"image_18.bmp\", \"image_19.bmp\", \"image_20.bmp\", \"image_21.bmp\", \"image_22.bmp\", \"image_23.bmp\", \"image_24.bmp\", \"image_25.bmp\", \"image_26.bmp\", \"image_27.bmp\", \"image_28.bmp\", \"image_29.bmp\", \"image_30.bmp\", \"image_31.bmp\", \"image_32.bmp\", \"image_33.bmp\", \"image_34.bmp\", \"image_35.bmp\", \"image_36.bmp\", \"image_37.bmp\", \"image_38.bmp\", \"image_39.bmp\", \"image_40.bmp\", \"image_41.bmp\", \"image_42.bmp\", \"image_43.bmp\", \"image_44.bmp\", \"image_45.bmp\", \"image_46.bmp\", \"image_47.bmp\", \"image_48.bmp\", \"image_49.bmp\", \"image_50.bmp\", \"image_51.bmp\", \"image_52.bmp\", \"image_53.bmp\", \"image_54.bmp\", \"image_55.bmp\", \"image_56.bmp\", \"image_57.bmp\", \"image_58.bmp\", \"image_59.bmp\", \"image_60.bmp\", \"image_61.bmp\", \"image_62.bmp\", \"image_63.bmp\", \"image_64.bmp\", \"image_65.bmp\", \"image_66.bmp\", \"image_67.bmp\", \"image_68.bmp\", \"image_69.bmp\", \"image_70.bmp\", \"image_71.bmp\", \"image_72.bmp\", \"image_73.bmp\", \"image_74.bmp\", \"image_75.bmp\", \"image_76.bmp\", \"image_77.bmp\", \"image_78.bmp\", \"image_79.bmp\", \"image_80.bmp\", \"image_81.bmp\", \"image_82.bmp\", \"image_83.bmp\", \"image_84.bmp\", \"image_85.bmp\", \"image_86.bmp\", \"image_87.bmp\", \"image_88.bmp\", \"image_89.bmp\", \"image_90.bmp\", \"image_91.bmp\", \"image_92.bmp\", \"image_93.bmp\", \"image_94.bmp\", \"image_95.bmp\", \"image_96.bmp\", \"image_97.bmp\", \"image_98.bmp\", \"image_99.bmp\"]" ; + + // 保存图片到历史记录文件夹 + HandleAlgorithmFailure(image_files, DiamondCode); + + + // 启动算法 + parameter = _algorithmServer.CallParseJsonAndReturnActions(parameter.Shape, parameter.CrownType, image_files); + //机器号 + parameter.DeviceId = socResolt.DeviceId; + switch (parameter.status) + { + case StatusCodes.AlgorithmFailed: + ShowErrorMessage(MultilingualHelper.getString("AlgorithmFailed"), loading); + return; + case StatusCodes.ImageFileReadFailure: + ShowErrorMessage(MultilingualHelper.getString("ImageFileReadFailure"), loading); + return; + case StatusCodes.JsonParseFailure: + ShowErrorMessage(MultilingualHelper.getString("JsonParseFailure"), loading); + return; + case StatusCodes.NoDiamond: + ShowErrorMessage(MultilingualHelper.getString("NoDiamond"), loading); + return; + } + parameter.Standard = getStandardName(); + parameter.Shape = value.Split(" ")[0]; + parameter.CrownType = value.Split(" ")[1]; + parameter.PavType = value.Split(" ")[2]; + parameter.DiamondCode = DiamondCode; + + if (!parameter.status.Equals(StatusCodes.Ok)) + parameter.error_msg = MultilingualHelper.getString(StatusCodes.GetConstantNameByValue(parameter.status)); + //参数实体转json输出 + try + { + string parameterJson = JsonConvert.SerializeObject(parameter); + parameterJson = JToken.Parse(parameterJson).ToString(); + string outputPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "logs", "result"); + if (!Directory.Exists(outputPath)) + Directory.CreateDirectory(outputPath); + string outputFilePath = $"{outputPath}/{DiamondCode}-{DateTime.Now:yyyyMMdd_HHmmss}.json"; + using (var file = File.Create(outputFilePath)) + using (StreamWriter stream = new StreamWriter(file)) + { + stream.Write(parameterJson); + } + } + catch (Exception ex) + { + Logger.Error("output输出失败:"+ex.Message); + } + + isEnd = true; + //GradingResult(parameter); + await loading.Dispatcher.Invoke(async () => + { + for (int i = progress; progress <= 100; i++) + { + Random random = new Random(); int minValue = 20; int maxValue = 100; // 生成50到150之间的随机整数 + int randomNumber = random.Next(minValue, maxValue + 1); + await Task.Delay(randomNumber); + loading.setValue(i); + if (loading.ProgressBar.Value == 98) + { + GradingResult(parameter); + } + if(loading.ProgressBar.Value >= 100) + { + + loading.Close(); + break; + } + } + // 检测到钻石需进行清洁 + if (parameter.status == StatusCodes.Recheck) + { + ShowErrorMessage(MultilingualHelper.getString("Recheck"), loading); + } + + }); + }); + } + } + catch (DirectoryNotFoundException ex) + { + loading.Close(); + new MessageBox().Show(MultilingualHelper.getString("SavePathIsnotExists")); + } + catch (IOException ex) + { + loading.Close(); + new MessageBox().Show($"{MultilingualHelper.getString("FileOpened")}:{ex.Message}"); + } + finally { + + } +**/ } [Log] diff --git a/ViewModel/Grading/GradingLoadingVM.cs b/ViewModel/Grading/GradingLoadingVM.cs index bd65506..dea6658 100644 --- a/ViewModel/Grading/GradingLoadingVM.cs +++ b/ViewModel/Grading/GradingLoadingVM.cs @@ -1,11 +1,21 @@ +using System.Configuration; +using System.Data; using System.IO; +using System.Windows; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using SparkClient.Model.Common; +using SparkClient.Model.Entity.ApiEntity; using SparkClient.Model.Helper; using SparkClient.Model.Services; -using SparkClient.Views.Dialog; +using SparkClient.ViewModel.BaseWindow; +using SparkClient.ViewModel.Configuration; +using SparkDotNetCore.DiamondScanner; +using SparkDotNetCore.DiamondScanner.Entity; +using MessageBox = SparkClient.Views.Dialog.MessageBox; namespace SparkClient.ViewModel.Grading; @@ -13,7 +23,7 @@ public class GradingLoadingVM : BaseViewModel,IDisposable { private double _progress; private SOCClientService _socClientService; - + public AlgorithmResultEntity Parameter; /// /// 进度 /// @@ -38,6 +48,10 @@ public class GradingLoadingVM : BaseViewModel,IDisposable private CancellationTokenSource _progressCts; private CancellationTokenSource? _playbackCts; + private Diamond _diamond; + private Scanner _scanner; + private CancellationTokenSource _completionCts; + #region 图片播放控制 private PlayStatus _currentStatus = PlayStatus.Stopped; public PlayStatus CurrentStatus @@ -57,7 +71,7 @@ public class GradingLoadingVM : BaseViewModel,IDisposable _ => "重播" // Stopped 状态 }; private CancellationTokenSource _cts; - private int _playDelay = 200; // 默认播放速度 + private int _playDelay = 100; // 默认播放速度 public ICommand PlayControlCommand { get; } public ICommand PreviousCommand { get; } @@ -76,10 +90,27 @@ public class GradingLoadingVM : BaseViewModel,IDisposable } public string[] ImagePaths { get; set; } - public ImageSource CurrentImage { get; private set; } - - public bool ImageIsEnable { get; private set; } + private ImageSource _currentImage; + public ImageSource CurrentImage + { + get => _currentImage; + private set + { + _currentImage = value; + OnPropertyChanged(nameof(CurrentImage)); + } + } + private bool _imageIsEnable; + public bool ImageIsEnable + { + get => _imageIsEnable; + private set + { + _imageIsEnable = value; + OnPropertyChanged(nameof(ImageIsEnable)); // 触发通知 + } + } #endregion public GradingLoadingVM(string diamnondType, string diamondCode) @@ -94,52 +125,213 @@ public class GradingLoadingVM : BaseViewModel,IDisposable _progressCts = new CancellationTokenSource(); _playbackCts = new CancellationTokenSource(); + _completionCts = new CancellationTokenSource(); } /// /// 开始检测 /// - public async Task Start() + public async Task Start(int type = 0) { - //开始显示进度条 - //切工仪通讯 拉取图片 延时...5秒 - //播放图片 - //图片拉取完毕---| - // var configValue = ConfigurationHelper.ReadConfigValue("ProgressTime"); - // int iProgTime = int.TryParse(configValue, out var result) ? result : 50000; - // int stepTime = iProgTime / 97; - // - // for (int i = 0; i <= 97; i++) - // { - // _progressCts.Token.ThrowIfCancellationRequested(); - // Progress = i; - // await Task.Delay(stepTime, _progressCts.Token); - // } - var progress = RunProgressAsync(_progressCts.Token); - - _socClientService = new SOCClientService(); - var processImage = _socClientService.ProcessImageCollectionAsync(); - //通知页面可以播放图片 - await processImage; - - if (!"ok".Equals(processImage.Result.Status)) + + try { - _progressCts.Cancel(); - new MessageBox().Show(MultilingualHelper.getString(StatusCodes.GetConstantNameByValue(processImage.Result.Status))); - return -1; + + var progress = RunProgressAsync(_progressCts.Token); + if(type == 0){ + _socClientService = new SOCClientService(); + var processImage = _socClientService.ProcessImageCollectionAsync(); + //通知页面可以播放图片 + await processImage; + + if (!("ok".Equals(processImage.Result.Status) || "S000".Equals(processImage.Result.Status))) + { + _progressCts.Cancel(); + new MessageBox().Show( + MultilingualHelper.getString(StatusCodes.GetConstantNameByValue(processImage.Result.Status))); + return -1; + } + LoadImages(processImage.Result.Images); + } + + if (type == 1) + { + List mnFiles = new List(); + for (int i = 0; i < 100; i++) + { + mnFiles.Add($"{i}.bmp"); + } + LoadImages(mnFiles); + } + + ImageIsEnable = true; + StartPlayback(); + + + Diamond diamond = new Diamond(); + string circleSql = $"SELECT VALUE FROM CUTTER_CONFIG WHERE KEY = 'half_circle'"; + DataTable circleTable = DataBaseHelper.ExecuteQuery(circleSql); + object halfCircleValue = circleTable.Rows[0][0]; + bool.TryParse(halfCircleValue.ToString(), out bool boolResult); + bool half_circle = boolResult; + + //算法配置参数,初始化算法配置数据并获取 AlgorithmConfigJson + var _algorithmConfigVM = new AlgorithmConfigVM(); + _algorithmConfigVM.InitAlgorithmData(null); + string algo_config = _algorithmConfigVM.AlgorithmConfigJson; + + + //图片根目录 + string? image_file_base_path = ConfigurationManager.AppSettings["ImageFileBasePath"]; + if (string.IsNullOrEmpty(image_file_base_path)) + { + throw new InvalidOperationException("ImageFileBasePath is not configured in AppSettings."); + } + + // 获取 log4net 日志文件所在的目录 + string? log4NetLogDirectory = + Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); + // 构建C++ DLL 日志文件路径 + string algorithm_log_path = Path.Combine(log4NetLogDirectory, "logs"); + + // 将所有变量拼接成一个 JSON 对象 + JObject jsonData = new JObject( + new JProperty("shape", _diamnondType.Split(" ")[0]), + new JProperty("shape_mode", _diamnondType.Split(" ")[1]), + new JProperty("image_file_base_path", image_file_base_path), + new JProperty("image_files", ImagePaths), + new JProperty("half_circle", half_circle), + new JProperty("algorithm_log_path", algorithm_log_path), + new JProperty("algo_config", JObject.Parse(algo_config)) + ); + _scanner = new Scanner(diamond); + var detectTask = _scanner.DetectAsyncByJsonStr(jsonData.ToString()); + + await detectTask; + if (detectTask.Status == TaskStatus.RanToCompletion) + { + return ReslutGen(detectTask); + } + await progress; + return ReslutGen(detectTask); + } + catch(Exception ex) + { + return -100; } + } + + private int ReslutGen(Task detectTask) + { + + CompleteProgressQuicklyAsync(); - LoadImages(processImage.Result.Images); - ImageIsEnable = true; + switch (detectTask.Result.Status) + { + case StatusCodes.AlgorithmFailed: + new MessageBox().Show(MultilingualHelper.getString("AlgorithmFailed")); + return -1; + case StatusCodes.ImageFileReadFailure: + new MessageBox().Show(MultilingualHelper.getString("ImageFileReadFailure")); + return -1; + case StatusCodes.JsonParseFailure: + new MessageBox().Show(MultilingualHelper.getString("JsonParseFailure")); + return -1; + case StatusCodes.NoDiamond: + new MessageBox().Show(MultilingualHelper.getString("NoDiamond")); + return -1; + } + + Progress = 100; - await progress; - return 0; + string strParam = JsonConvert.SerializeObject(detectTask.Result); + AlgorithmResultEntity parameter = JsonConvert.DeserializeObject(strParam); + if (parameter == null) + { + new MessageBox().Show(MultilingualHelper.getString("JsonParseFailure")); + return -1; + } + + try + { + string parameterJson = JsonConvert.SerializeObject(parameter); + parameterJson = JToken.Parse(parameterJson).ToString(); + string outputPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "logs", "result"); + if (!Directory.Exists(outputPath)) + Directory.CreateDirectory(outputPath); + string outputFilePath = $"{outputPath}/{_diamondCode}-{DateTime.Now:yyyyMMdd_HHmmss}.json"; + using (var file = File.Create(outputFilePath)) + using (StreamWriter stream = new StreamWriter(file)) + { + stream.Write(parameterJson); + } + } + catch (Exception ex) + { + Logger.Error("output输出失败:" + ex.Message); + } + + Parameter = parameter; + return 0; + } + + private async Task CompleteProgressSlowlyAsync() + { + // 缓慢完成剩余3%(总耗时保持原速度的3倍) + const int remainingSteps = 3; + int stepTime = 500; // 自定义慢速步长 + + int current = (int)Progress; + for (int i = 1; i <= remainingSteps; i++) + { + if (_progressCts.IsCancellationRequested) break; + UpdateProgress(current + i); + await Task.Delay(stepTime); + } } + private async Task CompleteProgressQuicklyAsync() + { + // 取消原进度任务 + _progressCts.Cancel(); + + // 快速完成剩余进度(0.5秒内完成) + int current = (int)Progress; + int remaining = 100 - current; + if (remaining <= 0) return; + + int stepTime = Math.Max(50, 500 / remaining); // 动态计算步长 + + while (current < 100) + { + current = Math.Min(current + 1, 100); + UpdateProgress(current); + await Task.Delay(stepTime); + } + } + private void UpdateProgress(int value) + { + // UI线程安全更新 + Application.Current.Dispatcher.Invoke(() => + { + Progress = value; + }); + } private void Stop(object param) { //询问?停止:忽略 + MessageBox messageBox = new MessageBox(); + MessageBoxResult showAsk = messageBox.ShowAsk("正在计算钻石数据,是否终止?"); + if (showAsk == MessageBoxResult.OK) + { + _scanner?.Cancel(); + _progressCts.Cancel(); + WindowManager.mainViewModel.Content = WindowManager.PreviousVM(); + this.Dispose(); + } + + } private async Task RunProgressAsync(CancellationToken token) @@ -263,13 +455,13 @@ public class GradingLoadingVM : BaseViewModel,IDisposable { if (ImagePaths == null || CurrentIndex < 0 || CurrentIndex >= ImagePaths.Length) return; - + string? savePath = ConfigurationManager.AppSettings["ImageFileBasePath"]; var bitmap = new BitmapImage(); bitmap.BeginInit(); bitmap.CacheOption = BitmapCacheOption.OnLoad; - bitmap.UriSource = new Uri(ImagePaths[CurrentIndex]); + bitmap.UriSource = new Uri(savePath + @"\" + ImagePaths[CurrentIndex]); bitmap.EndInit(); - bitmap.Freeze(); // 确保跨线程安全 + bitmap.Freeze(); // 确保跨线程安全# CurrentImage = bitmap; OnPropertyChanged(nameof(CurrentImage)); diff --git a/Views/BaseWindow/BaseControl.xaml.cs b/Views/BaseWindow/BaseControl.xaml.cs index 8122e72..6d12c7b 100644 --- a/Views/BaseWindow/BaseControl.xaml.cs +++ b/Views/BaseWindow/BaseControl.xaml.cs @@ -20,10 +20,20 @@ public partial class BaseControl FocusManager.SetFocusedElement(this, this); Keyboard.Focus(this); + string runModel = ConfigurationHelper.ReadConfigValue("RunModel"); + if ("0".Equals(runModel)) + //json模式 + runModel = " -【Json模式】"; + else if ("1".Equals(runModel)) + { + runModel = " -【Image模式】"; + } + else + { + runModel = string.Empty; + } - #if DEBUG - tbTitle.Text = tbTitle.Text + " -【测试版】"; - #endif + tbTitle.Text = tbTitle.Text + runModel; } private void Border_Minimize_MouseEnter(object sender, MouseEventArgs e) diff --git a/Views/Grading/GradingLoading.xaml b/Views/Grading/GradingLoading.xaml index 065665e..d4f6438 100644 --- a/Views/Grading/GradingLoading.xaml +++ b/Views/Grading/GradingLoading.xaml @@ -315,7 +315,7 @@ - + @@ -336,7 +336,7 @@ + TextAlignment="Center" FontSize="30" IsEnabled="False"/> @@ -355,7 +355,7 @@