feat: 优化评分确认弹窗与表演赛表现布局
提交确认仅展示评分类别与录入说明,隐藏裁判总分和小项得分;表演赛表现裁判采用失误与表现左右双栏布局;补充提交确认弹窗组件测试。
This commit is contained in:
parent
8f95150f17
commit
116096aa51
@ -99,10 +99,7 @@ class _ScoringPageState extends State<ScoringPage> with WidgetsBindingObserver {
|
||||
return;
|
||||
}
|
||||
final correctionSubmission = controller.isCorrectionMode.value;
|
||||
final score = controller.currentJudgeScore;
|
||||
final confirmed = await showSubmitConfirmation(
|
||||
score: score,
|
||||
scoreLabel: controller.currentJudgeScoreLabel,
|
||||
details: _submissionScoreDetails(controller),
|
||||
correctionMode: controller.isCorrectionMode.value,
|
||||
);
|
||||
@ -1134,7 +1131,8 @@ class _PerformancePanel extends StatelessWidget {
|
||||
isPresentation &&
|
||||
(controller.profile.competition == CompetitionKind.individual ||
|
||||
controller.profile.competition == CompetitionKind.wheel ||
|
||||
controller.profile.competition == CompetitionKind.doubleDutch);
|
||||
controller.profile.competition == CompetitionKind.doubleDutch ||
|
||||
controller.profile.competition == CompetitionKind.show);
|
||||
final scoreRows = <Widget>[
|
||||
...controller.performanceItems.entries.map((entry) {
|
||||
if (isPresentation) {
|
||||
@ -2410,8 +2408,6 @@ List<SubmissionScoreDetail> _submissionScoreDetails(
|
||||
for (final category in controller.showDifficultyCategories)
|
||||
SubmissionScoreDetail(
|
||||
label: category,
|
||||
value:
|
||||
'${_formatScore(controller.showDifficultyCategorySubtotal(category))} 分',
|
||||
description: _showDifficultyCountSummary(controller, category),
|
||||
),
|
||||
];
|
||||
@ -2420,14 +2416,11 @@ List<SubmissionScoreDetail> _submissionScoreDetails(
|
||||
for (final entry in controller.requiredElementCounts.entries)
|
||||
SubmissionScoreDetail(
|
||||
label: entry.key,
|
||||
value: '${entry.value} 个',
|
||||
description: '规定元素完成数量',
|
||||
description: '规定元素完成数量:${entry.value} 个',
|
||||
),
|
||||
for (final entry in controller.difficultyCounts.entries)
|
||||
SubmissionScoreDetail(
|
||||
label: '${entry.key}级难度',
|
||||
value:
|
||||
'${_formatScore(controller.difficultySubtotal(entry.key, entry.value))} 分',
|
||||
description: '记录数量:${entry.value}',
|
||||
),
|
||||
];
|
||||
@ -2436,41 +2429,33 @@ List<SubmissionScoreDetail> _submissionScoreDetails(
|
||||
for (final item in controller.performanceItems.keys)
|
||||
SubmissionScoreDetail(
|
||||
label: item,
|
||||
value: '${controller.performanceCalculatedItemScore(item)} 分',
|
||||
description:
|
||||
'减 ${controller.performanceEffectiveMinusCount(item)} / 加 ${controller.performancePlusCount(item)}',
|
||||
),
|
||||
SubmissionScoreDetail(
|
||||
label: '失误',
|
||||
value: '${controller.performanceErrorCount.value} 次',
|
||||
description: '计分时从五个表现类别各减去该次数',
|
||||
description:
|
||||
'已记录 ${controller.performanceErrorCount.value} 次,计分时从五个表现类别各减去该次数',
|
||||
),
|
||||
];
|
||||
case ScoreRole.creative:
|
||||
case ScoreRole.execution:
|
||||
return [
|
||||
for (final entry in controller.performanceItems.entries)
|
||||
SubmissionScoreDetail(
|
||||
label: entry.key,
|
||||
value: '${_formatScore(entry.value)} 分',
|
||||
description:
|
||||
'本项满分 ${_formatScore(controller.performanceItemMaximum(entry.key))} 分',
|
||||
),
|
||||
SubmissionScoreDetail(label: entry.key, description: '评分项已完成录入'),
|
||||
];
|
||||
case ScoreRole.technical:
|
||||
return [
|
||||
for (final entry in controller.requiredElementCounts.entries)
|
||||
SubmissionScoreDetail(
|
||||
label: entry.key,
|
||||
value: '${entry.value} 个',
|
||||
description:
|
||||
'规定元素 · Q=${controller.requiredElementFactor.value.toStringAsFixed(3)}',
|
||||
description: '规定元素完成数量:${entry.value} 个',
|
||||
),
|
||||
for (final rule in controller.deductionRules)
|
||||
SubmissionScoreDetail(
|
||||
label: rule.key,
|
||||
value: '${controller.deductionCounts[rule.key] ?? 0} 次',
|
||||
description: rule.standard,
|
||||
description:
|
||||
'已记录 ${controller.deductionCounts[rule.key] ?? 0} 次 · ${rule.standard}',
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
@ -7,14 +7,9 @@ import '../../../core/models/scoring_task.dart';
|
||||
import '../../../core/network/api_models.dart';
|
||||
|
||||
class SubmissionScoreDetail {
|
||||
const SubmissionScoreDetail({
|
||||
required this.label,
|
||||
required this.value,
|
||||
required this.description,
|
||||
});
|
||||
const SubmissionScoreDetail({required this.label, required this.description});
|
||||
|
||||
final String label;
|
||||
final String value;
|
||||
final String description;
|
||||
}
|
||||
|
||||
@ -241,24 +236,20 @@ class _PickerTitleLine extends StatelessWidget {
|
||||
}
|
||||
|
||||
Future<bool?> showSubmitConfirmation({
|
||||
required double score,
|
||||
required String scoreLabel,
|
||||
required List<SubmissionScoreDetail> details,
|
||||
required bool correctionMode,
|
||||
}) {
|
||||
return Get.dialog<bool>(
|
||||
_ScoringDialogFrame(
|
||||
width: 960,
|
||||
height: 720,
|
||||
height: 620,
|
||||
icon: correctionMode ? Icons.edit_document : Icons.task_alt_rounded,
|
||||
title: correctionMode ? '确认提交修正' : '确认提交成绩',
|
||||
subtitle: correctionMode
|
||||
? '请核对当前裁判总分与全部评分类别,修正提交后将形成新的操作记录。'
|
||||
: '请核对当前裁判总分与全部评分类别,确认后将锁定本场评分内容。',
|
||||
? '请核对全部评分类别,修正提交后将形成新的操作记录。'
|
||||
: '请核对全部评分类别,确认后将锁定本场评分内容。',
|
||||
body: Column(
|
||||
children: [
|
||||
_SubmissionScoreSummary(score: score, scoreLabel: scoreLabel),
|
||||
const SizedBox(height: 14),
|
||||
Row(
|
||||
children: [
|
||||
const Icon(
|
||||
@ -268,7 +259,7 @@ Future<bool?> showSubmitConfirmation({
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
'评分明细(${details.length}项)',
|
||||
'评分内容(${details.length}项)',
|
||||
style: const TextStyle(
|
||||
color: AppColors.textPrimary,
|
||||
fontSize: 16,
|
||||
@ -277,7 +268,7 @@ Future<bool?> showSubmitConfirmation({
|
||||
),
|
||||
const Spacer(),
|
||||
const Text(
|
||||
'请逐项确认后再提交',
|
||||
'请逐项确认已完成录入',
|
||||
style: TextStyle(color: AppColors.textSecondary, fontSize: 12),
|
||||
),
|
||||
],
|
||||
@ -317,78 +308,6 @@ Future<bool?> showSubmitConfirmation({
|
||||
);
|
||||
}
|
||||
|
||||
class _SubmissionScoreSummary extends StatelessWidget {
|
||||
const _SubmissionScoreSummary({
|
||||
required this.score,
|
||||
required this.scoreLabel,
|
||||
});
|
||||
|
||||
final double score;
|
||||
final String scoreLabel;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => Container(
|
||||
width: double.infinity,
|
||||
height: 142,
|
||||
padding: const EdgeInsets.symmetric(vertical: 14, horizontal: 28),
|
||||
decoration: BoxDecoration(
|
||||
gradient: const LinearGradient(
|
||||
colors: [AppColors.primaryPale, Color(0xFFE7F1FF)],
|
||||
),
|
||||
border: Border.all(color: const Color(0xFFBCD1EE)),
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
scoreLabel,
|
||||
style: const TextStyle(
|
||||
color: AppColors.primaryDark,
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Image.asset(
|
||||
'assets/images/score-left.png',
|
||||
width: 34,
|
||||
height: 50,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Text(
|
||||
score.toStringAsFixed(2),
|
||||
style: const TextStyle(
|
||||
color: AppColors.primaryDark,
|
||||
fontSize: 48,
|
||||
height: 1,
|
||||
fontWeight: FontWeight.w900,
|
||||
),
|
||||
),
|
||||
),
|
||||
Image.asset(
|
||||
'assets/images/score-right.png',
|
||||
width: 34,
|
||||
height: 50,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
const Text(
|
||||
'评分数据与记录画板 PNG 将一并保存',
|
||||
style: TextStyle(color: AppColors.textSecondary, fontSize: 12),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
class _SubmissionDetailCard extends StatelessWidget {
|
||||
const _SubmissionDetailCard({required this.detail});
|
||||
|
||||
@ -426,15 +345,6 @@ class _SubmissionDetailCard extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
detail.value,
|
||||
style: const TextStyle(
|
||||
color: AppColors.primary,
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w900,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 7),
|
||||
|
||||
39
test/submission_dialog_test.dart
Normal file
39
test/submission_dialog_test.dart
Normal file
@ -0,0 +1,39 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:yd_pattern_scoring_system/modules/scoring/widgets/scoring_dialogs.dart';
|
||||
|
||||
void main() {
|
||||
tearDown(Get.reset);
|
||||
|
||||
testWidgets('提交确认弹窗仅展示评分类别和录入说明,不展示裁判得分', (tester) async {
|
||||
await tester.pumpWidget(
|
||||
GetMaterialApp(
|
||||
home: Scaffold(
|
||||
body: Builder(
|
||||
builder: (context) => TextButton(
|
||||
onPressed: () => showSubmitConfirmation(
|
||||
correctionMode: false,
|
||||
details: const [
|
||||
SubmissionScoreDetail(label: '音乐', description: '减 1 / 加 2'),
|
||||
SubmissionScoreDetail(label: '完成质量', description: '评分项已完成录入'),
|
||||
],
|
||||
),
|
||||
child: const Text('打开'),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.text('打开'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('确认提交成绩'), findsOneWidget);
|
||||
expect(find.text('评分内容(2项)'), findsOneWidget);
|
||||
expect(find.text('音乐'), findsOneWidget);
|
||||
expect(find.text('完成质量'), findsOneWidget);
|
||||
expect(find.textContaining('裁判总分'), findsNothing);
|
||||
expect(find.textContaining('本次裁判得分'), findsNothing);
|
||||
});
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user