using BrilliantSightClient.Model.Entity.ApiEntity; using BrilliantSightClient.Model.Extension; 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; using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace BrilliantSightClient.Model.GradeLevel; public class GradeLevelCalculator { AlgorithmResultEntity _diamondResult; public bool IsInitialized = false; private JToken _diamondData; GradeLevelMst _masterLevel; private List _gradeLevelCutSets; private List _gradeLevelSymSets; public List GradeLevelCutSets { get => _gradeLevelCutSets; } public List GradeLevelSymSets { get => _gradeLevelSymSets; } private bool CutIsMultiDimensional = false; private string CutMultiDimensionalSign = string.Empty; private bool SymIsMultiDimensional = false; private string SymMultiDimensionalSign = string.Empty; private List _gradeLevelDataSets; private List _gradeLevelCutTreeSets; private List _gradeLevelSymTreeSets; private List _gradeLevelSetDtls; private GradeLevelTotalSet _gradeLevelCutTotalSet; private GradeLevelTotalSet _gradeLevelSymTotalSet; public GradeLevelCalculator(AlgorithmResultEntity entity) { _diamondResult = entity; _diamondData = JToken.Parse(JsonConvert.SerializeObject(entity.Measurements)); 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.Replace("P","")}' and PAVILION = '{entity.PavType.Replace("P","")}'" ; var masterLevel = DataBaseHelper.ExecuteQuery(masterSql); if (masterLevel.Count == 0) return; _masterLevel = masterLevel.First(); var setsSql = $"select * from GRADE_LEVEL_SET where MST_SIGN = '{_masterLevel.Sign}'"; var levelSets = DataBaseHelper.ExecuteQuery(setsSql); if (levelSets.Count == 0) return; _gradeLevelCutSets = levelSets.FindAll(x => x.Set_Type == GradeType.Cut.GetValue()); _gradeLevelSymSets = levelSets.FindAll(x => x.Set_Type == GradeType.Sym.GetValue()); var dataSetSql = $"select * from GRADE_LEVEL_DATA_SET where MST_SIGN = '{_masterLevel.Sign}'"; _gradeLevelDataSets = DataBaseHelper.ExecuteQuery(dataSetSql); var treeSetSql = $"select * from GRADE_LEVEL_TREE_SET where MST_SIGN = '{_masterLevel.Sign}'"; var treeSets = DataBaseHelper.ExecuteQuery(treeSetSql); _gradeLevelCutTreeSets = treeSets.FindAll(x => x.NodeType - 1 == GradeType.Cut.GetValue()); _gradeLevelSymTreeSets = treeSets.FindAll(x => x.NodeType - 1 == GradeType.Sym.GetValue()); CutIsMultiDimensional = _gradeLevelCutTreeSets.Count() > 1; SymIsMultiDimensional = _gradeLevelSymTreeSets.Count() > 1; var setDtlSql = $"select * from GRADE_LEVEL_SET_DTL where MST_SIGN = '{_masterLevel.Sign}'"; _gradeLevelSetDtls = DataBaseHelper.ExecuteQuery(setDtlSql); var totalSetSql = $"select * from GRADE_LEVEL_TOTAL_SET where MST_SIGN = '{_masterLevel.Sign}'"; var totalSets = DataBaseHelper.ExecuteQuery(totalSetSql); _gradeLevelCutTotalSet = totalSets.FindAll(x => x.Set_Type == GradeType.Cut.GetValue()).First(); _gradeLevelSymTotalSet = totalSets.FindAll(x => x.Set_Type == GradeType.Sym.GetValue()).First(); IsInitialized = true; } public GradeLevelSet? GetCutGradeLevelSet(string key, DataInfo dataInfo) { if (IsInitialized == false) return null; if("GIRDLE_VALLEY".Equals(key))key = "GIRDLE"; GradeLevelDataSet? dataSet = _gradeLevelDataSets.FirstOrDefault(x => x.KName.Equals(key)); if (dataSet == null) return null; //检查是否多维度 if (CutIsMultiDimensional) { //多维度 List cutTree = _gradeLevelCutTreeSets.FindAll(x => x.IsTop == 0); if(cutTree.Count <= 0) return null; GradeLevelDataSet? dimensionKey = _gradeLevelDataSets.FirstOrDefault(x => cutTree.First().DimensionSign == x.Sign); if (dimensionKey == null) return null; CutMultiDimensionalSign = string.IsNullOrWhiteSpace(CutMultiDimensionalSign)?DimensionTreeSign(dimensionKey, cutTree):CutMultiDimensionalSign; if ("1".Equals(CutMultiDimensionalSign) || "-1".Equals(CutMultiDimensionalSign)) { return _gradeLevelCutSets.OrderByDescending(set => set.Short).FirstOrDefault(); } return GetFinalCutGrade(CutMultiDimensionalSign, key, dataInfo); } else { //单维度 return GetFinalCutGrade(_gradeLevelCutTreeSets.First().Sign, key, dataInfo); } } public GradeLevelSet? GetCutTotalGradeLevelSet(List dataInfos) { if (IsInitialized == false) return null; return CalculateTotalGrade(dataInfos, _gradeLevelCutTotalSet, _gradeLevelCutSets); } public GradeLevelSet? GetSymGradeLevelSet(string key, DataInfo dataInfo) { if (IsInitialized == false) return null; if("GIRDLE_VALLEY".Equals(key))key = "GIRDLE"; GradeLevelDataSet? dataSet = _gradeLevelDataSets.FirstOrDefault(x => x.KName.Equals(key)); if (dataSet == null) return null; double value = string.IsNullOrWhiteSpace(dataInfo.Dev) ? dataInfo.Avg.ToDouble() : dataInfo.Dev.ToDouble(); // 检查是否多维度 if (SymIsMultiDimensional) { // 多维度 List symTree = _gradeLevelSymTreeSets.FindAll(x => x.IsTop == 0); if (symTree.Count <= 0) return null; GradeLevelDataSet? dimensionKey = _gradeLevelDataSets.FirstOrDefault(x => symTree.First().DimensionSign == x.Sign); if (dimensionKey == null) return null; SymMultiDimensionalSign = string.IsNullOrWhiteSpace(SymMultiDimensionalSign)?DimensionTreeSign(dimensionKey, symTree):SymMultiDimensionalSign; if ("1".Equals(SymMultiDimensionalSign) || "-1".Equals(SymMultiDimensionalSign)) { return _gradeLevelSymSets.OrderByDescending(set => set.Short).FirstOrDefault(); } return GetFinalSymGrade(SymMultiDimensionalSign, key, value); } else { // 单维度 return GetFinalSymGrade(_gradeLevelSymTreeSets.First().Sign, key, value); } } public GradeLevelSet GetSymTotalGradeLevelSet(List dataInfos) { if (IsInitialized == false) return null; return CalculateTotalGrade(dataInfos, _gradeLevelSymTotalSet, _gradeLevelSymSets); } private string DimensionTreeSign(GradeLevelDataSet dimensionKey, List cutTree) { string dimensionTreeSign = string.Empty; try { // 从JToken中获取对应路径的值 JToken? dimensionValueToken = _diamondData.SelectToken(dimensionKey.KName); if (dimensionValueToken == null) return string.Empty; // 转换为double并进行计算 if (double.TryParse(dimensionValueToken.ToString(), out double dimensionValue)) { // 乘以100并四舍五入取整 int roundedValue = (int)Math.Round(dimensionValue*100, MidpointRounding.AwayFromZero); // 循环查找有效树 int currentRoundedValue = roundedValue; while (true) { // 获取所有维度值并排序 var dimensionValues = cutTree .Where(x => !string.IsNullOrEmpty(x.DimensionValue)) .Select(x => { if (int.TryParse(x.DimensionValue, out int value)) return new { Value = value, Sign = x.Sign }; return null; }) .Where(x => x != null) .OrderBy(x => x.Value) .ToList(); if (!dimensionValues.Any()) break; // 无维度值时退出 // 判断当前roundedValue对应的树 var matchedDimension = dimensionValues.FirstOrDefault(x => x.Value == currentRoundedValue); if (matchedDimension != null) { dimensionTreeSign = matchedDimension.Sign; // 检查当前树是否有有效定级配置 if (HasValidGradeConfig(dimensionTreeSign)) { return dimensionTreeSign; } } else if (currentRoundedValue > dimensionValues.Max(x => x.Value)) { dimensionTreeSign = "1"; if (HasValidGradeConfig(dimensionTreeSign)) { return dimensionTreeSign; } break; // 最大树无效时不再查找 } else if (currentRoundedValue < dimensionValues.Min(x => x.Value)) { dimensionTreeSign = "-1"; if (HasValidGradeConfig(dimensionTreeSign)) { return dimensionTreeSign; } break; // 最小树无效时不再查找 } // 未找到有效树时,尝试下一个树(DimensionValue+1) currentRoundedValue++; if (currentRoundedValue > dimensionValues.Max(x => x.Value)) { break; // 超出最大维度值时退出 } } } } catch { // 处理异常,返回空白 dimensionTreeSign = string.Empty; } return dimensionTreeSign; } // 检查树是否有有效定级配置 private bool HasValidGradeConfig(string treeSign) { var validConfigs = _gradeLevelSetDtls .Where(dtl => dtl.Tree_Sign == treeSign) .Where(dtl => !(dtl.Max_Value == double.MaxValue && dtl.Min_Value == double.MinValue) && !(dtl.Max_Value == 0 && dtl.Min_Value == 0) ) .ToList(); return validConfigs.Any(); } public GradeLevelSet? GetFinalCutGrade(string treeSign, string key, DataInfo dataInfo) { if (IsInitialized == false) return null; // 通过TreeSign和Key关联获取子集 var dataSet = _gradeLevelDataSets.FirstOrDefault(ds => ds.KName == key); if (dataSet == null) return null; var filteredDtls = _gradeLevelSetDtls .Where(dtl => dtl.Tree_Sign == treeSign && dtl.DataSet_Sign == dataSet.Sign) .ToList(); if (!filteredDtls.Any()) return null; // 查找最大值和最小值对应的区间 List maxValDtls = new List(); List minValDtls = new List(); if (dataInfo.Max.ToDouble() == 0 && dataInfo.Min.ToDouble() == 0) { maxValDtls = filteredDtls .Where(dtl => dataInfo.Avg.ToDouble() >= dtl.Min_Value && dataInfo.Avg.ToDouble() <= dtl.Max_Value) .ToList(); minValDtls = filteredDtls .Where(dtl => dataInfo.Avg.ToDouble() >= dtl.Min_Value && dataInfo.Avg.ToDouble() <= dtl.Max_Value) .ToList(); } else { maxValDtls = filteredDtls .Where(dtl => dataInfo.Max.ToDouble() >= dtl.Min_Value && dataInfo.Max.ToDouble() <= dtl.Max_Value) .ToList(); minValDtls = filteredDtls .Where(dtl => dataInfo.Min.ToDouble() >= dtl.Min_Value && dataInfo.Min.ToDouble() <= dtl.Max_Value) .ToList(); } // 获取对应的GradeLevelSet集合 var associatedLevelSets = _gradeLevelCutSets .Where(ls => filteredDtls.Any(dtl => dtl.Level_Sign == ls.Sign)) .ToList(); // 处理最大值的情况 GradeLevelSet? maxLevel = null; if (maxValDtls.Any()) { // 若有多个区间,取最差的(Short值最大) if (maxValDtls.Count > 1) { maxLevel = associatedLevelSets .Where(ls => maxValDtls.Any(dtl => dtl.Level_Sign == ls.Sign)) .OrderBy(ls => ls.Short) .FirstOrDefault(); } else { maxLevel = associatedLevelSets .FirstOrDefault(ls => ls.Sign == maxValDtls.First().Level_Sign); } } // 处理最小值的情况 GradeLevelSet? minLevel = null; if (minValDtls.Any()) { // 若有多个区间,取最差的(Short值最大) if (minValDtls.Count > 1) { minLevel = associatedLevelSets .Where(ls => minValDtls.Any(dtl => dtl.Level_Sign == ls.Sign)) .OrderBy(ls => ls.Short) .FirstOrDefault(); } else { minLevel = associatedLevelSets .FirstOrDefault(ls => ls.Sign == minValDtls.First().Level_Sign); } } // 若最大值和最小值都找到对应的区间,返回较差的一个 if (maxLevel != null && minLevel != null) { return maxLevel.Short > minLevel.Short ? maxLevel : minLevel; } // 若只有一个找到区间,返回该区间对应的级别 if (maxLevel != null) return maxLevel; if (minLevel != null) return minLevel; // 若都没找到,返回子集中最差的级别 return associatedLevelSets.OrderBy(ls => ls.Short).FirstOrDefault(); } private GradeLevelSet? GetFinalSymGrade(string treeSign, string key, double devVal) { // 通过TreeSign和Key关联获取子集 var dataSet = _gradeLevelDataSets.FirstOrDefault(ds => ds.KName == key); if (dataSet == null) return null; var filteredDtls = _gradeLevelSetDtls .Where(dtl => dtl.Tree_Sign == treeSign && dtl.DataSet_Sign == dataSet.Sign) .ToList(); if (!filteredDtls.Any()) return null; // 查找偏差值对应的区间 var devValDtls = filteredDtls .Where(dtl => devVal >= dtl.Min_Value && devVal <= dtl.Max_Value) .ToList(); // 获取对应的GradeLevelSet集合 var associatedLevelSets = _gradeLevelSymSets .Where(ls => filteredDtls.Any(dtl => dtl.Level_Sign == ls.Sign)) .ToList(); // 处理偏差值的情况 GradeLevelSet? devLevel = null; if (devValDtls.Any()) { // 若有多个区间,取最差的(Short值最大) if (devValDtls.Count > 1) { devLevel = associatedLevelSets .Where(ls => devValDtls.Any(dtl => dtl.Level_Sign == ls.Sign)) .OrderBy(ls => ls.Short) .FirstOrDefault(); } else { devLevel = associatedLevelSets .FirstOrDefault(ls => ls.Sign == devValDtls.First().Level_Sign); } } // 若找到对应的区间,返回该区间对应的级别 if (devLevel != null) return devLevel; // 若没找到,返回子集中最差的级别 return associatedLevelSets.OrderByDescending(ls => ls.Short).FirstOrDefault(); } private GradeLevelSet CalculateTotalGrade(List dataInfos, GradeLevelTotalSet totalSet, List levelSets) { // 解析参与评级的数据签名 var dataSigns = totalSet.DataSigns.Split(',', StringSplitOptions.RemoveEmptyEntries); // 找出所有参与评级的项目对应的评级 var gradeLevels = new List(); foreach (var dataSign in dataSigns) { var dataSet = _gradeLevelDataSets.FirstOrDefault(ds => ds.Sign == dataSign); if (dataSet == null) continue; var dataInfo = dataInfos.FirstOrDefault(di => di.TestItemId == dataSet.KName); if (dataInfo == null) continue; GradeLevelSet? gradeLevel = null; if (totalSet.Set_Type == GradeType.Cut.GetValue()) { // 切工评级 gradeLevel = GetCutGradeLevelSet(dataSet.KName, dataInfo); } else if (totalSet.Set_Type == GradeType.Sym.GetValue()) { // 对称评级 gradeLevel = GetSymGradeLevelSet(dataSet.KName, dataInfo); } if (gradeLevel != null) { gradeLevels.Add(gradeLevel); } } // 若没有找到任何评级,返回默认最差评级 if (!gradeLevels.Any()) { return levelSets.OrderByDescending(ls => ls.Short).FirstOrDefault() ?? throw new NotGradeSetException("无法计算总评级,没有找到有效的评级数据"); } // 根据统计方式聚合评级 switch (totalSet.Statistics) { case 0: // 最大值(最差) return gradeLevels.OrderBy(ls => ls.Short).First(); case 1: // 最小值(最好) return gradeLevels.OrderByDescending(ls => ls.Short).First(); case 2: // 平均值 // 计算平均Short值 double averageShort = gradeLevels.Average(ls => ls.Short); // 找到最接近平均值的等级 return levelSets .OrderBy(ls => Math.Abs(ls.Short - averageShort)) .FirstOrDefault() ?? throw new NotGradeSetException("无法计算平均评级,没有找到匹配的等级"); default: throw new NotSupportedException($"不支持的统计方式: {totalSet.Statistics}"); } } }