From 35e40c6dd880c812db317e814f7e6806455edb38 Mon Sep 17 00:00:00 2001 From: tongg 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 @@ 取消网络质量检测 当前网络传输效率低,可能影响检测效率! + + Name + \ 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 _gradeLevelCutSets; + private List _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(entity.Shape)} and CROWN = {entity.CrownType} and PAVILION = {entity.PavType}" ; + var masterLevel = DataBaseHelper.ExecuteQuery(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(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; } + /// + /// 百分比用的小数格式化 + /// + /// + /// + [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(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 GenerateDataInfos(AlgorithmResultEntity result) { - JToken measurements = JToken.Parse(JsonConvert.SerializeObject(result.Measurements)); + JToken jData = JToken.Parse(JsonConvert.SerializeObject(result.Measurements)); List dataInfos = new List(); int shape = EntityHelper.GetValueFromName(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 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 GenerateDtlDoubles(JToken data, ViewData viewData) + { + List result = new List(); + 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); + } + /// + /// 处理字符串列表,确保返回列表长度为8 + /// 超过8个元素时保留最大值和最小值并缩减到8个元素 + /// 不足8个元素时用空字符串补足 + /// + /// 输入的字符串列表,所有元素应可转换为double + /// 处理后的字符串列表,长度固定为8 + public static List ProcessList(List result) + { + if (result == null) + throw new ArgumentNullException(nameof(result)); + if (result.Count < 8) + { + var paddedList = new List(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 + { + 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(); + 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 { 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(); } } \ 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 @@