update:计分规则修正
This commit is contained in:
parent
f4346d30cd
commit
f5f751eb63
@ -173,7 +173,7 @@ public static class ScoreSheetCalculationService
|
||||
/// <summary>
|
||||
/// 按计分规则计算一张评分单。
|
||||
/// requireAll 为 true(正式提交)时校验必填项与取值范围;为 false(保存草稿)时允许留空,只算已录入的部分。
|
||||
/// 花样赛的表现维度分、失误自动减分、规定元素缺失数一律由服务端联动生成,客户端传来的自动项不参与计算。
|
||||
/// 花样赛的表现维度分、失误联动项、规定元素缺失数一律由服务端生成,客户端传来的自动项不参与计算。
|
||||
/// </summary>
|
||||
public static ScoreSheetCalculationResult Calculate(List<ScoreItemDefinition> definitions,
|
||||
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.StepDeductions is { Count: > 0 }) continue;
|
||||
if (definition.Item.ScoreDimension == ScoreDimensionCode.Required
|
||||
&& definition.Item.ItemType == ScoreItemTypeCode.RequiredElement) continue;
|
||||
if (definition.Item.ItemType == ScoreItemTypeCode.RequiredElement) continue;
|
||||
|
||||
switch (definition.Item.ScoreDimension)
|
||||
{
|
||||
@ -239,11 +238,17 @@ public static class ScoreSheetCalculationService
|
||||
result.RequiredScore = config.Round(result.RequiredScore);
|
||||
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
|
||||
? 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;
|
||||
}
|
||||
|
||||
@ -257,7 +262,9 @@ public static class ScoreSheetCalculationService
|
||||
var mode = definitions.Select(x => x.DifficultyAggregate).FirstOrDefault(x => !string.IsNullOrEmpty(x));
|
||||
if (mode == null) return;
|
||||
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);
|
||||
if (actionCount <= 0m)
|
||||
{
|
||||
@ -296,7 +303,8 @@ public static class ScoreSheetCalculationService
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 表现维度计算。页面减数量 = 人工减 + 失误自动减;按规则公式还需单独减失误次数。
|
||||
/// 表现维度计算。个人花样的失误单独参与总成绩扣分,不进入表现分;
|
||||
/// 其他花样项目沿用失误联动表现维度的既有口径。
|
||||
/// 每个维度 = 基准分 + 人工加 - (人工减 + 失误自动减) - 失误次数,限制在上下限内,
|
||||
/// 再按各维度权重加权求和得到本裁判的表现分。失误自动减分作为自动项落明细,裁判不可直接修改。
|
||||
/// </summary>
|
||||
@ -308,11 +316,16 @@ public static class ScoreSheetCalculationService
|
||||
.ToList();
|
||||
if (dimensions.Count == 0) return;
|
||||
|
||||
// 失误数联动五个维度各自动减 1 次。
|
||||
// 个人花样的失误由成绩汇总中的 M 系数单独处理,不能再降低本裁判的表现分。
|
||||
var failure = definitions.FirstOrDefault(x => x.IsFailureCount);
|
||||
var failureCount = failure == null
|
||||
? 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;
|
||||
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;
|
||||
raw += adjust.AdjustSign * count * (adjust.Item.UnitValue ?? 1m);
|
||||
}
|
||||
// 失误同时增加页面减数量,并作为公式中的独立失误项再扣一次。
|
||||
raw -= failureCount * 2m * (dimension.Item.UnitValue ?? 1m);
|
||||
// 其他花样项目沿用失误联动;个人花样这里不扣,汇总时由 M 系数处理。
|
||||
raw -= performanceFailureCount * 2m * (dimension.Item.UnitValue ?? 1m);
|
||||
// 维度分限制在规则给出的上下限内(规程为 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;
|
||||
|
||||
result.Lines.Add(new ScoreSheetLine
|
||||
@ -341,12 +356,16 @@ public static class ScoreSheetCalculationService
|
||||
InputValue = value, UnitValue = dimension.Item.UnitValue, Subtotal = value,
|
||||
Sort = dimension.Item.Sort, IsAutoGenerated = true,
|
||||
SubjectCode = dimension.SubjectCode,
|
||||
ParentItemCode = failure?.ItemCode
|
||||
ParentItemCode = performanceFailureCount > 0m ? failure?.ItemCode : null
|
||||
});
|
||||
result.Steps.Add(new ScoreSheetStep
|
||||
{
|
||||
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
|
||||
});
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user