完成质量裁判
This commit is contained in:
parent
0be9c0d3c1
commit
11aad4e245
@ -21,6 +21,22 @@ class DeductionRuleItem {
|
||||
}
|
||||
|
||||
abstract final class DeductionRuleCatalog {
|
||||
/// 服务端规定赛扣分项编码到平板控件键的映射。
|
||||
/// 名称文案存在“运动员的”“每人”等差异,提交与草稿恢复必须按编码匹配。
|
||||
static const prescribedServerItemAliases = <String, String>{
|
||||
'T_DED_ROPE_SALUTE': '赛前或赛后未行绳礼(每队)',
|
||||
'T_DED_APPEARANCE': '头发、着装、仪容不符合规定,佩戴饰物或饰物掉落(每人)',
|
||||
'T_DED_CHANGE_1X8': '更改1×8拍规定元素内容',
|
||||
'T_DED_INTERRUPT': '套路中断4秒以上',
|
||||
'T_DED_AREA_FOUL': '场地犯规(踩线/出界,仅个人花样规定套路)',
|
||||
// 兼容旧版内置规则编码。
|
||||
'T_NO_ROPE_SALUTE': '赛前或赛后未行绳礼(每队)',
|
||||
'T_APPEARANCE': '头发、着装、仪容不符合规定,佩戴饰物或饰物掉落(每人)',
|
||||
'T_CHANGE_1X8': '更改1×8拍规定元素内容',
|
||||
'T_INTERRUPT_4S': '套路中断4秒以上',
|
||||
'T_VENUE_FOUL': '场地犯规(踩线/出界,仅个人花样规定套路)',
|
||||
};
|
||||
|
||||
static const _mistake = DeductionRuleItem(
|
||||
key: '失误',
|
||||
label: '失误',
|
||||
|
||||
@ -20,6 +20,14 @@ class ExecutionScoreCriterion {
|
||||
}
|
||||
|
||||
abstract final class PrescribedExecutionRuleCatalog {
|
||||
static const displayLabels = <String, String>{
|
||||
'动作准确性': '动作的准确性(个人30分/集体20分)',
|
||||
'动作熟练性': '动作的熟练性(个人20分/集体15分)',
|
||||
'动作合拍性': '动作的合拍性(个人30分/集体15分)',
|
||||
'运动能力一致性': '运动能力一致性(集体15分)',
|
||||
'表演技巧一致性': '表演技巧一致性(集体15分)',
|
||||
};
|
||||
|
||||
/// 服务端规定赛评分项编码到平板控件键的映射。
|
||||
/// 按编码匹配可避免“动作的准确性”与“动作准确性”等文案差异丢分。
|
||||
static const serverItemAliases = <String, String>{
|
||||
@ -83,4 +91,6 @@ abstract final class PrescribedExecutionRuleCatalog {
|
||||
PrescribedEntryType.individual => individual,
|
||||
PrescribedEntryType.collective => collective,
|
||||
};
|
||||
|
||||
static String displayLabelFor(String item) => displayLabels[item] ?? item;
|
||||
}
|
||||
|
||||
@ -437,6 +437,9 @@ class ScoringController extends GetxController {
|
||||
final key = _matchingKey(
|
||||
deductionCounts.keys,
|
||||
'${item.name}${item.code}',
|
||||
aliases: profile.competition == CompetitionKind.prescribed
|
||||
? DeductionRuleCatalog.prescribedServerItemAliases
|
||||
: const {},
|
||||
);
|
||||
if (key != null) {
|
||||
deductionCounts[key] = count;
|
||||
@ -879,6 +882,13 @@ class ScoringController extends GetxController {
|
||||
.description;
|
||||
}
|
||||
|
||||
String performanceItemDisplayLabel(String item) {
|
||||
if (profile.role == ScoreRole.execution) {
|
||||
return PrescribedExecutionRuleCatalog.displayLabelFor(item);
|
||||
}
|
||||
return '$item(${performanceItemMaximum(item).round()})';
|
||||
}
|
||||
|
||||
void setPerformance(String item, double value) {
|
||||
performanceItems[item] = value.clamp(0, performanceItemMaximum(item));
|
||||
recalculate();
|
||||
|
||||
@ -1296,7 +1296,7 @@ class _PerformancePanel extends StatelessWidget {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
'${entry.key}($itemMaximum)',
|
||||
controller.performanceItemDisplayLabel(entry.key),
|
||||
style: const TextStyle(fontWeight: FontWeight.w700),
|
||||
),
|
||||
if (description != null) ...[
|
||||
|
||||
@ -30,6 +30,29 @@ void main() {
|
||||
expect(rules.fold<double>(0, (sum, item) => sum + item.maximum), 80);
|
||||
});
|
||||
|
||||
test('完成质量评分项同时标明个人与集体分值', () {
|
||||
expect(
|
||||
PrescribedExecutionRuleCatalog.displayLabelFor('动作准确性'),
|
||||
'动作的准确性(个人30分/集体20分)',
|
||||
);
|
||||
expect(
|
||||
PrescribedExecutionRuleCatalog.displayLabelFor('动作熟练性'),
|
||||
'动作的熟练性(个人20分/集体15分)',
|
||||
);
|
||||
expect(
|
||||
PrescribedExecutionRuleCatalog.displayLabelFor('动作合拍性'),
|
||||
'动作的合拍性(个人30分/集体15分)',
|
||||
);
|
||||
expect(
|
||||
PrescribedExecutionRuleCatalog.displayLabelFor('运动能力一致性'),
|
||||
'运动能力一致性(集体15分)',
|
||||
);
|
||||
expect(
|
||||
PrescribedExecutionRuleCatalog.displayLabelFor('表演技巧一致性'),
|
||||
'表演技巧一致性(集体15分)',
|
||||
);
|
||||
});
|
||||
|
||||
test('个人与集体规定赛使用不同任务状态键', () {
|
||||
final profile = JudgeAccounts.find('GS-E1')!;
|
||||
|
||||
|
||||
@ -35,7 +35,13 @@ void main() {
|
||||
});
|
||||
|
||||
test('规定赛完成质量项按稳定编码匹配平板控件', () {
|
||||
const keys = ['动作准确性', '动作熟练性', '动作合拍性'];
|
||||
const keys = [
|
||||
'动作准确性',
|
||||
'动作熟练性',
|
||||
'动作合拍性',
|
||||
'运动能力一致性',
|
||||
'表演技巧一致性',
|
||||
];
|
||||
const aliases = PrescribedExecutionRuleCatalog.serverItemAliases;
|
||||
|
||||
expect(
|
||||
@ -54,6 +60,48 @@ void main() {
|
||||
ScoreItemKeyMatcher.match(keys, 'CQ_SYNCHRONY 动作的合拍性', aliases: aliases),
|
||||
'动作合拍性',
|
||||
);
|
||||
expect(
|
||||
ScoreItemKeyMatcher.match(
|
||||
keys,
|
||||
'CQ_ABILITY_CONSISTENCY 运动能力一致性',
|
||||
aliases: aliases,
|
||||
),
|
||||
'运动能力一致性',
|
||||
);
|
||||
expect(
|
||||
ScoreItemKeyMatcher.match(
|
||||
keys,
|
||||
'CQ_SKILL_CONSISTENCY 表演技巧一致性',
|
||||
aliases: aliases,
|
||||
),
|
||||
'表演技巧一致性',
|
||||
);
|
||||
});
|
||||
|
||||
test('规定赛主裁扣分项按稳定编码匹配平板控件', () {
|
||||
final keys = DeductionRuleCatalog.forCompetition(
|
||||
CompetitionKind.prescribed,
|
||||
).map((item) => item.key).toList();
|
||||
const aliases = DeductionRuleCatalog.prescribedServerItemAliases;
|
||||
const serverItems = {
|
||||
'T_DED_ROPE_SALUTE': '赛前或赛后未行绳礼(每队)',
|
||||
'T_DED_APPEARANCE': '头发、着装、仪容不符合规定,佩戴饰物或饰物掉落(每人)',
|
||||
'T_DED_CHANGE_1X8': '更改1×8拍规定元素内容',
|
||||
'T_DED_INTERRUPT': '套路中断4秒以上',
|
||||
'T_DED_AREA_FOUL': '场地犯规(踩线/出界,仅个人花样规定套路)',
|
||||
};
|
||||
|
||||
expect(
|
||||
{
|
||||
for (final item in serverItems.entries)
|
||||
item.key: ScoreItemKeyMatcher.match(
|
||||
keys,
|
||||
item.key,
|
||||
aliases: aliases,
|
||||
),
|
||||
},
|
||||
serverItems,
|
||||
);
|
||||
});
|
||||
|
||||
final keys = DeductionRuleCatalog.forCompetition(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user