update:计分规则修正
This commit is contained in:
parent
f4346d30cd
commit
f5f751eb63
@ -173,7 +173,7 @@ public static class ScoreSheetCalculationService
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 按计分规则计算一张评分单。
|
/// 按计分规则计算一张评分单。
|
||||||
/// requireAll 为 true(正式提交)时校验必填项与取值范围;为 false(保存草稿)时允许留空,只算已录入的部分。
|
/// requireAll 为 true(正式提交)时校验必填项与取值范围;为 false(保存草稿)时允许留空,只算已录入的部分。
|
||||||
/// 花样赛的表现维度分、失误自动减分、规定元素缺失数一律由服务端联动生成,客户端传来的自动项不参与计算。
|
/// 花样赛的表现维度分、失误联动项、规定元素缺失数一律由服务端生成,客户端传来的自动项不参与计算。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static ScoreSheetCalculationResult Calculate(List<ScoreItemDefinition> definitions,
|
public static ScoreSheetCalculationResult Calculate(List<ScoreItemDefinition> definitions,
|
||||||
List<ScoreItemInputValue> inputs, ScoreRuleConfig config, bool requireAll)
|
List<ScoreItemInputValue> inputs, ScoreRuleConfig config, bool requireAll)
|
||||||
@ -213,8 +213,7 @@ public static class ScoreSheetCalculationService
|
|||||||
// 表现维度的加减项、递增扣分项、规定元素计数项各有专门算法,不按小计直接累加。
|
// 表现维度的加减项、递增扣分项、规定元素计数项各有专门算法,不按小计直接累加。
|
||||||
if (definition.DimensionCode != null && definition.AdjustSign != 0) continue;
|
if (definition.DimensionCode != null && definition.AdjustSign != 0) continue;
|
||||||
if (definition.StepDeductions is { Count: > 0 }) continue;
|
if (definition.StepDeductions is { Count: > 0 }) continue;
|
||||||
if (definition.Item.ScoreDimension == ScoreDimensionCode.Required
|
if (definition.Item.ItemType == ScoreItemTypeCode.RequiredElement) continue;
|
||||||
&& definition.Item.ItemType == ScoreItemTypeCode.RequiredElement) continue;
|
|
||||||
|
|
||||||
switch (definition.Item.ScoreDimension)
|
switch (definition.Item.ScoreDimension)
|
||||||
{
|
{
|
||||||
@ -239,11 +238,17 @@ public static class ScoreSheetCalculationService
|
|||||||
result.RequiredScore = config.Round(result.RequiredScore);
|
result.RequiredScore = config.Round(result.RequiredScore);
|
||||||
result.DeductionScore = config.Round(result.DeductionScore);
|
result.DeductionScore = config.Round(result.DeductionScore);
|
||||||
}
|
}
|
||||||
// 花样赛的规定元素完成量只用于跨裁判聚合时计算 Q,不能加进单张评分单的本裁判得分。
|
// 难度裁判的规定元素完成量仅作为独立记录,不能计入本裁判难度分。
|
||||||
// 最终 R 仍由跨裁判聚合按 D×(1+P)×Q×M 计算;规定赛保留原有加总口径。
|
// 同时兼容尚未配置 factor 模式的个人花样规则;规定赛完成质量裁判仍保留 RequiredScore 加总。
|
||||||
|
var isDifficultySheet = definitions.Any(x => !x.IsAuto &&
|
||||||
|
x.Item.ItemType != ScoreItemTypeCode.RequiredElement &&
|
||||||
|
(x.Item.ItemType == ScoreItemTypeCode.DifficultyCount ||
|
||||||
|
x.Item.ScoreDimension == ScoreDimensionCode.Difficulty));
|
||||||
|
var requiredContribution = isDifficultySheet ? 0m : result.RequiredScore;
|
||||||
|
// 花样赛最终 R 仍由跨裁判聚合按 D×(1+P)×Q×M 计算。
|
||||||
result.TotalScore = config.IsFactorTotal
|
result.TotalScore = config.IsFactorTotal
|
||||||
? config.Round(result.DifficultyScore + result.PerformanceScore)
|
? config.Round(result.DifficultyScore + result.PerformanceScore)
|
||||||
: config.Round(result.DifficultyScore + result.PerformanceScore + result.RequiredScore - result.DeductionScore);
|
: config.Round(result.DifficultyScore + result.PerformanceScore + requiredContribution - result.DeductionScore);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,7 +262,9 @@ public static class ScoreSheetCalculationService
|
|||||||
var mode = definitions.Select(x => x.DifficultyAggregate).FirstOrDefault(x => !string.IsNullOrEmpty(x));
|
var mode = definitions.Select(x => x.DifficultyAggregate).FirstOrDefault(x => !string.IsNullOrEmpty(x));
|
||||||
if (mode == null) return;
|
if (mode == null) return;
|
||||||
var difficultyLines = result.Lines
|
var difficultyLines = result.Lines
|
||||||
.Where(x => x.ScoreDimension == ScoreDimensionCode.Difficulty && x.CountValue is > 0m).ToList();
|
.Where(x => x.ItemType != ScoreItemTypeCode.RequiredElement &&
|
||||||
|
x.ScoreDimension == ScoreDimensionCode.Difficulty &&
|
||||||
|
x.CountValue is > 0m).ToList();
|
||||||
var actionCount = difficultyLines.Sum(x => x.CountValue!.Value);
|
var actionCount = difficultyLines.Sum(x => x.CountValue!.Value);
|
||||||
if (actionCount <= 0m)
|
if (actionCount <= 0m)
|
||||||
{
|
{
|
||||||
@ -296,7 +303,8 @@ public static class ScoreSheetCalculationService
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 表现维度计算。页面减数量 = 人工减 + 失误自动减;按规则公式还需单独减失误次数。
|
/// 表现维度计算。个人花样的失误单独参与总成绩扣分,不进入表现分;
|
||||||
|
/// 其他花样项目沿用失误联动表现维度的既有口径。
|
||||||
/// 每个维度 = 基准分 + 人工加 - (人工减 + 失误自动减) - 失误次数,限制在上下限内,
|
/// 每个维度 = 基准分 + 人工加 - (人工减 + 失误自动减) - 失误次数,限制在上下限内,
|
||||||
/// 再按各维度权重加权求和得到本裁判的表现分。失误自动减分作为自动项落明细,裁判不可直接修改。
|
/// 再按各维度权重加权求和得到本裁判的表现分。失误自动减分作为自动项落明细,裁判不可直接修改。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -308,11 +316,16 @@ public static class ScoreSheetCalculationService
|
|||||||
.ToList();
|
.ToList();
|
||||||
if (dimensions.Count == 0) return;
|
if (dimensions.Count == 0) return;
|
||||||
|
|
||||||
// 失误数联动五个维度各自动减 1 次。
|
// 个人花样的失误由成绩汇总中的 M 系数单独处理,不能再降低本裁判的表现分。
|
||||||
var failure = definitions.FirstOrDefault(x => x.IsFailureCount);
|
var failure = definitions.FirstOrDefault(x => x.IsFailureCount);
|
||||||
var failureCount = failure == null
|
var failureCount = failure == null
|
||||||
? 0m
|
? 0m
|
||||||
: result.Lines.FirstOrDefault(x => string.Equals(x.ItemCode, failure.ItemCode, StringComparison.OrdinalIgnoreCase))?.CountValue ?? 0m;
|
: result.Lines.FirstOrDefault(x => string.Equals(x.ItemCode, failure.ItemCode, StringComparison.OrdinalIgnoreCase))?.CountValue ?? 0m;
|
||||||
|
var isIndividualFreestyle = string.Equals(config.RuleType, "FREESTYLE_SINGLE", StringComparison.OrdinalIgnoreCase);
|
||||||
|
var performanceFailureCount = isIndividualFreestyle ? 0m : failureCount;
|
||||||
|
var hasPerformanceMarks = definitions.Any(x => !x.IsAuto && x.AdjustSign != 0 &&
|
||||||
|
result.Lines.Any(line => string.Equals(line.ItemCode, x.ItemCode, StringComparison.OrdinalIgnoreCase)
|
||||||
|
&& line.CountValue is > 0m));
|
||||||
|
|
||||||
var weighted = 0m;
|
var weighted = 0m;
|
||||||
foreach (var dimension in dimensions)
|
foreach (var dimension in dimensions)
|
||||||
@ -328,10 +341,12 @@ public static class ScoreSheetCalculationService
|
|||||||
.FirstOrDefault(x => string.Equals(x.ItemCode, adjust.ItemCode, StringComparison.OrdinalIgnoreCase))?.CountValue ?? 0m;
|
.FirstOrDefault(x => string.Equals(x.ItemCode, adjust.ItemCode, StringComparison.OrdinalIgnoreCase))?.CountValue ?? 0m;
|
||||||
raw += adjust.AdjustSign * count * (adjust.Item.UnitValue ?? 1m);
|
raw += adjust.AdjustSign * count * (adjust.Item.UnitValue ?? 1m);
|
||||||
}
|
}
|
||||||
// 失误同时增加页面减数量,并作为公式中的独立失误项再扣一次。
|
// 其他花样项目沿用失误联动;个人花样这里不扣,汇总时由 M 系数处理。
|
||||||
raw -= failureCount * 2m * (dimension.Item.UnitValue ?? 1m);
|
raw -= performanceFailureCount * 2m * (dimension.Item.UnitValue ?? 1m);
|
||||||
// 维度分限制在规则给出的上下限内(规程为 0~24)并取整。
|
// 维度分限制在规则给出的上下限内(规程为 0~24)并取整。
|
||||||
var value = Math.Clamp(Math.Round(raw, 0, MidpointRounding.AwayFromZero), dimension.MinValue, dimension.MaxValue);
|
var value = isIndividualFreestyle && !hasPerformanceMarks
|
||||||
|
? 0m
|
||||||
|
: Math.Clamp(Math.Round(raw, 0, MidpointRounding.AwayFromZero), dimension.MinValue, dimension.MaxValue);
|
||||||
weighted += value * dimension.DimensionWeight!.Value;
|
weighted += value * dimension.DimensionWeight!.Value;
|
||||||
|
|
||||||
result.Lines.Add(new ScoreSheetLine
|
result.Lines.Add(new ScoreSheetLine
|
||||||
@ -341,12 +356,16 @@ public static class ScoreSheetCalculationService
|
|||||||
InputValue = value, UnitValue = dimension.Item.UnitValue, Subtotal = value,
|
InputValue = value, UnitValue = dimension.Item.UnitValue, Subtotal = value,
|
||||||
Sort = dimension.Item.Sort, IsAutoGenerated = true,
|
Sort = dimension.Item.Sort, IsAutoGenerated = true,
|
||||||
SubjectCode = dimension.SubjectCode,
|
SubjectCode = dimension.SubjectCode,
|
||||||
ParentItemCode = failure?.ItemCode
|
ParentItemCode = performanceFailureCount > 0m ? failure?.ItemCode : null
|
||||||
});
|
});
|
||||||
result.Steps.Add(new ScoreSheetStep
|
result.Steps.Add(new ScoreSheetStep
|
||||||
{
|
{
|
||||||
Code = $"DIM_{dimension.DimensionCode}", Label = dimension.Item.ItemName,
|
Code = $"DIM_{dimension.DimensionCode}", Label = dimension.Item.ItemName,
|
||||||
Formula = $"{Trim(dimension.BaseValue ?? 0m)} + 人工加 - (人工减 + 失误联动减{Trim(failureCount)}) - 失误{Trim(failureCount)}次",
|
Formula = isIndividualFreestyle && !hasPerformanceMarks
|
||||||
|
? "尚未录入表现加减,表现分为 0;失误单独计入扣分"
|
||||||
|
: isIndividualFreestyle
|
||||||
|
? $"{Trim(dimension.BaseValue ?? 0m)} + 人工加 - 人工减(失误单独计入扣分)"
|
||||||
|
: $"{Trim(dimension.BaseValue ?? 0m)} + 人工加 - (人工减 + 失误联动减{Trim(performanceFailureCount)}) - 失误{Trim(performanceFailureCount)}次",
|
||||||
Value = value
|
Value = value
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user