From 35e40c6dd880c812db317e814f7e6806455edb38 Mon Sep 17 00:00:00 2001 From: tongg <tongguibina@163.com> Date: Mon, 2 Jun 2025 23:10:29 +0800 Subject: [PATCH] grade level custom --- Language/zh_Pro.xaml | 3 + .../Exceptions/NotGradeSetException.cs | 10 ++ Model/GradeLevel/GradeLevelCalculator.cs | 34 +++++- Model/GradeResult/Entity/Enums/Accuracy.cs | 12 +-- .../GradeResult/Entity/Enums/DiamondShape.cs | 6 +- .../Helper/DoubleDataFormatHelper.cs | 78 +++++++++++++- .../GradeResult/Helper/ViewDataInfoHelper.cs | 100 +++++++++++++++++- Model/Helper/DataBaseHelper.cs | 2 +- Views/Dialog/ImageSelect.xaml | 2 +- 9 files changed, 228 insertions(+), 19 deletions(-) create mode 100644 Model/GradeLevel/Exceptions/NotGradeSetException.cs diff --git a/Language/zh_Pro.xaml b/Language/zh_Pro.xaml index d4178d7..0a18973 100644 --- a/Language/zh_Pro.xaml +++ b/Language/zh_Pro.xaml @@ -249,4 +249,7 @@ <sys:String x:Key="NetworkSpeedCheckedText">取消网络质量检测</sys:String> <sys:String x:Key="NetworkSpeedCheckedMessage">当前网络传输效率低,可能影响检测效率!</sys:String> + + <sys:String x:Key="ColumnNameBase">Name</sys:String> + </ResourceDictionary> \ No newline at end of file diff --git a/Model/GradeLevel/Exceptions/NotGradeSetException.cs b/Model/GradeLevel/Exceptions/NotGradeSetException.cs new file mode 100644 index 0000000..746ef13 --- /dev/null +++ b/Model/GradeLevel/Exceptions/NotGradeSetException.cs @@ -0,0 +1,10 @@ +namespace BrilliantSightClient.Model.GradeLevel.Exceptions; + +public class NotGradeSetException : Exception +{ + public NotGradeSetException() + :base("Not Grade Set!") + { + + } +} \ No newline at end of file diff --git a/Model/GradeLevel/GradeLevelCalculator.cs b/Model/GradeLevel/GradeLevelCalculator.cs index 6126305..a375542 100644 --- a/Model/GradeLevel/GradeLevelCalculator.cs +++ b/Model/GradeLevel/GradeLevelCalculator.cs @@ -1,17 +1,45 @@ using BrilliantSightClient.Model.Entity.ApiEntity; +using BrilliantSightClient.Model.GradeLevel.Entity; using BrilliantSightClient.Model.GradeLevel.Entity.DatabaseEntity; +using BrilliantSightClient.Model.GradeLevel.Entity.Enum; +using BrilliantSightClient.Model.GradeLevel.Exceptions; +using BrilliantSightClient.Model.GradeLevel.Helper; using BrilliantSightClient.Model.GradeResult.Entity; +using BrilliantSightClient.Model.GradeResult.Entity.Enums; +using BrilliantSightClient.Model.Helper; namespace BrilliantSightClient.Model.GradeLevel; public class GradeLevelCalculator { + AlgorithmResultEntity _diamondResult; + + GradeLevelMst _masterLevel; + + private List<GradeLevelSet> _gradeLevelCutSets; + private List<GradeLevelSet> _gradeLevelSymSets; + + public GradeLevelCalculator(AlgorithmResultEntity entity) { - + _diamondResult = entity; + + var masterSql = $"select * from GRADE_LEVEL_MST where NAME = '{entity.Standard}' and RUNMODE = {Common.RunMode} or RUNMODE = -1 " + + $" and SHAPE = {EntityHelper.GetValueFromName<DiamondShape>(entity.Shape)} and CROWN = {entity.CrownType} and PAVILION = {entity.PavType}" ; + var masterLevel = DataBaseHelper.ExecuteQuery<GradeLevelMst>(masterSql); + if (masterLevel.Count == 0) + throw new NotGradeSetException(); + _masterLevel = masterLevel.First(); + + var setsSql = $"select * from GRADE_LEVEL_SET where MST_SIGN = '{_masterLevel.Sign}'"; + var levelSets = DataBaseHelper.ExecuteQuery<GradeLevelSet>(setsSql); + if (masterLevel.Count == 0) + throw new NotGradeSetException(); + _gradeLevelCutSets = levelSets.FindAll(x => x.Set_Type == GradeType.Cut.GetValue()); + _gradeLevelSymSets = levelSets.FindAll(x => x.Set_Type == GradeType.Sym.GetValue()); } - public GradeLevelSet GetCutGradeLevelSet(double maxVal, double minVal) + public GradeLevelSet GetCutGradeLevelSet(string key, double maxVal, double minVal) { return null; } @@ -21,7 +49,7 @@ public class GradeLevelCalculator return null; } - public GradeLevelSet GetSymGradeLevelSet(double devVal) + public GradeLevelSet GetSymGradeLevelSet(string key, double devVal) { return null; } diff --git a/Model/GradeResult/Entity/Enums/Accuracy.cs b/Model/GradeResult/Entity/Enums/Accuracy.cs index f941822..7f252d1 100644 --- a/Model/GradeResult/Entity/Enums/Accuracy.cs +++ b/Model/GradeResult/Entity/Enums/Accuracy.cs @@ -5,15 +5,15 @@ namespace BrilliantSightClient.Model.GradeResult.Entity.Enums; public enum Accuracy { [Description("强制保留两位小数,向下取整(ZDZ1)")] - ForceTwoDecimals, + ForceTwoDecimals = 1, [Description("强制保留一位小数,向下取整(ZD1)")] - ForceOneDecimal, + ForceOneDecimal = 2, [Description("将数值舍入到最近的 0.5 倍数(ZD5)")] - HalfStepRounding, + HalfStepRounding = 3, [Description("将数值舍入到最近的 5 的整数倍(Z5)")] - MultipleOfFive, + MultipleOfFive = 4, [Description("将数值舍入到最近的0.2倍数(ZD2)")] - DecimalTwoStepRounding, + DecimalTwoStepRounding = 5, [Description("强制向下取整为整数(Floor)")] - IntegerFloor + IntegerFloor = 6 } \ No newline at end of file diff --git a/Model/GradeResult/Entity/Enums/DiamondShape.cs b/Model/GradeResult/Entity/Enums/DiamondShape.cs index b667d9d..2a76698 100644 --- a/Model/GradeResult/Entity/Enums/DiamondShape.cs +++ b/Model/GradeResult/Entity/Enums/DiamondShape.cs @@ -4,10 +4,10 @@ namespace BrilliantSightClient.Model.GradeResult.Entity.Enums; public enum DiamondShape { - [Description("强制保留两位小数,向下取整(ZDZ1)")] + [Description("圆形")] Round = 0, - [Description("强制保留一位小数,向下取整(ZD1)")] + [Description("椭圆形")] Oval = 1, - [Description("将数值舍入到最近的 0.5 倍数(ZD5)")] + [Description("梨形")] Pear = 2, } \ No newline at end of file diff --git a/Model/GradeResult/Helper/DoubleDataFormatHelper.cs b/Model/GradeResult/Helper/DoubleDataFormatHelper.cs index 28e7a00..21591fd 100644 --- a/Model/GradeResult/Helper/DoubleDataFormatHelper.cs +++ b/Model/GradeResult/Helper/DoubleDataFormatHelper.cs @@ -1,4 +1,5 @@ using BrilliantSightClient.Model.Attributes; +using BrilliantSightClient.Model.Extension; using BrilliantSightClient.Model.GradeResult.Entity.Enums; namespace BrilliantSightClient.Model.GradeResult.Helper; @@ -95,6 +96,65 @@ public static class DoubleDataFormatHelper return result; } + /// <summary> + /// 百分比用的小数格式化 + /// </summary> + /// <param name="value"></param> + /// <returns></returns> + [Log] + public static string FormatDouble(object? value, Accuracy accuracy) + { + string result = ""; + + double dvalue = Double.NaN; + if (!Double.TryParse(value.ToSafeString(), out dvalue)) + { + return string.Empty; + } + + if (Model.Helper.Common.RunMode == 0) + { + switch (accuracy) + { + case Accuracy.ForceTwoDecimals: + result = (Math.Floor(dvalue * 100) / 100).ToString("f2"); + break; + case Accuracy.ForceOneDecimal: + result = (Math.Floor(dvalue * 10) / 10).ToString("f1"); + break; + case Accuracy.HalfStepRounding: + result = (RoundFiveDownSixUp(dvalue * 2) / 2).ToString("f1"); + break; + case Accuracy.MultipleOfFive: + result = (RoundFiveDownSixUp(dvalue / 5) * 5).ToString(); + break; + case Accuracy.DecimalTwoStepRounding: + result = RoundToPointTwo(dvalue).ToString("f1"); // 保留1位小数 + break; + case Accuracy.IntegerFloor: + result = Math.Floor(dvalue).ToString("F1"); // 直接取整 + break; + } + } + else + { + //工厂模式不量化 + switch (accuracy) + { + case Accuracy.ForceTwoDecimals: + result = (Math.Floor(dvalue * 100) / 100).ToString("f2"); + break; + case Accuracy.HalfStepRounding: + case Accuracy.ForceOneDecimal: + case Accuracy.DecimalTwoStepRounding: + case Accuracy.IntegerFloor: + case Accuracy.MultipleOfFive: + result = (Math.Floor(dvalue * 10) / 10).ToString("f1"); + break; + } + } + return result; + } [Log] public static double RoundFiveDownSixUp(double value) @@ -132,6 +192,22 @@ public static class DoubleDataFormatHelper { return (Math.Floor(value * 100) / 100).ToString("f2"); } - + public static Accuracy ToAccuracy(this string value) + { + if (string.IsNullOrEmpty(value)) + throw new ArgumentNullException(nameof(value), "输入值不能为空"); + + if (int.TryParse(value, out int numericValue)) + { + if (Enum.IsDefined(typeof(Accuracy), numericValue)) + return (Accuracy)numericValue; + } + + // 尝试按名称转换(处理ForceTwoDecimals等情况) + if (Enum.TryParse<Accuracy>(value, true, out var result)) + return result; + + throw new ArgumentException($"无法将值 '{value}' 转换为有效的Accuracy枚举", nameof(value)); + } } \ No newline at end of file diff --git a/Model/GradeResult/Helper/ViewDataInfoHelper.cs b/Model/GradeResult/Helper/ViewDataInfoHelper.cs index 2cf286b..6b5ca9a 100644 --- a/Model/GradeResult/Helper/ViewDataInfoHelper.cs +++ b/Model/GradeResult/Helper/ViewDataInfoHelper.cs @@ -1,4 +1,6 @@ using BrilliantSightClient.Model.Entity.ApiEntity; +using BrilliantSightClient.Model.Extension; +using BrilliantSightClient.Model.GradeLevel; using BrilliantSightClient.Model.GradeLevel.Helper; using BrilliantSightClient.Model.GradeResult.Entity; using BrilliantSightClient.Model.GradeResult.Entity.Enums; @@ -15,7 +17,7 @@ public class ViewDataInfoHelper { public static List<DataInfo> GenerateDataInfos(AlgorithmResultEntity result) { - JToken measurements = JToken.Parse(JsonConvert.SerializeObject(result.Measurements)); + JToken jData = JToken.Parse(JsonConvert.SerializeObject(result.Measurements)); List<DataInfo> dataInfos = new List<DataInfo>(); int shape = EntityHelper.GetValueFromName<DiamondShape>(result.Shape)??-1; if(shape == -1) throw new Exception("Unsupported shapes"); @@ -24,11 +26,101 @@ public class ViewDataInfoHelper foreach (var viewData in showViewData) { DataInfo dataInfo = new DataInfo(); - + dataInfo.TestItemId = viewData.InfoPath; + dataInfo.TestItemName = "Name".Equals(MultilingualHelper.getString("ColumnNameBase"))? viewData.Name : viewData.EName; + if(!viewData.AvgKey.IsNullOrEmpty()) + dataInfo.Avg = DoubleDataFormatHelper.FormatDouble(jData[viewData.AvgKey], viewData.AvgType.ToAccuracy()); + if(!viewData.DevKey.IsNullOrEmpty()) + dataInfo.Dev = DoubleDataFormatHelper.FormatDouble(jData[viewData.DevKey], viewData.DevType.ToAccuracy()); + if(!viewData.MaxKey.IsNullOrEmpty()) + dataInfo.Max = DoubleDataFormatHelper.FormatDouble(jData[viewData.MaxKey], viewData.MaxType.ToAccuracy()); + if(!viewData.MinKey.IsNullOrEmpty()) + dataInfo.Min = DoubleDataFormatHelper.FormatDouble(jData[viewData.MinKey], viewData.MinType.ToAccuracy()); + if (!viewData.DtlKey.IsNullOrEmpty()) + { + List<string> dtlDoubles = GenerateDtlDoubles(jData, viewData); + dataInfo.Dtl1 = dtlDoubles[0]; + dataInfo.Dtl2 = dtlDoubles[1]; + dataInfo.Dtl3 = dtlDoubles[2]; + dataInfo.Dtl4 = dtlDoubles[3]; + dataInfo.Dtl5 = dtlDoubles[4]; + dataInfo.Dtl6 = dtlDoubles[5]; + dataInfo.Dtl7 = dtlDoubles[6]; + dataInfo.Dtl8 = dtlDoubles[7]; + } + + GradeLevelCalculator levelCalculator = new GradeLevelCalculator(result); + dataInfos.Add(dataInfo); } return dataInfos; } - - + + public static List<string> GenerateDtlDoubles(JToken data, ViewData viewData) + { + List<string> result = new List<string>(); + int.TryParse(viewData.DtlCt, out int dtlCt); + JToken? jToken = data[viewData.DtlKey]; + if (jToken == null) return result; + + for (int i = 1; i <= dtlCt; i++) + { + result.Add(DoubleDataFormatHelper.FormatDouble(jToken[$"{viewData.DtlAttr}_{i}"], viewData.DtlType.ToAccuracy())); + } + return ProcessList(result); + } + /// <summary> + /// 处理字符串列表,确保返回列表长度为8 + /// 超过8个元素时保留最大值和最小值并缩减到8个元素 + /// 不足8个元素时用空字符串补足 + /// </summary> + /// <param name="result">输入的字符串列表,所有元素应可转换为double</param> + /// <returns>处理后的字符串列表,长度固定为8</returns> + public static List<string> ProcessList(List<string> result) + { + if (result == null) + throw new ArgumentNullException(nameof(result)); + if (result.Count < 8) + { + var paddedList = new List<string>(result); + while (paddedList.Count < 8) + { + paddedList.Add(string.Empty); + } + return paddedList; + } + var indexedValues = result + .Select((value, index) => new { Value = double.Parse(value), Index = index }) + .ToList(); + var max = indexedValues.OrderByDescending(x => x.Value).First(); + var min = indexedValues.OrderBy(x => x.Value).First(); + var remaining = indexedValues + .Where(x => x.Index != max.Index && x.Index != min.Index) + .ToList(); + if (remaining.Count <= 6) + { + var resultList = new List<string> + { + result[max.Index], + result[min.Index] + }; + resultList.AddRange(remaining.Select(x => result[x.Index])); + while (resultList.Count < 8) + { + resultList.Add(string.Empty); + } + return resultList; + } + var sampledIndices = new List<int>(); + for (int i = 0; i < 6; i++) + { + int index = (int)Math.Round(i * (remaining.Count - 1) / 5.0); + sampledIndices.Add(remaining[index].Index); + } + var finalList = new List<string> { result[max.Index] }; + finalList.AddRange(sampledIndices.Select(i => result[i])); + finalList.Add(result[min.Index]); + + return finalList; + } } \ No newline at end of file diff --git a/Model/Helper/DataBaseHelper.cs b/Model/Helper/DataBaseHelper.cs index bf86d4b..cc6d9d5 100644 --- a/Model/Helper/DataBaseHelper.cs +++ b/Model/Helper/DataBaseHelper.cs @@ -203,6 +203,6 @@ public class DataBaseHelper Logger.Error($"全局异常捕获:{ex.Message}", ex); System.Windows.MessageBox.Show($"{MultilingualHelper.getString("ApplicationError")}{ex.Message}"); } - return null; + return new List<T>(); } } \ No newline at end of file diff --git a/Views/Dialog/ImageSelect.xaml b/Views/Dialog/ImageSelect.xaml index 1f74b38..8f6aec5 100644 --- a/Views/Dialog/ImageSelect.xaml +++ b/Views/Dialog/ImageSelect.xaml @@ -66,7 +66,7 @@ <Label Grid.Row="2" Grid.Column="1" HorizontalAlignment="right" Content="文件名格式" Background="Transparent" BorderBrush="Transparent" FontSize="16" FontFamily="AlibabaPuHui-regular" /> - <TextBox Grid.Row="2" Grid.ColumnSpan="1" TextWrapping="Wrap" x:Name ="FileName" Grid.Column="2" Text="%d.bmp"/> + <TextBox Grid.Row="2" Grid.ColumnSpan="1" TextWrapping="Wrap" x:Name ="FileName" Grid.Column="2" Text="image_%d.bmp"/> </Grid> <Grid> <Grid.ColumnDefinitions>