diff --git a/Language/zh_CN.xaml b/Language/zh_CN.xaml
index 28b5279..74b3fd0 100644
--- a/Language/zh_CN.xaml
+++ b/Language/zh_CN.xaml
@@ -145,6 +145,7 @@
显示选择面的同类面
显示瑕疵面
显示正方向标识
+ 显示网格线
保存成功
保存失败
选择路径
@@ -166,7 +167,7 @@
形状
冠部
亭部
- 重量(ct)
+ 预估重量(ct)
切工等级
对称等级
平均值
diff --git a/Model/Services/AlgorithmServer.cs b/Model/Services/AlgorithmServer.cs
index 8d2569c..074d888 100644
--- a/Model/Services/AlgorithmServer.cs
+++ b/Model/Services/AlgorithmServer.cs
@@ -8,6 +8,9 @@ using Newtonsoft.Json.Linq;
using SparkClient.Model.Entity.ApiEntity;
using SparkClient.Model.Helper;
using System.Configuration;
+using System.Diagnostics;
+using System.Text;
+using System.Text.RegularExpressions;
using SparkClient.Model.Common;
namespace SparkClient.Model.Services
@@ -24,7 +27,7 @@ namespace SparkClient.Model.Services
// 添加公共方法
public AlgorithmResultEntity CallParseJsonAndReturnActions(string shape, string shape_mode, string image_files)
- {
+ {
try
{
//半圆
@@ -33,18 +36,23 @@ 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);
object lightLevelValue = table.Rows[0][0];
string algo_config = lightLevelValue.ToString() ?? throw new InvalidOperationException();
-
+
//图片根目录
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);
+ string? log4NetLogDirectory =
+ Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
// 构建C++ DLL 日志文件路径
string algorithm_log_path = Path.Combine(log4NetLogDirectory, "logs");
@@ -55,51 +63,137 @@ 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("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);
- // 检查返回的 JSON 字符串是否为空或无效
- if (string.IsNullOrEmpty(resultJson))
+ string jsonDataString = jsonData.ToString().Replace("\"", "\\\"");
+ //string jsonDataString = jsonData.ToString();
+ // // 调用 C++ DLL 函数解析 JSON
+ // IntPtr resultPtr = DetectDiamond(jsonDataString);
+ // string resultJson = Marshal.PtrToStringAnsi(resultPtr);
+ // // 释放 DLL 分配的内存
+ // FreeString(resultPtr);
+ // // 检查返回的 JSON 字符串是否为空或无效
+ // if (string.IsNullOrEmpty(resultJson))
+ // {
+ // Logger.Error("Algorithm failed or no result returned.");
+ // // 返回一个默认的 AlgorithmResultEntity 对象表示解析失败
+ // return new AlgorithmResultEntity
+ // {
+ // facets = new List(),
+ // measurements = new Measurements()
+ // };
+ // }
+
+ // 启动隔离的控制台应用程序
+ var startInfo = new ProcessStartInfo
{
- // 返回一个默认的 AlgorithmResultEntity 对象表示解析失败
- return new AlgorithmResultEntity
+ FileName = "AlgorithmDllIsolationConsoleApp.exe", // 控制台应用程序路径
+ Arguments = $"\"{jsonDataString}\"", // 将 JSON 数据作为参数传递给控制台应用程序
+ RedirectStandardOutput = true, // 获取控制台应用程序的输出
+ RedirectStandardError = true,
+ UseShellExecute = false,
+ CreateNoWindow = true
+ };
+
+ using (var process = Process.Start(startInfo))
+ {
+ // 使用 StringBuilder 来捕获标准输出和标准错误
+ var outputBuilder = new StringBuilder();
+ var errorBuilder = new StringBuilder();
+
+ // 订阅标准输出事件
+ process.OutputDataReceived += (sender, e) =>
{
- facets = new List(),
- measurements = new Measurements()
+ if (e.Data == null)
+ {
+ // 当 e.Data 为 null 时,表示读取完成
+ outputBuilder.AppendLine(e.Data);
+ Console.WriteLine($"Output: {e.Data}");
+ return;
+ }
+ // 将输出数据追加到 outputBuilder
+ outputBuilder.AppendLine(e.Data);
+ // 打印输出数据到控制台
+ Console.WriteLine($"Output: {e.Data}");
};
- }
- // 反序列化 JSON 字符串为 AlgorithmResultEntity 对象
- var result = JsonConvert.DeserializeObject(resultJson);
- // 检查反序列化结果是否为 null
- if (result == null)
- {
- // 返回一个默认的 AlgorithmResultEntity 对象表示解析失败
- return new AlgorithmResultEntity
+ // 订阅标准错误事件
+ process.ErrorDataReceived += (sender, e) =>
{
- facets = new List(),
- measurements = new Measurements()
+ if (e.Data == null)
+ {
+ // 当 e.Data 为 null 时,表示读取完成
+ errorBuilder.AppendLine(e.Data);
+ Logger.Error($"Error Output: {e.Data}");
+ return;
+ }
+ // 将错误数据追加到 errorBuilder
+ errorBuilder.AppendLine(e.Data);
+ // 记录错误数据到日志
+ Logger.Error($"Error Output: {e.Data}");
};
+
+ // 开始异步读取
+ process.BeginOutputReadLine();
+ process.BeginErrorReadLine();
+
+ // 等待控制台应用程序结束
+ process.WaitForExit();
+
+ // 等待异步读取完成
+ //Task.WaitAll(outputTcs.Task, errorTcs.Task);
+
+ // 获取结果
+ string resultJson = outputBuilder.ToString();
+ string errorOutput = errorBuilder.ToString();
+
+
+ // 如果控制台应用程序有错误输出
+ if (!string.IsNullOrEmpty(errorOutput))
+ {
+ Logger.Error($"Console App Error: {errorOutput}");
+ }
+
+ // 如果没有结果或失败
+ if (string.IsNullOrEmpty(resultJson))
+ {
+ Logger.Error("Algorithm failed or no result returned.");
+ return new AlgorithmResultEntity
+ {
+ facets = new List(),
+ measurements = new Measurements()
+ };
+ }
+
+ // 反序列化 JSON 字符串为 AlgorithmResultEntity 对象
+ var result = JsonConvert.DeserializeObject(resultJson);
+
+ // 检查反序列化结果是否为 null
+ if (result == null)
+ {
+ // 返回一个默认的 AlgorithmResultEntity 对象表示解析失败
+ return new AlgorithmResultEntity
+ {
+ facets = new List(),
+ measurements = new Measurements()
+ };
+ }
+
+ // 记录算法失败的状态
+ Logger.Info($"Algorithm failed with status: {result.status}");
+ // 记录算法失败的错误信息
+ Logger.Info($"Algorithm failed with errorMsg: {result.error_msg}");
+ // 处理 C++ DLL 日志文件
+ //ProcessDllLog();
+ // 算法调用失败时,保存图片到历史记录文件夹
+ // if (result.status == StatusCodes.AlgorithmFailed)
+ // {
+ // HandleAlgorithmFailure(image_files);
+ // }
+ return result;
}
- // 记录算法失败的状态
- 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)
- // {
- // HandleAlgorithmFailure(image_files);
- // }
- return result;
}
catch (Exception ex)
{
@@ -112,6 +206,7 @@ namespace SparkClient.Model.Services
Logger.Error($"Inner Exception: {ex.InnerException.Message}");
Logger.Error($"Inner Stack Trace: {ex.InnerException.StackTrace}");
}
+
// 返回一个默认的 AlgorithmResultEntity 对象表示解析失败
return new AlgorithmResultEntity
{
diff --git a/SparkClient.sln.DotSettings.user b/SparkClient.sln.DotSettings.user
index ebbda40..a510370 100644
--- a/SparkClient.sln.DotSettings.user
+++ b/SparkClient.sln.DotSettings.user
@@ -1,4 +1,6 @@
+ ForceIncluded
+ ForceIncluded
ForceIncluded
ForceIncluded
ForceIncluded
@@ -49,6 +51,7 @@
ForceIncluded
ForceIncluded
ForceIncluded
+ ForceIncluded
ForceIncluded
ForceIncluded
ForceIncluded
@@ -59,6 +62,7 @@
ForceIncluded
ForceIncluded
ForceIncluded
+ ForceIncluded
ForceIncluded
ForceIncluded
ForceIncluded
diff --git a/ViewModel/BaseWindow/HomeWindowVM.cs b/ViewModel/BaseWindow/HomeWindowVM.cs
index 226dad8..5e540de 100644
--- a/ViewModel/BaseWindow/HomeWindowVM.cs
+++ b/ViewModel/BaseWindow/HomeWindowVM.cs
@@ -4,6 +4,7 @@ using log4net;
using SparkClient.Model.Helper;
using SparkClient.Model.Services;
using SparkClient.ViewModel.Configuration;
+using SparkClient.ViewModel.Configuration.SettingsPages;
using SparkClient.ViewModel.Grading;
using MessageBox = SparkClient.Views.Dialog.MessageBox;
@@ -34,12 +35,34 @@ public class HomeWindowVM : BaseViewModel
public void ShowConfigPage(object parameter)
{
- ConfigMenuPageVM vm = new ConfigMenuPageVM();
- WindowManager.mainViewModel.Content = vm;
- WindowManager.openContent.Add(vm);
+ if (isPermissions())
+ {
+ ConfigMenuPageVM vm = new ConfigMenuPageVM();
+ WindowManager.mainViewModel.Content = vm;
+ WindowManager.openContent.Add(vm);
+ }
+ else
+ {
+ BaseControlVM vm = new BaseControlVM(new SettingBaseVM(), MultilingualHelper.getString("SystemSetting"));
+ WindowManager.mainViewModel.Content = vm;
+ WindowManager.openContent.Add(vm);
+ }
}
-
- public async void ShowDiamlondSelPage(object parameter)
+ private bool isPermissions()
+ {
+ bool result = false;
+ string PERMISSIONS = Settings.SelectValueById("PERMISSIONS");
+ if ("admin".Equals(PERMISSIONS))
+ {
+ result = true;
+ }
+ else
+ {
+ result = false;
+ }
+ return result;
+ }
+ public async void ShowDiamlondSelPage(object parameter)
{
try
{
diff --git a/ViewModel/Grading/GradingResultVM.cs b/ViewModel/Grading/GradingResultVM.cs
index 73a4cad..055d428 100644
--- a/ViewModel/Grading/GradingResultVM.cs
+++ b/ViewModel/Grading/GradingResultVM.cs
@@ -23,6 +23,15 @@ using SparkClient.Views.UserControl.ViewportData.Helper;
using System.Diagnostics.Metrics;
using log4net;
using SparkClient.ViewModel.Configuration;
+using System.Drawing.Printing;
+using System.Drawing;
+using RectangleF = System.Drawing.RectangleF;
+using FontFamily = System.Drawing.FontFamily;
+using FontStyle = System.Drawing.FontStyle;
+using NPOI.SS.Formula.Functions;
+using System.Windows.Media;
+using Brush = System.Drawing.Brush;
+using Brushes = System.Drawing.Brushes;
namespace SparkClient.ViewModel.Grading;
///
@@ -828,6 +837,7 @@ public class GradingResultVM : BaseViewModel
}
}
SaveTestResult(SaveStatus.SaveAs);
+ //PrintLabel();
}
catch (Exception ex)
{
@@ -1644,6 +1654,130 @@ public class GradingResultVM : BaseViewModel
}
#endregion
+ public void PrintLabel()
+ {
+ PrintDocument printDoc = new PrintDocument();
+ printDoc.PrintPage += new PrintPageEventHandler(PrintPageHandler);
+ printDoc.DefaultPageSettings.PaperSize = new System.Drawing.Printing.PaperSize("Custom", 550, 300);
+
+ PrintDialog printDialog = new PrintDialog();
+ printDialog.Document = printDoc;
+
+ if (printDialog.ShowDialog() == DialogResult.OK)
+ {
+ printDoc.Print();
+ }
+ }
+
+ private void PrintPageHandler(object sender, PrintPageEventArgs e)
+ {
+ var result = algorithmResult.measurements;
+ int startX = 10;
+ int startY = 10;
+ var col2X = startX + 90;
+ var col3X = col2X + 70;
+ // 设置字体
+ Font font = new Font(FontFamily.GenericSerif, 12, FontStyle.Bold);
+
+ // 设置颜色
+ Brush brush = Brushes.Black;
+
+ // 设置对齐方式
+ StringFormat format = new StringFormat();
+ format.Alignment = StringAlignment.Center; // 水平居中
+ format.LineAlignment = StringAlignment.Center; // 垂直居中
+
+ // 绘制文本
+ // 第一行
+ int X = startX;
+ int Y = startY;
+ e.Graphics.DrawString(Standard, font, brush, new PointF(X, Y));
+ X += 70;
+ e.Graphics.DrawString(Shape, font, brush, new PointF(X, Y));
+ X += 50;
+ e.Graphics.DrawString($"ID:{DiamondCode}", font, brush, new PointF(X, Y));
+ X += 100;
+ e.Graphics.DrawString($"Weight:{Wight}ct.", font, brush, new PointF(X, Y));
+ X += 120;
+ Brush backgroundBrush = new SolidBrush(System.Drawing.Color.Black); // 背景色为黄色
+ e.Graphics.FillRectangle(backgroundBrush, new RectangleF(X, Y, 200, font.Height));
+ e.Graphics.DrawString(CutLevelTotal, font, Brushes.White, new PointF(X, Y));
+
+ // 第二行
+ X = startX;
+ Y += font.Height;
+ e.Graphics.DrawString("Diameter", font, brush, new PointF(X, Y));
+
+ e.Graphics.DrawString($"{FormatDouble_D(result.DIAMETER)}mm", font, brush, new PointF(col2X, Y));
+
+ e.Graphics.DrawString($"({FormatDouble_D(result.M1)}mm-{FormatDouble_D(result.M2)}mm)", font, brush, new PointF(col3X, Y));
+ e.Graphics.DrawString($"0.3%", font, brush, new PointF(310, Y));
+ e.Graphics.FillRectangle(backgroundBrush, new RectangleF(350, Y, 200, font.Height));
+ e.Graphics.DrawString(SymLevelTotal, font, Brushes.White, new PointF(X, Y));
+
+ // 第三行
+ X = startX;
+ Y += font.Height;
+ e.Graphics.DrawString("Total Dep.", font, brush, new PointF(X, Y));
+ X = col2X;
+ e.Graphics.DrawString($"{FormatDouble_D(result.DIAMETER * result.TOTAL_DEPTH)}mm", font, brush, new PointF(X, Y));
+ X = col3X;
+ e.Graphics.DrawString($"{FormatDouble_P(result.TOTAL_DEPTH)}%", font, brush, new PointF(X, Y));
+ e.Graphics.DrawString($"{DtResults.Where(X=> "TOTAL_DEPTH".Equals(X.TestItemId)).Select(X=>X.CutLevel).FirstOrDefault()}", font, brush, new PointF(480, Y));
+ // 第四行
+ X = startX;
+ Y += font.Height;
+ e.Graphics.DrawString("Table", font, brush, new PointF(X, Y));
+ X = col2X;
+ e.Graphics.DrawString($"{FormatDouble_D(result.DIAMETER * result.TABLE)}mm", font, brush, new PointF(X, Y));
+ X = col3X;
+ e.Graphics.DrawString($"{FormatDouble_P(result.TABLE)}%", font, brush, new PointF(X, Y));
+ e.Graphics.DrawString($"{DtResults.Where(X => "TABLE".Equals(X.TestItemId)).Select(X => X.CutLevel).FirstOrDefault()}", font, brush, new PointF(480, Y));
+ // 第五行
+ X = startX;
+ Y += font.Height;
+ e.Graphics.DrawString("Crown", font, brush, new PointF(X, Y));
+ X = col2X;
+ e.Graphics.DrawString($"{FormatDouble_A(result.CROWN_ANGLE)}°", font, brush, new PointF(X, Y));
+ X = col3X;
+ e.Graphics.DrawString($"({FormatDouble_A(result.CROWN_ANGLE_MIN)}°-{FormatDouble_A(result.CROWN_ANGLE_MAX)}°)", font, brush, new PointF(X, Y));
+ X += 120;
+ e.Graphics.DrawString($"({FormatDouble_A(result.CROWN_HEIGHT)}%)", font, brush, new PointF(X, Y));
+ e.Graphics.DrawString($"{DtResults.Where(X => "CROWN_ANGLE".Equals(X.TestItemId)).Select(X => X.CutLevel).FirstOrDefault()}", font, brush, new PointF(410, Y));
+ e.Graphics.DrawString($"{DtResults.Where(X => "CROWN_HEIGHT".Equals(X.TestItemId)).Select(X => X.CutLevel).FirstOrDefault()}", font, brush, new PointF(480, Y));
+ // 第六行
+ X = startX;
+ Y += font.Height;
+ e.Graphics.DrawString("Pavil.", font, brush, new PointF(X, Y));
+ X = col2X;
+ e.Graphics.DrawString($"{FormatDouble_A(result.PAV_ANGLE)}°", font, brush, new PointF(X, Y));
+ X = col3X;
+ e.Graphics.DrawString($"({FormatDouble_A(result.PAV_ANGLE_MIN)}°-{FormatDouble_A(result.PAV_ANGLE_MAX)}°)", font, brush, new PointF(X, Y));
+ X += 120;
+ e.Graphics.DrawString($"({FormatDouble_A(result.PAV_DEPTH)}%)", font, brush, new PointF(X, Y));
+ e.Graphics.DrawString($"{DtResults.Where(X => "PAV_ANGLE".Equals(X.TestItemId)).Select(X => X.CutLevel).FirstOrDefault()}", font, brush, new PointF(410, Y));
+ e.Graphics.DrawString($"{DtResults.Where(X => "PAV_DEPTH".Equals(X.TestItemId)).Select(X => X.CutLevel).FirstOrDefault()}", font, brush, new PointF(480, Y));
+ // 第七行
+ X = startX;
+ Y += font.Height;
+ e.Graphics.DrawString("Culet", font, brush, new PointF(X, Y));
+ X = col2X;
+ e.Graphics.DrawString($"{FormatDouble_P(result.CULET)}%", font, brush, new PointF(X, Y));
+ X = col3X;
+ e.Graphics.DrawString($"Twist", font, brush, new PointF(X, Y));
+ X += 60;
+ e.Graphics.DrawString($"({FormatDouble_A(result.TWIST_MIN)}°-{FormatDouble_A(result.TWIST_MAX)}°)", font, brush, new PointF(X, Y));
+ // 第八行
+ X = startX;
+ Y += font.Height;
+ e.Graphics.DrawString("Girdle 16M", font, brush, new PointF(X, Y));
+ X = col2X;
+ e.Graphics.DrawString($"{FormatDouble_D(result.GIRDLE_VALLEY)}", font, brush, new PointF(X, Y));
+ X = col3X;
+ e.Graphics.DrawString($"({FormatDouble_P(result.GIRDLE_VALLEY_MIN)}%-{FormatDouble_P(result.GIRDLE_VALLEY_MAX)}%)", font, brush, new PointF(X, Y));
+ e.Graphics.DrawString($"{DtResults.Where(X => "GIRDLE".Equals(X.TestItemId)).Select(X => X.CutLevel).FirstOrDefault()}", font, brush, new PointF(480, Y));
+
+ }
#region 钻石操作相关
//暂略
//部分代码(直接操作控件)需要在xaml.cs里边写
diff --git a/Views/Dialog/ExportDialog.xaml.cs b/Views/Dialog/ExportDialog.xaml.cs
index d129168..89d74ad 100644
--- a/Views/Dialog/ExportDialog.xaml.cs
+++ b/Views/Dialog/ExportDialog.xaml.cs
@@ -1,4 +1,5 @@
-using System;
+using log4net;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -19,6 +20,7 @@ namespace SparkClient.Views.Dialog
///
public partial class ExportDialog : Window
{
+ private static readonly ILog Logger = LogManager.GetLogger(typeof(ExportDialog));
public ExportDialog()
{
InitializeComponent();
diff --git a/Views/Dialog/JsonImport.xaml.cs b/Views/Dialog/JsonImport.xaml.cs
index 26964b1..f0cf9b5 100644
--- a/Views/Dialog/JsonImport.xaml.cs
+++ b/Views/Dialog/JsonImport.xaml.cs
@@ -1,6 +1,8 @@
using HandyControl.Controls;
+using log4net;
using SparkClient.ViewModel;
using SparkClient.ViewModel.Dialog;
+using SparkClient.Views.Grading;
using System.IO;
using System.Windows;
using System.Windows.Controls;
@@ -14,6 +16,7 @@ namespace SparkClient.Views.Dialog
///
public partial class JsonImport
{
+ private static readonly ILog Logger = LogManager.GetLogger(typeof(JsonImport));
public BaseViewModel ViewModel = null;
public JsonImport()
{
diff --git a/Views/Dialog/MessageBox.xaml.cs b/Views/Dialog/MessageBox.xaml.cs
index 6c167bb..ae68b97 100644
--- a/Views/Dialog/MessageBox.xaml.cs
+++ b/Views/Dialog/MessageBox.xaml.cs
@@ -3,12 +3,15 @@ using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
+using log4net;
using SparkClient.Model.Helper;
+using SparkClient.Views.Grading;
namespace SparkClient.Views.Dialog;
public partial class MessageBox : Window
{
+ private static readonly ILog Logger = LogManager.GetLogger(typeof(GradingResult));
public MessageBox()
{
InitializeComponent();
diff --git a/Views/Grading/GradingResult.xaml.cs b/Views/Grading/GradingResult.xaml.cs
index 9038466..b8ce535 100644
--- a/Views/Grading/GradingResult.xaml.cs
+++ b/Views/Grading/GradingResult.xaml.cs
@@ -4,6 +4,7 @@ using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
+using log4net;
using SparkClient.ViewModel.Grading;
using GeometryModel3D = HelixToolkit.Wpf.SharpDX.GeometryModel3D;
@@ -11,6 +12,8 @@ namespace SparkClient.Views.Grading;
public partial class GradingResult
{
+ private static readonly ILog Logger = LogManager.GetLogger(typeof(GradingResult));
+
// List triangles = new List();
List mouseAddModels = new List();
// 用于记录当前所有已存在的Popup