diff --git a/App.xaml.cs b/App.xaml.cs index 532adfa..6de3409 100644 --- a/App.xaml.cs +++ b/App.xaml.cs @@ -25,7 +25,7 @@ public partial class App : Application //打开数据库连接 //读取数据库多语言配置 DataBaseHelper.CreateConnection(); - string LanguageId = Settings.SelectValueByName("LanguageId"); + string LanguageId = Settings.SelectValueById("LanguageId"); if (LanguageId.Length == 0) { LanguageId = "zh-cn"; diff --git a/Language/zh_CN.xaml b/Language/zh_CN.xaml index f0df0bc..48a2bf1 100644 --- a/Language/zh_CN.xaml +++ b/Language/zh_CN.xaml @@ -191,7 +191,7 @@ P004:JSON解析失败 P021:检测到钻石需进行清洁 P011:未检测到钻石 - 请检查切工仪设备舱门是否关闭 + S007:请检查切工仪设备舱门是否关闭 应用程序出现错误: diff --git a/LoginWindow.xaml.cs b/LoginWindow.xaml.cs index 4d30970..a1683a7 100644 --- a/LoginWindow.xaml.cs +++ b/LoginWindow.xaml.cs @@ -15,8 +15,8 @@ public partial class LoginWindow : Window { InitializeComponent(); WindowStartupLocation = WindowStartupLocation.CenterScreen; - AccountTextBox.Text = Settings.SelectValueByName("SAVE_ACCOUNT"); - PasswordBox.Password = Settings.SelectValueByName("SAVE_PASSWORD"); + AccountTextBox.Text = Settings.SelectValueById("SAVE_ACCOUNT"); + PasswordBox.Password = Settings.SelectValueById("SAVE_PASSWORD"); checkCUDA(); // 检测MSVCRuntime是否安装 checkMSVCRuntime(); diff --git a/Model/Entity/ApiEntity/StatusCodes.cs b/Model/Entity/ApiEntity/StatusCodes.cs index 411f8d8..24f3c97 100644 --- a/Model/Entity/ApiEntity/StatusCodes.cs +++ b/Model/Entity/ApiEntity/StatusCodes.cs @@ -5,6 +5,8 @@ /// public static class StatusCodes { + // 成功 + public const string Ok = "ok"; // 成功 public const string Success = "S000"; diff --git a/Model/Entity/JsonEntity.cs b/Model/Entity/JsonEntity.cs index a0464bc..393f991 100644 --- a/Model/Entity/JsonEntity.cs +++ b/Model/Entity/JsonEntity.cs @@ -10,6 +10,9 @@ using System.Windows.Shapes; namespace EncryptFileTool.Entity { + /// + /// 定级配置导入数据 + /// public class JsonEntity { public string SHAPE_ID { get; set; } diff --git a/Model/Services/AlgorithmServer.cs b/Model/Services/AlgorithmServer.cs index 90d46a7..8d2569c 100644 --- a/Model/Services/AlgorithmServer.cs +++ b/Model/Services/AlgorithmServer.cs @@ -33,7 +33,7 @@ namespace SparkClient.Model.Services object halfCircleValue = circleTable.Rows[0][0]; bool.TryParse(halfCircleValue.ToString(), out bool boolResult); bool half_circle = boolResult; - + //算法配置参数 string sql = $"SELECT JSON FROM ALGORITHM_CONFIG ORDER BY JSON_ORDER ASC"; DataTable table = DataBaseHelper.ExecuteQuery(sql); @@ -43,6 +43,11 @@ namespace SparkClient.Model.Services //图片根目录 string? image_file_base_path = ConfigurationManager.AppSettings["ImageFileBasePath"]; + // 获取 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", shape), @@ -50,13 +55,12 @@ namespace SparkClient.Model.Services new JProperty("image_file_base_path", image_file_base_path), new JProperty("image_files", JToken.Parse(image_files)), new JProperty("half_circle", half_circle), + new JProperty("algorithm_log_path", algorithm_log_path), new JProperty("algo_config", JObject.Parse(algo_config)) ); - string jsonDataString = jsonData.ToString(); // 调用 C++ DLL 函数解析 JSON IntPtr resultPtr = DetectDiamond(jsonDataString); - string resultJson = Marshal.PtrToStringAnsi(resultPtr); // 释放 DLL 分配的内存 FreeString(resultPtr); @@ -71,7 +75,6 @@ namespace SparkClient.Model.Services measurements = new Measurements() }; } - // 反序列化 JSON 字符串为 AlgorithmResultEntity 对象 var result = JsonConvert.DeserializeObject(resultJson); @@ -85,73 +88,17 @@ namespace SparkClient.Model.Services measurements = new Measurements() }; } - + // 记录算法失败的状态 + Logger.Error($"Algorithm failed with status: {result.status}"); + // 记录算法失败的错误信息 + Logger.Error($"Algorithm failed with errorMsg: {result.error_msg}"); + // 处理 C++ DLL 日志文件 + //ProcessDllLog(); // 算法调用失败时,保存图片到历史记录文件夹 - if (result.status == StatusCodes.AlgorithmFailed) - { - // 从配置文件中读取 imageHistoryPath - // 定义历史记录文件夹路径 - string? imageHistoryPath = ConfigurationManager.AppSettings["ImageHistoryPath"]; - // 生成时间戳,格式为 yyyyMMddHHmmss - string timestamp = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss"); - // 组合新的文件夹路径 - string newFolderPath = Path.Combine(imageHistoryPath, $"image-{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"];// 图片根目录 - - 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}"); - } - } - - + // if (result.status == StatusCodes.AlgorithmFailed) + // { + // HandleAlgorithmFailure(image_files); + // } return result; } catch (Exception ex) @@ -173,6 +120,154 @@ namespace SparkClient.Model.Services }; } } + + /// + /// 处理算法调用失败时的逻辑,包括保存图片到历史记录文件夹 + /// + /// 图片文件路径的 JSON 字符串 + private void HandleAlgorithmFailure(string image_files) + { + + // 从配置文件中读取 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("yyyy-MM-dd-HH-mm-ss"); + // 组合新的文件夹路径 + string newFolderPath = Path.Combine(imageHistoryPath, $"image-{timestamp}"); + + // 检查 D 盘内存空间 + DriveInfo dDrive = new DriveInfo("D"); + long requiredSpace = 1000L * 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}"); + } + } + + /// + /// 处理 C++ DLL 的日志文件,将其复制到 log4net 日志目录下的 logs 文件夹,并记录其内容到日志中 + /// + private void ProcessDllLog() + { + try + { + // 获取系统临时目录路径(TMP 或 TEMP 环境变量) + string? tempDirectory = Environment.GetEnvironmentVariable("TMP") ?? Environment.GetEnvironmentVariable("TEMP"); + if (tempDirectory != null) + { + // 构建搜索模式 + string searchPattern = "*diamond_cut_inspector*"; + // 获取所有匹配的文件 + string[] logFiles = Directory.GetFiles(tempDirectory, searchPattern, SearchOption.TopDirectoryOnly); + if (logFiles.Length > 0) + { + // 找到最新的日志文件 + string latestLogFile = logFiles.OrderByDescending(file => new FileInfo(file).LastWriteTime).First(); + // 获取 log4net 日志文件所在的目录 + string log4netLogDirectory = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); + if (log4netLogDirectory != null) + { + // 构建 logs 目录路径 + string logsDirectory = Path.Combine(log4netLogDirectory, "logs"); + // 确保 logs 目录存在 + Directory.CreateDirectory(logsDirectory); + // 构建目标文件路径 + string targetFilePath = Path.Combine(logsDirectory, Path.GetFileName(latestLogFile)); + // 复制最新日志文件到 logs 目录 + File.Copy(latestLogFile, targetFilePath, true); + // 读取复制后的日志文件的内容 + string dllLogContent = File.ReadAllText(targetFilePath); + // 记录 C++ DLL 日志文件的内容到日志中 + Logger.Error("C++ DLL Log Content:"); + Logger.Error(dllLogContent); + } + else + { + Logger.Error("Unable to determine the log4net log directory."); + } + } + else + { + // 如果没有找到匹配的日志文件,记录错误信息 + Logger.Error("No C++ DLL log files found matching the pattern '*diamond_cut_inspector*.log'."); + } + } + else + { + // 如果无法获取临时目录路径,记录错误信息 + Logger.Error("Unable to determine the temporary directory path."); + } + } + catch (Exception ex) + { + // 记录读取或复制日志文件时的异常 + Logger.Error($"Error processing C++ DLL log file: {ex.Message}"); + Logger.Error($"Stack Trace: {ex.StackTrace}"); + } + } } } diff --git a/SparkClient.csproj b/SparkClient.csproj index 429e771..999d941 100644 --- a/SparkClient.csproj +++ b/SparkClient.csproj @@ -52,9 +52,9 @@ - + Always - + diff --git a/SparkClient.sln.DotSettings.user b/SparkClient.sln.DotSettings.user index 5990b75..ebbda40 100644 --- a/SparkClient.sln.DotSettings.user +++ b/SparkClient.sln.DotSettings.user @@ -57,6 +57,7 @@ ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded diff --git a/SparkDB.db b/SparkDB.db index 6b845ec..f7c0790 100644 Binary files a/SparkDB.db and b/SparkDB.db differ diff --git a/ViewModel/BaseWindow/BaseControlVM.cs b/ViewModel/BaseWindow/BaseControlVM.cs index f8dfdb7..bc874a5 100644 --- a/ViewModel/BaseWindow/BaseControlVM.cs +++ b/ViewModel/BaseWindow/BaseControlVM.cs @@ -64,11 +64,17 @@ public class BaseControlVM : BaseViewModel { if(Content is GradingResultVM) { - MessageBox message = new MessageBox(); - MessageBoxResult result = message.ShowAsk(MultilingualHelper.getString("DiamodResultCloseConfirm")); - if (MessageBoxResult.OK.Equals(result)) - { + bool isSaved = (Content as GradingResultVM).isSaved; + if (isSaved) { WindowManager.mainViewModel.Content = WindowManager.PreviousVM(); + } + else { + MessageBox message = new MessageBox(); + MessageBoxResult result = message.ShowAsk(MultilingualHelper.getString("DiamodResultCloseConfirm")); + if (MessageBoxResult.OK.Equals(result)) + { + WindowManager.mainViewModel.Content = WindowManager.PreviousVM(); + } } } else diff --git a/ViewModel/Configuration/AlgorithmConfigVM.cs b/ViewModel/Configuration/AlgorithmConfigVM.cs index a8f0ca1..a35a5b2 100644 --- a/ViewModel/Configuration/AlgorithmConfigVM.cs +++ b/ViewModel/Configuration/AlgorithmConfigVM.cs @@ -122,7 +122,7 @@ public class AlgorithmConfigVM : BaseViewModel } } private void IsEnabledByRole (){ - string PERMISSIONS = Settings.SelectValueByName("PERMISSIONS"); + string PERMISSIONS = Settings.SelectValueById("PERMISSIONS"); if ("admin".Equals(PERMISSIONS)) { IsEnabled = true; diff --git a/ViewModel/Configuration/CutConfigVM.cs b/ViewModel/Configuration/CutConfigVM.cs index 59118fb..ec59a0d 100644 --- a/ViewModel/Configuration/CutConfigVM.cs +++ b/ViewModel/Configuration/CutConfigVM.cs @@ -147,7 +147,7 @@ public class CutConfigVM: BaseViewModel } private void IsEnabledByRole() { - string PERMISSIONS = Settings.SelectValueByName("PERMISSIONS"); + string PERMISSIONS = Settings.SelectValueById("PERMISSIONS"); if ("admin".Equals(PERMISSIONS)) { IsEnabled = true; diff --git a/ViewModel/Configuration/SettingsPages/ModelColorSetPageVM.cs b/ViewModel/Configuration/SettingsPages/ModelColorSetPageVM.cs index 540eace..f182cda 100644 --- a/ViewModel/Configuration/SettingsPages/ModelColorSetPageVM.cs +++ b/ViewModel/Configuration/SettingsPages/ModelColorSetPageVM.cs @@ -1,9 +1,14 @@ +using log4net; using SparkClient.Model.Helper; +using SparkClient.ViewModel.Grading; namespace SparkClient.ViewModel.Configuration.SettingsPages; - +/// +/// 系统配置中颜色配置页面VM +/// public class ModelColorSetPageVM : BaseViewModel { + private static readonly ILog Logger = LogManager.GetLogger(typeof(ModelColorSetPageVM)); private string _FACET_COLOR; private string _BORDER_COLOR; private string _SELECTED_FACET_COLOR; @@ -21,22 +26,73 @@ public class ModelColorSetPageVM : BaseViewModel private string _PAVILION_MAIN_FACET_COLOR; private string _LOWER_GIRDLE_FACET_COLOR; private string _CULET_COLOR; + /// + /// 面部颜色 + /// public string FACET_COLOR { get { return _FACET_COLOR; } set { _FACET_COLOR = value; OnPropertyChanged(nameof(FACET_COLOR)); } } + /// + /// 边框颜色 + /// public string BORDER_COLOR { get { return _BORDER_COLOR; } set { _BORDER_COLOR = value; OnPropertyChanged(nameof(BORDER_COLOR)); } } + /// + /// 选中面颜色 + /// public string SELECTED_FACET_COLOR { get { return _SELECTED_FACET_COLOR; } set { _SELECTED_FACET_COLOR = value; OnPropertyChanged(nameof(SELECTED_FACET_COLOR)); } } + /// + /// 选中面边框颜色 + /// public string SELECTED_BORDER_COLOR { get { return _SELECTED_BORDER_COLOR; } set { _SELECTED_BORDER_COLOR = value; OnPropertyChanged(nameof(SELECTED_BORDER_COLOR)); } } + /// + /// 选中面同类面颜色 + /// public string SELECTED_TYPE_COLOR { get { return _SELECTED_TYPE_COLOR; } set { _SELECTED_TYPE_COLOR = value; OnPropertyChanged(nameof(SELECTED_TYPE_COLOR)); } } + /// + /// 选中面文字信息颜色 + /// public string SELECTED_FONT_COLOR { get { return _SELECTED_FONT_COLOR; } set { _SELECTED_FONT_COLOR = value; OnPropertyChanged(nameof(SELECTED_FONT_COLOR)); } } + /// + /// 标识线条颜色 + /// public string RULER_COLOR { get { return _RULER_COLOR; } set { _RULER_COLOR = value; OnPropertyChanged(nameof(RULER_COLOR)); } } + /// + /// 正方向标记颜色 + /// public string ARROW_COLOR { get { return _ARROW_COLOR; } set { _ARROW_COLOR = value; OnPropertyChanged(nameof(ARROW_COLOR)); } } + /// + /// 瑕疵面颜色 + /// public string BLEMISH_FACET_COLOR { get { return _BLEMISH_FACET_COLOR; } set { _BLEMISH_FACET_COLOR = value; OnPropertyChanged(nameof(BLEMISH_FACET_COLOR)); } } + /// + /// 台面颜色 + /// public string TABLE_FACET_COLOR { get { return _TABLE_FACET_COLOR; } set { _TABLE_FACET_COLOR = value; OnPropertyChanged(nameof(TABLE_FACET_COLOR)); } } + /// + /// 风筝面颜色 + /// public string UPPER_MAIN_FACET_COLOR { get { return _UPPER_MAIN_FACET_COLOR; } set { _UPPER_MAIN_FACET_COLOR = value; OnPropertyChanged(nameof(UPPER_MAIN_FACET_COLOR)); } } + /// + /// 星刻面颜色 + /// public string STAR_FACET_COLOR { get { return _STAR_FACET_COLOR; } set { _STAR_FACET_COLOR = value; OnPropertyChanged(nameof(STAR_FACET_COLOR)); } } + /// + /// 上腰面颜色 + /// public string UPPER_GIRDLE_FACET_COLOR { get { return _UPPER_GIRDLE_FACET_COLOR; } set { _UPPER_GIRDLE_FACET_COLOR = value; OnPropertyChanged(nameof(UPPER_GIRDLE_FACET_COLOR)); } } + /// + /// 腰面颜色 + /// public string GIRDLE_FACET_COLOR { get { return _GIRDLE_FACET_COLOR; } set { _GIRDLE_FACET_COLOR = value; OnPropertyChanged(nameof(GIRDLE_FACET_COLOR)); } } + /// + /// 亭部主刻面颜色 + /// public string PAVILION_MAIN_FACET_COLOR { get { return _PAVILION_MAIN_FACET_COLOR; } set { _PAVILION_MAIN_FACET_COLOR = value; OnPropertyChanged(nameof(PAVILION_MAIN_FACET_COLOR)); } } + /// + /// 下腰面颜色 + /// public string LOWER_GIRDLE_FACET_COLOR { get { return _LOWER_GIRDLE_FACET_COLOR; } set { _LOWER_GIRDLE_FACET_COLOR = value; OnPropertyChanged(nameof(LOWER_GIRDLE_FACET_COLOR)); } } + /// + /// 底面颜色 + /// public string CULET_COLOR { get { return _CULET_COLOR; } set { _CULET_COLOR = value; OnPropertyChanged(nameof(CULET_COLOR)); } } private Dictionary colors; @@ -44,44 +100,64 @@ public class ModelColorSetPageVM : BaseViewModel { InitSetting(); } - + /// + /// 页面初始化参数赋值 + /// private void InitSetting() { - colors = new Dictionary(); - colors.Add("FACET_COLOR", "面部颜色"); - colors.Add("BORDER_COLOR", "边框颜色"); - colors.Add("SELECTED_FACET_COLOR", "选中面颜色"); - colors.Add("SELECTED_BORDER_COLOR", "选中面边框颜色"); - colors.Add("SELECTED_TYPE_COLOR", "选中面同类面颜色"); - colors.Add("SELECTED_FONT_COLOR", "选中面文字信息颜色"); - colors.Add("RULER_COLOR", "标识线条颜色"); - colors.Add("ARROW_COLOR", "正方向标记颜色"); - colors.Add("BLEMISH_FACET_COLOR", "瑕疵面颜色"); - colors.Add("TABLE_FACET_COLOR", "台面颜色"); - colors.Add("UPPER_MAIN_FACET_COLOR", "风筝面颜色"); - colors.Add("STAR_FACET_COLOR", "星刻面颜色"); - colors.Add("UPPER_GIRDLE_FACET_COLOR", "上腰面颜色"); - colors.Add("GIRDLE_FACET_COLOR", "腰面颜色"); - colors.Add("PAVILION_MAIN_FACET_COLOR", "亭部主刻面颜色"); - colors.Add("LOWER_GIRDLE_FACET_COLOR", "下腰面颜色"); - colors.Add("CULET_COLOR", "底面颜色"); - + try + { + colors = new Dictionary(); + colors.Add("FACET_COLOR", "面部颜色"); + colors.Add("BORDER_COLOR", "边框颜色"); + colors.Add("SELECTED_FACET_COLOR", "选中面颜色"); + colors.Add("SELECTED_BORDER_COLOR", "选中面边框颜色"); + colors.Add("SELECTED_TYPE_COLOR", "选中面同类面颜色"); + colors.Add("SELECTED_FONT_COLOR", "选中面文字信息颜色"); + colors.Add("RULER_COLOR", "标识线条颜色"); + colors.Add("ARROW_COLOR", "正方向标记颜色"); + colors.Add("BLEMISH_FACET_COLOR", "瑕疵面颜色"); + colors.Add("TABLE_FACET_COLOR", "台面颜色"); + colors.Add("UPPER_MAIN_FACET_COLOR", "风筝面颜色"); + colors.Add("STAR_FACET_COLOR", "星刻面颜色"); + colors.Add("UPPER_GIRDLE_FACET_COLOR", "上腰面颜色"); + colors.Add("GIRDLE_FACET_COLOR", "腰面颜色"); + colors.Add("PAVILION_MAIN_FACET_COLOR", "亭部主刻面颜色"); + colors.Add("LOWER_GIRDLE_FACET_COLOR", "下腰面颜色"); + colors.Add("CULET_COLOR", "底面颜色"); - foreach (var color in colors) + foreach (var color in colors) + { + setColor(color.Key); + } + } + catch (Exception ex) { - setColor(color.Key); + Logger.Error($"全局异常捕获:{ex.Message}", ex); } } - + /// + /// 颜色数据更新 + /// + /// + /// public bool SaveUpdate(object param) { - DataBaseHelper.BeginTransaction(); - foreach(var color in colors) + try + { + DataBaseHelper.BeginTransaction(); + foreach (var color in colors) + { + updateDataBase(color.Key); + } + DataBaseHelper.commit(); + return true; + } + catch (Exception ex) { - updateDataBase(color.Key); + Logger.Error($"全局异常捕获:{ex.Message}", ex); + return false; } - DataBaseHelper.commit(); - return true; } private void updateDataBase(string SETTING_ID) { @@ -94,9 +170,13 @@ public class ModelColorSetPageVM : BaseViewModel }; colorData.insert(); } + /// + /// 画面中颜色属性赋值 + /// + /// private void setColor(string SETTING_ID) { - var value = Settings.SelectValueByName(SETTING_ID); + var value = Settings.SelectValueById(SETTING_ID); if (value == null || string.IsNullOrEmpty(value)) { value = "#FF000000"; diff --git a/ViewModel/Configuration/SettingsPages/SettingsVM.cs b/ViewModel/Configuration/SettingsPages/SettingsVM.cs index 1bbd7ec..6e3d507 100644 --- a/ViewModel/Configuration/SettingsPages/SettingsVM.cs +++ b/ViewModel/Configuration/SettingsPages/SettingsVM.cs @@ -1,4 +1,5 @@ using HandyControl.Controls; +using log4net; using Newtonsoft.Json.Linq; using SparkClient.Model.Entity.Base; using SparkClient.Model.Helper; @@ -17,6 +18,7 @@ namespace SparkClient.ViewModel.Configuration.SettingsPages { public class SettingsVM : BaseViewModel { + private static readonly ILog Logger = LogManager.GetLogger(typeof(ModelColorSetPageVM)); public ICommand SelectFileCommand { get; } public string _languageId; @@ -47,119 +49,154 @@ namespace SparkClient.ViewModel.Configuration.SettingsPages public DataTable Rules { get { return _rules; } set { _rules = value; OnPropertyChanged(nameof(Rules)); } } public SettingsVM() { - SelectFileCommand = new RelayCommand(SelectFile); - InitSetting(); + try { + SelectFileCommand = new RelayCommand(SelectFile); + InitSetting(); + } + catch (Exception ex) + { + Logger.Error($"全局异常捕获:{ex.Message}", ex); + } } private void InitSetting() { - Languages = new DataTable(); - Languages.Columns.Add("Key"); - Languages.Columns.Add("Value"); - Languages.Rows.Add("中文", "zh-cn"); - Languages.Rows.Add("English", "en"); - LanguageId = Settings.SelectValueByName("LanguageId"); - if (LanguageId.Length == 0) + try + { + Languages = new DataTable(); + Languages.Columns.Add("Key"); + Languages.Columns.Add("Value"); + Languages.Rows.Add("中文", "zh-cn"); + Languages.Rows.Add("English", "en"); + LanguageId = Settings.SelectValueById("LanguageId"); + if (LanguageId.Length == 0) + { + LanguageId = "zh-cn"; + } + bool.TryParse( Settings.SelectValueById("TxtFileChecked"), out bool TxtFileChecked); + this.TxtFileChecked = TxtFileChecked; + bool.TryParse(Settings.SelectValueById("StlFileChecked"), out bool StlFileChecked); + this.StlFileChecked = StlFileChecked; + bool.TryParse(Settings.SelectValueById("ExcelFileChecked"), out bool ExcelFileChecked); + this.ExcelFileChecked = ExcelFileChecked; + bool.TryParse(Settings.SelectValueById("DatFileChecked"), out bool DatFileChecked); + this.DatFileChecked = DatFileChecked; + FilePath = Settings.SelectValueById("FilePath"); + RuleId = Settings.SelectValueById("RuleId"); + selectRules(); + } + catch (Exception ex) { - LanguageId = "zh-cn"; + Logger.Error($"全局异常捕获:{ex.Message}", ex); } - bool.TryParse( Settings.SelectValueByName("TxtFileChecked"), out bool TxtFileChecked); - this.TxtFileChecked = TxtFileChecked; - bool.TryParse(Settings.SelectValueByName("StlFileChecked"), out bool StlFileChecked); - this.StlFileChecked = StlFileChecked; - bool.TryParse(Settings.SelectValueByName("ExcelFileChecked"), out bool ExcelFileChecked); - this.ExcelFileChecked = ExcelFileChecked; - bool.TryParse(Settings.SelectValueByName("DatFileChecked"), out bool DatFileChecked); - this.DatFileChecked = DatFileChecked; - FilePath = Settings.SelectValueByName("FilePath"); - RuleId = Settings.SelectValueByName("RuleId"); - selectRules(); } private void selectRules() { - Rules = new DataTable(); - Rules.Columns.Add("Key"); - Rules.Columns.Add("Value"); - string sql = $"SELECT * FROM RULE WHERE RULE_ID NOT LIKE '%_TA_%';"; - DataTable db = DataBaseHelper.ExecuteQuery(sql); - foreach (DataRow row in db.Rows) + try { - Rules.Rows.Add(row[MultilingualHelper.getString("RULE_NAME")].ToString(), row["RULE_ID"].ToString()); + Rules = new DataTable(); + Rules.Columns.Add("Key"); + Rules.Columns.Add("Value"); + string sql = $"SELECT * FROM RULE WHERE RULE_ID NOT LIKE '%_TA_%';"; + DataTable db = DataBaseHelper.ExecuteQuery(sql); + foreach (DataRow row in db.Rows) + { + Rules.Rows.Add(row[MultilingualHelper.getString("RULE_NAME")].ToString(), row["RULE_ID"].ToString()); + } + } + catch (Exception ex) + { + Logger.Error($"全局异常捕获:{ex.Message}", ex); } //Rules.Rows.Add("IGI 2023", "IGI2023"); } public bool SaveUpdate(object param) { - if (!Directory.Exists(FilePath)) + try { - Growl.Error(MultilingualHelper.getString("SavePathIsnotExists")); + if (!Directory.Exists(FilePath)) + { + Growl.Error(MultilingualHelper.getString("SavePathIsnotExists")); + return false; + } + MultilingualHelper.setLanguage(_languageId); + + updateDataBase(); + Growl.InfoGlobal(MultilingualHelper.getString("Save_successful_message")); + return true; + } + catch (Exception ex) + { + Logger.Error($"全局异常捕获:{ex.Message}", ex); return false; } - MultilingualHelper.setLanguage(_languageId); - - updateDataBase(); - Growl.InfoGlobal(MultilingualHelper.getString("Save_successful_message")); - return true; } private void updateDataBase() { - // 语言设置登录 - Settings LanguageData = new Settings() - { - Key = "LanguageId", - ItemName = "语言设置", - Value = LanguageId, - }; - LanguageData.insert(); - // 上传文件登录 - Settings TxtFileCheckedData = new Settings() + try { - Key = "TxtFileChecked", - ItemName = "上传文件 TXT文件", - Value = TxtFileChecked.ToString(), - }; - TxtFileCheckedData.insert(); + // 语言设置登录 + Settings LanguageData = new Settings() + { + Key = "LanguageId", + ItemName = "语言设置", + Value = LanguageId, + }; + LanguageData.insert(); + // 上传文件登录 + Settings TxtFileCheckedData = new Settings() + { + Key = "TxtFileChecked", + ItemName = "上传文件 TXT文件", + Value = TxtFileChecked.ToString(), + }; + TxtFileCheckedData.insert(); - Settings StlFileCheckedData = new Settings() - { - Key = "StlFileChecked", - ItemName = "上传文件 STL文件", - Value = StlFileChecked.ToString(), - }; - StlFileCheckedData.insert(); + Settings StlFileCheckedData = new Settings() + { + Key = "StlFileChecked", + ItemName = "上传文件 STL文件", + Value = StlFileChecked.ToString(), + }; + StlFileCheckedData.insert(); - Settings ExcelFileCheckedData = new Settings() - { - Key = "ExcelFileChecked", - ItemName = "上传文件 Excel文件", - Value = ExcelFileChecked.ToString(), - }; - ExcelFileCheckedData.insert(); + Settings ExcelFileCheckedData = new Settings() + { + Key = "ExcelFileChecked", + ItemName = "上传文件 Excel文件", + Value = ExcelFileChecked.ToString(), + }; + ExcelFileCheckedData.insert(); - Settings DatFileCheckedData = new Settings() - { - Key = "DatFileChecked", - ItemName = "上传文件 Dat文件", - Value = DatFileChecked.ToString(), - }; - DatFileCheckedData.insert(); - // 保存路径登录 - Settings FilePathData = new Settings() - { - Key = "FilePath", - ItemName = "保存路径", - Value = FilePath, - }; - FilePathData.insert(); - // 定级标准登录 - Settings RuleData = new Settings() + Settings DatFileCheckedData = new Settings() + { + Key = "DatFileChecked", + ItemName = "上传文件 Dat文件", + Value = DatFileChecked.ToString(), + }; + DatFileCheckedData.insert(); + // 保存路径登录 + Settings FilePathData = new Settings() + { + Key = "FilePath", + ItemName = "保存路径", + Value = FilePath, + }; + FilePathData.insert(); + // 定级标准登录 + Settings RuleData = new Settings() + { + Key = "RuleId", + ItemName = "定级标准", + Value = RuleId, + }; + RuleData.insert(); + } + catch (Exception ex) { - Key = "RuleId", - ItemName = "定级标准", - Value = RuleId, - }; - RuleData.insert(); + Logger.Error($"全局异常捕获:{ex.Message}", ex); + } } public void SelectFile(object param) { @@ -182,6 +219,9 @@ namespace SparkClient.ViewModel.Configuration.SettingsPages } } } + /// + /// 设定表实体 + /// public class Settings { private static string TABLE_NAME = "SETTING"; @@ -203,7 +243,10 @@ namespace SparkClient.ViewModel.Configuration.SettingsPages /// [DbField("SETTING_P")] public required string Value { get; set; } - + /// + /// 设定表DB登录 + /// + /// 更新数量 public int insert() { string sql = $"SELECT * FROM {TABLE_NAME} WHERE SETTING_ID = '{Key}';"; @@ -219,8 +262,12 @@ namespace SparkClient.ViewModel.Configuration.SettingsPages return DataBaseHelper.ExecuteNonQuery(insertSql); } } - - public static string SelectValueByName(string Id) + /// + /// 设定表值检索 + /// + /// + /// value + public static string SelectValueById(string Id) { string sql = $"SELECT * FROM {TABLE_NAME} WHERE SETTING_ID = '{Id}';"; DataTable db = DataBaseHelper.ExecuteQuery(sql); diff --git a/ViewModel/Grading/DiamondSelectVM.cs b/ViewModel/Grading/DiamondSelectVM.cs index f6a2906..9403e35 100644 --- a/ViewModel/Grading/DiamondSelectVM.cs +++ b/ViewModel/Grading/DiamondSelectVM.cs @@ -1,3 +1,4 @@ +using System.Configuration; using Newtonsoft.Json; using SparkClient.Model.Entity.ApiEntity; using SparkClient.Model.Helper; @@ -15,6 +16,8 @@ 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; @@ -170,7 +173,6 @@ public class DiamondSelectVM : BaseViewModel parameter.CrownType = value.Split(" ")[1]; parameter.PavType = value.Split(" ")[2]; } - // 初始化SOC客户端服务,传入SOC端的地址和认证Token _socClientService = new SOCClientService(); // 启动soc @@ -207,6 +209,10 @@ public class DiamondSelectVM : BaseViewModel 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); + + // 启动算法 parameter = _algorithmServer.CallParseJsonAndReturnActions(parameter.Shape, parameter.CrownType, image_files); //机器号 @@ -365,7 +371,95 @@ public class DiamondSelectVM : BaseViewModel await Task.Delay(5); loading.Close(); } + } + /// + /// 处理算法调用失败时的逻辑,包括保存图片到历史记录文件夹 + /// + /// 图片文件路径的 JSON 字符串 + /// + private static readonly ILog Logger = LogManager.GetLogger(typeof(AlgorithmServer)); + private void HandleAlgorithmFailure(string image_files) + { + + // 从配置文件中读取 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("yyyy-MM-dd-HH-mm-ss"); + // 组合新的文件夹路径 + string newFolderPath = Path.Combine(imageHistoryPath, $"image-{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}"); + } + } /// /// 跳转至检测结果 /// diff --git a/ViewModel/Grading/GradingResultVM.cs b/ViewModel/Grading/GradingResultVM.cs index c5e18db..2e446d5 100644 --- a/ViewModel/Grading/GradingResultVM.cs +++ b/ViewModel/Grading/GradingResultVM.cs @@ -46,6 +46,7 @@ public class GradingResultVM : BaseViewModel private string _ds; private RowDetail _selRowDataDetail; private bool _isEnabled; + public bool isSaved = false; public ICommand SaveFileCommand { get; } public ICommand SaveAsCommand { get; } public List DtResults { get { return _dtResults; } set { _dtResults = value; OnPropertyChanged(nameof(DtResults)); } } @@ -87,7 +88,7 @@ public class GradingResultVM : BaseViewModel algorithmResult = result as AlgorithmResultEntity?? new AlgorithmResultEntity(); InitView(algorithmResult); machine = algorithmResult.DeviceId; - username = Settings.SelectValueByName("PERMISSIONS"); + username = Settings.SelectValueById("PERMISSIONS"); if (ruleId.StartsWith("IGI")) { IsEnabled = true; @@ -139,7 +140,7 @@ public class GradingResultVM : BaseViewModel Type type = colorConfigEntity.GetType(); foreach (var property in colorProperty) { - var value = Settings.SelectValueByName(property.Key); + var value = Settings.SelectValueById(property.Key); PropertyInfo? p = type.GetProperty(property.Value); if (p != null && !string.IsNullOrEmpty(value)) { @@ -196,7 +197,7 @@ public class GradingResultVM : BaseViewModel } private string getRuleId() { - return Settings.SelectValueByName("RuleId"); + return Settings.SelectValueById("RuleId"); } #endregion /// @@ -662,6 +663,7 @@ public class GradingResultVM : BaseViewModel string fullPath = Path.Combine(getFilePath(), this.DiamondCode); ExportFile(fullPath); SaveTestResult(SaveStatus.Save); + isSaved = true; } private string getFilePath() {