using System.Configuration; using Newtonsoft.Json; using SparkClient.Model.Entity.ApiEntity; using SparkClient.Model.Helper; using SparkClient.ViewModel.BaseWindow; using SparkClient.Views.Dialog; using System.Data; using System.Windows; using System.Windows.Input; using System.Windows.Media.Imaging; using System.Windows.Threading; using SparkClient.Model.Entity; using SparkClient.Model.Services; using System.Text; using System.IO; using System.Windows.Media; using log4net; using Newtonsoft.Json.Linq; using SparkClient.Model.Common; using Color = System.Windows.Media.Color; using MessageBox = SparkClient.Views.Dialog.MessageBox; using SparkClient.Model.Attributes; namespace SparkClient.ViewModel.Grading; /// /// 钻石选择画面VM /// public class DiamondSelectVM : BaseViewModel { private SOCClientService _socClientService; private AlgorithmServer _algorithmServer; private AlgorithmConfigEntity _algorithmConfigEntity; private string DiamondCode { get; set; } private List _buttons; private List _buttons2; private ICommand ChangeDiamondTypeCommand; private ICommand StartGradingCommand; public List Buttons { get { return _buttons; } set { _buttons = value; OnPropertyChanged(nameof(Buttons)); } } public List Buttons2 { get { return _buttons2; } set { _buttons2 = value; OnPropertyChanged(nameof(Buttons2)); } } public DiamondSelectVM() { ChangeDiamondTypeCommand = new RelayCommand(ChangeDiamondType); StartGradingCommand = new RelayCommand(StartGrading); List tempButtons = new List(); List buttonInfos = GetButtonInfos(); foreach (var buttonInfo in buttonInfos) { var bitmap = new BitmapImage(new Uri("pack://application:,,,/Resource/Images/UIResource/" + buttonInfo.ImageName, UriKind.RelativeOrAbsolute)); ButtonViewModel button = new ButtonViewModel() { Text = buttonInfo.ButtonName, ImageSource = bitmap, Type = buttonInfo.Type, Command = ChangeDiamondTypeCommand ,IsEnabled= buttonInfo.IsEnabled, IsHighlighted = false}; tempButtons.Add(button); } Buttons = tempButtons; } /// /// 画面按钮添加 /// /// private List GetButtonInfos() { List buttonInfos = new List(); buttonInfos.Add(new ButtonInfo() { Type = "round", IsEnabled = true, ImageName = "round.png", ButtonName = MultilingualHelper.getString("圆形") }); buttonInfos.Add(new ButtonInfo() { Type = "Hexagon", IsEnabled = false, ImageName = "Hexagon.png", ButtonName = MultilingualHelper.getString("六边形") }); buttonInfos.Add(new ButtonInfo() { Type = "cushion", IsEnabled = false, ImageName = "Cushion.png", ButtonName = MultilingualHelper.getString("枕形") }); buttonInfos.Add(new ButtonInfo() { Type = "Pear", IsEnabled = false, ImageName = "Pear.png", ButtonName = MultilingualHelper.getString("梨形") }); buttonInfos.Add(new ButtonInfo() { Type = "Princess", IsEnabled = false, ImageName = "Princess.png", ButtonName = MultilingualHelper.getString("公主方形") }); buttonInfos.Add(new ButtonInfo() { Type = "oval", IsEnabled = false, ImageName = "oval.png", ButtonName = MultilingualHelper.getString("椭圆形") }); buttonInfos.Add(new ButtonInfo() { Type = "Emerald", IsEnabled = false, ImageName = "Emerald.png", ButtonName = MultilingualHelper.getString("祖母绿形") }); buttonInfos.Add(new ButtonInfo() { Type = "Odd", IsEnabled = false, ImageName = "Odd.png", ButtonName = MultilingualHelper.getString("异形钻") }); return buttonInfos; } /// /// 获取钻石列表 /// /// [Log] public void InitDiamondList(object param) { } /// /// 切换钻石类型(右侧列表) /// /// 钻石类型 [Log] public void ChangeDiamondType(object type) { if (type!= null) { foreach (var item in Buttons.Where(x => x.Type == type)) { item.IsHighlighted = true; }; List tempButtons2 = new List(); var bitmap = new BitmapImage(new Uri("pack://application:,,,/Resource/Images/UIResource/round_P8-P8.png", UriKind.RelativeOrAbsolute)); ButtonViewModel button = new ButtonViewModel() { Text = "P8-P8", ImageSource = bitmap, Type = "ROUND P8 P8", Command = StartGradingCommand, IsFocused = true}; tempButtons2.Add(button); Buttons2 = tempButtons2; } } /// /// 开始检测(对soc和算法开始通讯) /// /// [Log] public async void StartGrading(object param) { MessageBox messageBox = new MessageBox(); MessageBoxResult result = messageBox.ShowInput($"{MultilingualHelper.getString("UpdateDiamondCode")}", out string inputStr, MultilingualHelper.getString("ok"), MultilingualHelper.getString("Skip") ); if (result == MessageBoxResult.None) { return; } if (result == MessageBoxResult.OK) { DiamondCode = inputStr.Trim(); } else { DiamondCode = ""; } #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); } 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 { } #endif } [Log] private string getStandardName() { string sql = $"select\r\nRULE_NAME AS NAME,\r\nRULE_EN_NAME AS EN_NAME\r\nfrom\r\nsetting\r\nleft join rule\r\non setting.SETTING_P = rule.RULE_ID\r\nwhere\r\nsetting.SETTING_ID = 'RuleId'\r\n"; DataTable dataTable = DataBaseHelper.ExecuteQuery(sql); if (dataTable == null || dataTable.Rows.Count == 0) { return ""; } else { return dataTable.Rows[0][MultilingualHelper.getString("NameType")].ToString()??""; } } // 将 UI 操作调度到主线程并显示错误信息 void ShowErrorMessage(string errorMessage, LoadingDialog loading) { Application.Current.Dispatcher.Invoke(() => { loading.Close(); new MessageBox().Show(errorMessage); // MessageBox msgDialog = // // msgDialog.ErrorMessage = errorMessage; // msgDialog.ShowDialog(); }); //loading.Dispatcher.Invoke(() => loading.Close()); } /// /// 开始检测(对soc和算法开始通讯) /// /// [Log] public async void DoStartGrading(object param) { LoadingDialog loading = new LoadingDialog(DiamondCode); try { if (param != null) { AlgorithmResultEntity parameter = new AlgorithmResultEntity(); JsonImport jsonImport = new JsonImport(); //jsonImport.FilePath.Text = "D:\\项目\\TEST240.json"; bool? a = jsonImport.ShowDialog(); if (a ?? false) { string fileName = jsonImport.FilePath.Text; string[] lines = File.ReadAllLines(fileName); StringBuilder stringBuilder = new StringBuilder(); foreach (var line in lines) { stringBuilder.Append(line); } parameter = JsonConvert.DeserializeObject(stringBuilder.ToString()); } else { return; } var tcs = new TaskCompletionSource(); var progressTask = Task.Run(() => Application.Current.Dispatcher.Invoke(() => { loading.Closed += (s, e) => tcs.SetResult(true); loading.ShowDialog(); } )); await Task.Run(async () => { for (int i = 0; i <= 100; i++) { // 模拟耗时操作 //System.Threading.Thread.Sleep(50); // 休眠50毫秒 await Task.Delay(5); // 更新进度条的值(需要在UI线程上执行) loading.Dispatcher.Invoke(() => { loading.setValue(i); }); } // SocResultEntity socResolt = new SocResultEntity(); // AlgorithmResultEntity parameter = new AlgorithmResultEntity(); // // 启动soc // socResolt = DoSoc(); // // 启动算法 // parameter = DoAlgorithm(); //parameter = DoSoc(); parameter.Standard = getStandardName(); 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]; } parameter.DiamondCode = DiamondCode; GradingResult(parameter); }); await Task.Delay(5); loading.Close(); } } catch (DirectoryNotFoundException ex) { loading.Close(); new MessageBox().Show(MultilingualHelper.getString("SavePathIsnotExists")); } catch (IOException ex) { loading.Close(); new MessageBox().Show($"{MultilingualHelper.getString("FileOpened")}:{ex.Message}"); } catch (Exception ex) { new MessageBox().Show($"{MultilingualHelper.getString("ApplicationError")}{ex.Message}"); Logger.Error($"全局异常捕获:{ex.Message}", ex); } } /// /// 处理算法调用失败时的逻辑,包括保存图片到历史记录文件夹 /// /// 图片文件路径的 JSON 字符串 /// private static readonly ILog Logger = LogManager.GetLogger(typeof(AlgorithmServer)); [Log] private void HandleAlgorithmFailure(string image_files, string dCode = "") { // 从配置文件中读取 imageHistoryPath // 定义历史记录文件夹路径 string? imageHistoryPath = ConfigurationManager.AppSettings["ImageHistoryPath"]; if (string.IsNullOrEmpty(imageHistoryPath)) { Logger.Error("ImageHistoryPath is not configured in AppSettings."); return; } // 生成时间戳,格式为 yyyyMMddHHmmss string timestamp = DateTime.Now.ToString("yyyyMMdd-HHmmss"); // 组合新的文件夹路径 string newFolderPath = Path.Combine(imageHistoryPath, string.IsNullOrWhiteSpace(dCode) ? $"image-{timestamp}" : $"image-{dCode}-{timestamp}" ); // 检查 D 盘内存空间 DriveInfo dDrive = new DriveInfo("D"); long requiredSpace = 10L * 1024 * 1024 * 1024; // 10GB if (dDrive.TotalFreeSpace < requiredSpace) { // 如果 D 盘空间不足 10GB,删除最早创建的10个文件夹 DirectoryInfo historyDir = new DirectoryInfo(imageHistoryPath); // 获取历史记录文件夹的信息 DirectoryInfo[] subDirs = historyDir.GetDirectories(); // 获取历史记录文件夹中的所有子文件夹 if (subDirs.Length > 0) { // 按创建时间排序子文件夹 var orderedSubDirs = subDirs.OrderBy(d => d.CreationTime).ToList(); int foldersToDelete = Math.Min(10, orderedSubDirs.Count); // 删除最早的 10 个文件夹,如果不够 10 个则全删掉 for (int i = 0; i < foldersToDelete; i++) { orderedSubDirs[i].Delete(true); } } } // 创建新文件夹 Directory.CreateDirectory(newFolderPath); // 保存图片到新文件夹 try { // 解析 image_files JSON 数组 JArray imageFilesArray = JArray.Parse(image_files); string[] imageFiles = imageFilesArray.Select(token => token.ToString()).ToArray(); string? imageBasePath = ConfigurationManager.AppSettings["ImageFileBasePath"]; // 图片根目录 if (string.IsNullOrEmpty(imageBasePath)) { Logger.Error("ImageFileBasePath is not configured in AppSettings."); return; } foreach (string imageFile in imageFiles) { // 获取文件名 string fileName = Path.GetFileName(imageFile); // 构建完整的源文件路径 string sourcePath = Path.Combine(imageBasePath, imageFile); // 组合目标路径 string destinationPath = Path.Combine(newFolderPath, fileName); // 复制文件到目标路径,如果目标文件已存在则覆盖 File.Copy(sourcePath, destinationPath, true); } } catch (JsonException ex) { // 记录日志或处理异常 Logger.Error($"Error parsing image_files JSON: {ex.Message}"); Logger.Error($"Stack Trace: {ex.StackTrace}"); } catch (Exception ex) { // 记录其他异常 Logger.Error($"Error saving images: {ex.Message}"); Logger.Error($"Stack Trace: {ex.StackTrace}"); } } /// /// 跳转至检测结果 /// /// [Log] public void GradingResult(AlgorithmResultEntity param) { try { //WindowManager.mainViewModel.Content = WindowManager.PreviousVM(); 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)"; vm.ShowFunctionButton = System.Windows.Visibility.Visible; WindowManager.mainViewModel.Content = vm; WindowManager.openContent.Add(vm); } catch (IOException) { throw; } } } public class ButtonInfo { public string Type { get; set; } public string ImageName { get; set; } public string ButtonName { get; set; } public bool IsEnabled { get; set; } } public class ButtonViewModel : BaseViewModel { private string _text; private BitmapImage _imageSource; private ICommand _command; private string _type; private int _col; private bool _isEnabled; private bool _isHighlighted; private Brush _foreground; private Brush _background; private bool _isFocused; public string Text { get { return _text; } set { _text = value; OnPropertyChanged(nameof(Text)); } } public BitmapImage ImageSource { get { return _imageSource; } set { _imageSource = value; OnPropertyChanged(nameof(ImageSource)); } } public ICommand Command { get { return _command; } set { _command = value; OnPropertyChanged(nameof(Command)); } } public string Type { get { return _type; } set { _type = value; OnPropertyChanged(nameof(Type)); } } public int Column { get { return _col; } set { _col = value; OnPropertyChanged(nameof(Column)); } } public bool IsEnabled { get { return _isEnabled; } set { _isEnabled = value; OnPropertyChanged(nameof(IsEnabled)); } } public bool IsHighlighted { get { return _isHighlighted; } set { _isHighlighted = value; OnPropertyChanged(nameof(IsHighlighted)); UpdateStyles(); } } public Brush ForegroundColor { get { return _foreground; } set { _foreground = value; OnPropertyChanged(nameof(ForegroundColor)); } } public Brush BackgroundColor { get { return _background; } set { _background = value; OnPropertyChanged(nameof(BackgroundColor)); } } public bool IsFocused { get { return _isFocused; } set { _isFocused = value; OnPropertyChanged(nameof(IsFocused)); } } [Log] private void UpdateStyles() { if (IsHighlighted) { // 高亮状态的样式 LinearGradientBrush linearGradientBrush = new LinearGradientBrush( new GradientStopCollection() { new GradientStop(Color.FromRgb(64, 177, 255), 0), // #61bde2 new GradientStop(Color.FromRgb(60, 156, 230), 1) // #53abd9 }, new Point(0, 0), // StartPoint new Point(0, 1) // EndPoint ); BackgroundColor = linearGradientBrush; ForegroundColor = new SolidColorBrush(Color.FromRgb(255, 255, 255)); string path = _imageSource.UriSource.AbsolutePath; if (!path.Contains("_select.png")) { path = path.Replace(".png", "_select.png"); } ImageSource = new BitmapImage(new Uri("pack://application:,,," + path)); } else { // 默认状态的样式 BackgroundColor = new SolidColorBrush(Color.FromRgb(235, 238, 245)); ForegroundColor = Brushes.Black; string path = _imageSource.UriSource.AbsolutePath.Replace("_select.png", ".png"); ImageSource = new BitmapImage(new Uri("pack://application:,,," + path)); } } }