1.新增参赛队伍页面交互

2.新增人工处理功能交互
This commit is contained in:
2026-07-20 09:29:53 +08:00
parent a4333d3bd1
commit 4e0a675198
8 changed files with 1014 additions and 1 deletions
@@ -0,0 +1,210 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:recording_tool/features/competition_teams/model/model_competition_team.dart';
import 'package:recording_tool/shared/widgets/app_button.dart';
class ManualWinnerDialog extends StatefulWidget {
const ManualWinnerDialog({super.key, required this.matchup});
final CompetitionMatchup matchup;
static Future<String?> show(
BuildContext context, {
required CompetitionMatchup matchup,
}) {
return showDialog<String>(
context: context,
barrierDismissible: false,
builder: (_) => ManualWinnerDialog(matchup: matchup),
);
}
@override
State<ManualWinnerDialog> createState() => _ManualWinnerDialogState();
}
class _ManualWinnerDialogState extends State<ManualWinnerDialog> {
String? _selectedTeamId;
@override
void initState() {
super.initState();
_selectedTeamId = widget.matchup.winnerTeamId;
}
@override
Widget build(BuildContext context) {
return AlertDialog(
insetPadding: EdgeInsets.symmetric(horizontal: 22.w),
contentPadding: EdgeInsets.zero,
clipBehavior: Clip.antiAlias,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(18.r)),
content: SizedBox(
width: 320.w,
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Image.asset(
'assets/images/image_dialog_bg.png',
width: 320.w,
height: 112.h,
fit: BoxFit.cover,
),
Padding(
padding: EdgeInsets.fromLTRB(20.w, 8.h, 20.w, 20.h),
child: Column(
children: [
Text(
'请在比赛结束前处理',
key: const ValueKey('manual-winner-dialog-title'),
style: TextStyle(
fontSize: 20.sp,
fontWeight: FontWeight.w700,
color: const Color(0xFF20242B),
),
),
SizedBox(height: 16.h),
_TeamChoice(
team: widget.matchup.teamA,
color: const Color(0xFFFF6B75),
selected: _selectedTeamId == widget.matchup.teamA.id,
onTap: () => setState(
() => _selectedTeamId = widget.matchup.teamA.id,
),
),
SizedBox(height: 10.h),
_TeamChoice(
team: widget.matchup.teamB,
color: const Color(0xFF20BFA9),
selected: _selectedTeamId == widget.matchup.teamB.id,
onTap: () => setState(
() => _selectedTeamId = widget.matchup.teamB.id,
),
),
SizedBox(height: 20.h),
Row(
children: [
Expanded(
child: AppButton(
label: '取消',
variant: AppButtonVariant.secondary,
onPressed: () => Navigator.of(context).pop(),
),
),
SizedBox(width: 14.w),
Expanded(
child: AppButton(
label: '确定',
onPressed: _selectedTeamId == null
? null
: () => Navigator.of(
context,
).pop(_selectedTeamId),
),
),
],
),
],
),
),
],
),
),
),
);
}
}
class _TeamChoice extends StatelessWidget {
const _TeamChoice({
required this.team,
required this.color,
required this.selected,
required this.onTap,
});
final CompetitionTeam team;
final Color color;
final bool selected;
final VoidCallback onTap;
@override
Widget build(BuildContext context) {
return Semantics(
selected: selected,
button: true,
label: '选择${team.name}直接获胜',
child: Material(
color: color.withValues(alpha: selected ? 0.16 : 0.08),
borderRadius: BorderRadius.circular(12.r),
child: InkWell(
key: ValueKey('winner-choice-${team.id}'),
onTap: onTap,
borderRadius: BorderRadius.circular(12.r),
child: Container(
width: double.infinity,
padding: EdgeInsets.symmetric(horizontal: 14.w, vertical: 12.h),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12.r),
border: Border.all(
color: selected ? color : color.withValues(alpha: 0.35),
width: selected ? 2 : 1,
),
),
child: Row(
children: [
AnimatedContainer(
duration: const Duration(milliseconds: 160),
width: 22.r,
height: 22.r,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(color: selected ? color : Colors.grey),
color: selected ? color : Colors.transparent,
),
child: selected
? Icon(Icons.check, size: 15.r, color: Colors.white)
: null,
),
SizedBox(width: 12.w),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
team.name,
style: TextStyle(
fontSize: 17.sp,
fontWeight: FontWeight.w600,
color: const Color(0xFF20242B),
),
),
SizedBox(height: 4.h),
Text(
team.playerNames,
style: TextStyle(
fontSize: 14.sp,
color: const Color(0xFF606874),
),
),
],
),
),
SizedBox(width: 8.w),
Text(
'直接获胜',
style: TextStyle(
fontSize: 13.sp,
fontWeight: FontWeight.w600,
color: color,
),
),
],
),
),
),
),
);
}
}