评分单计算调整

This commit is contained in:
马梓彭 2026-09-22 08:44:12 +08:00
parent 9b914062d1
commit 62cb2d8657
3 changed files with 67 additions and 8 deletions

View File

@ -1,12 +1,21 @@
/// Maps server labels to the existing scoring controls without allowing a
/// shorter label (e.g. 违例) to shadow a more specific one (e.g. 空间违例).
abstract final class ScoreItemKeyMatcher {
static String? match(Iterable<String> keys, String source) {
static String? match(
Iterable<String> keys,
String source, {
Map<String, String> aliases = const {},
}) {
String normalize(String value) =>
value.replaceAll(RegExp(r'[\s()()_+\-]'), '').toLowerCase();
final text = normalize(source);
if (text.isEmpty) return null;
for (final alias in aliases.entries) {
if (text.contains(normalize(alias.key)) && keys.contains(alias.value)) {
return alias.value;
}
}
final candidates = {
for (final key in keys)
if (normalize(key).isNotEmpty) key: normalize(key),

View File

@ -289,13 +289,14 @@ class ScoringController extends GetxController {
}
if (profile.competition == CompetitionKind.individual) {
if (profile.role == ScoreRole.difficulty ||
(profile.role == ScoreRole.technical &&
taskVariant != EliteScoringRuleCatalog.individualSolo)) {
if (profile.role == ScoreRole.difficulty) {
requiredElementCounts.assignAll({
EliteScoringRuleCatalog.requiredLevel3AndAbove: 0,
EliteScoringRuleCatalog.requiredLevel2AndBelow: 0,
});
} else if (profile.role == ScoreRole.technical &&
taskVariant != EliteScoringRuleCatalog.individualSolo) {
requiredElementCounts.assignAll({'互动配合': 0});
}
} else if (profile.competition == CompetitionKind.wheel &&
profile.role == ScoreRole.technical) {
@ -369,10 +370,7 @@ class ScoringController extends GetxController {
}
if (item.itemType == 2 || item.scoreDimension == 3) {
final key = _matchingKey(
requiredElementCounts.keys,
'${item.subjectName ?? ''}${item.name}${item.code}',
);
final key = _requiredElementKeyOf(item);
if (key != null) {
requiredElementCounts[key] = count;
_itemUiKeys[item.code] = key;
@ -466,6 +464,18 @@ class ScoringController extends GetxController {
return ScoreItemKeyMatcher.match(keys, source);
}
String? _requiredElementKeyOf(JudgeScoreItem item) {
return ScoreItemKeyMatcher.match(
requiredElementCounts.keys,
'${item.subjectName ?? ''}${item.name}${item.code}',
aliases: const {
'REQUIRED_N3_PLUS': EliteScoringRuleCatalog.requiredLevel3AndAbove,
'REQUIRED_N2_MINUS': EliteScoringRuleCatalog.requiredLevel2AndBelow,
'REQ_INTERACTION': '互动配合',
},
);
}
Future<void> _restoreLatestScore() async {
final saved = await _repository.loadLatest(
judgeId: profile.account,

View File

@ -1,6 +1,7 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:yd_pattern_scoring_system/core/models/deduction_rule_item.dart';
import 'package:yd_pattern_scoring_system/core/models/judge_account.dart';
import 'package:yd_pattern_scoring_system/core/models/elite_scoring_rule.dart';
import 'package:yd_pattern_scoring_system/core/network/score_item_key_matcher.dart';
void main() {
@ -47,4 +48,43 @@ void main() {
expect(ScoreItemKeyMatcher.match(keys, '未知项目'), isNull);
expect(ScoreItemKeyMatcher.match(keys, '违例'), '违例');
});
test('个人花样规定元素按稳定编码映射到平板控件', () {
const requiredKeys = [
EliteScoringRuleCatalog.requiredLevel3AndAbove,
EliteScoringRuleCatalog.requiredLevel2AndBelow,
];
const aliases = {
'REQUIRED_N3_PLUS': EliteScoringRuleCatalog.requiredLevel3AndAbove,
'REQUIRED_N2_MINUS': EliteScoringRuleCatalog.requiredLevel2AndBelow,
};
expect(
ScoreItemKeyMatcher.match(
requiredKeys,
'3级及以上规定元素数REQUIRED_N3_PLUS',
aliases: aliases,
),
EliteScoringRuleCatalog.requiredLevel3AndAbove,
);
expect(
ScoreItemKeyMatcher.match(
requiredKeys,
'2级及以下规定元素数REQUIRED_N2_MINUS',
aliases: aliases,
),
EliteScoringRuleCatalog.requiredLevel2AndBelow,
);
});
test('同步花样互动配合按稳定编码映射到主裁控件', () {
expect(
ScoreItemKeyMatcher.match(
const ['互动配合'],
'REQ_INTERACTION',
aliases: const {'REQ_INTERACTION': '互动配合'},
),
'互动配合',
);
});
}