1.重构参赛队伍详情页面,更新数据模型以支持新结构;
2.优化比赛信息展示逻辑,增强用户交互体验; 3.修复API请求以获取队伍详情并处理异常情况。
This commit is contained in:
@@ -2,56 +2,91 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:recording_tool/features/competition_teams/model/model_competition_team.dart';
|
||||
import 'package:recording_tool/features/competition_teams/view_model/view_model_competition_teams.dart';
|
||||
import 'package:recording_tool/features/competition_teams/widgets/widget_manual_winner_dialog.dart';
|
||||
import 'package:recording_tool/shared/widgets/app_empty_view.dart';
|
||||
import 'package:recording_tool/shared/widgets/app_toast.dart';
|
||||
|
||||
class CompetitionTeamDetailPage extends ConsumerWidget {
|
||||
const CompetitionTeamDetailPage({
|
||||
super.key,
|
||||
required this.itemId,
|
||||
required this.eventId,
|
||||
});
|
||||
class CompetitionTeamDetailPage extends ConsumerStatefulWidget {
|
||||
const CompetitionTeamDetailPage({super.key, required this.detail});
|
||||
|
||||
final String itemId;
|
||||
final String eventId;
|
||||
final CompetitionTeamDetail detail;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final items = ref.watch(
|
||||
competitionTeamsProvider.select((state) => state.items),
|
||||
ConsumerState<CompetitionTeamDetailPage> createState() =>
|
||||
_CompetitionTeamDetailPageState();
|
||||
}
|
||||
|
||||
class _CompetitionTeamDetailPageState
|
||||
extends ConsumerState<CompetitionTeamDetailPage> {
|
||||
/// matchupIndex -> winnerTeamId
|
||||
final Map<int, String> _winners = {};
|
||||
|
||||
CompetitionTeamDetail get _detail => widget.detail;
|
||||
|
||||
String get _title {
|
||||
final name = _detail.itemName?.trim() ?? '';
|
||||
final group = _detail.groupName?.trim() ?? '';
|
||||
if (name.isEmpty) return '参赛队伍';
|
||||
return group.isEmpty ? name : '$name ($group)';
|
||||
}
|
||||
|
||||
List<Matchup> get _matchups => _detail.matchups ?? const <Matchup>[];
|
||||
|
||||
CompetitionTeam _toCompetitionTeam(Team team) {
|
||||
return CompetitionTeam(
|
||||
id: team.id?.trim().isNotEmpty == true ? team.id! : 'unknown-team',
|
||||
name: team.teamName?.trim().isNotEmpty == true ? team.teamName! : '未命名队伍',
|
||||
players: (team.players ?? const <Player>[])
|
||||
.map(
|
||||
(player) => CompetitionPlayer(
|
||||
id: player.id?.trim() ?? '',
|
||||
name: player.name?.trim().isNotEmpty == true
|
||||
? player.name!
|
||||
: '选手',
|
||||
),
|
||||
)
|
||||
.toList(growable: false),
|
||||
);
|
||||
CompetitionTeamListItem? item;
|
||||
for (final candidate in items) {
|
||||
if (candidate.itemId == itemId) {
|
||||
item = candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CompetitionMatchup? _toCompetitionMatchup(Matchup matchup, int index) {
|
||||
final teamA = matchup.teamA;
|
||||
final teamB = matchup.teamB;
|
||||
if (teamA == null || teamA.isEmpty || teamB == null || teamB.isEmpty) {
|
||||
return null;
|
||||
}
|
||||
return CompetitionMatchup(
|
||||
id: '${_detail.scheduleId ?? _detail.itemId ?? 'match'}-$index',
|
||||
teamA: _toCompetitionTeam(teamA.first),
|
||||
teamB: _toCompetitionTeam(teamB.first),
|
||||
winnerTeamId: _winners[index],
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final matchups = _matchups;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
appBar: AppBar(title: Text(item?.title ?? '参赛队伍')),
|
||||
body: item == null
|
||||
? const AppEmptyView(message: '未找到对阵信息')
|
||||
: item.matchups.isEmpty
|
||||
appBar: AppBar(title: Text(_title)),
|
||||
body: matchups.isEmpty
|
||||
? const AppEmptyView(message: '暂无对阵信息')
|
||||
: ListView.separated(
|
||||
padding: EdgeInsets.fromLTRB(20.w, 24.h, 20.w, 36.h),
|
||||
itemCount: item.matchups.length,
|
||||
itemCount: matchups.length,
|
||||
separatorBuilder: (_, _) => SizedBox(height: 22.h),
|
||||
itemBuilder: (context, index) {
|
||||
final matchup = item!.matchups[index];
|
||||
final raw = matchups[index];
|
||||
final matchup = _toCompetitionMatchup(raw, index);
|
||||
if (matchup == null) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return _MatchupCard(
|
||||
matchup: matchup,
|
||||
index: index,
|
||||
onManualProcess: () => _handleManualProcess(
|
||||
context,
|
||||
ref,
|
||||
itemId: item!.itemId,
|
||||
matchup: matchup,
|
||||
),
|
||||
matchTitle: raw.matchTitle?.trim() ?? '',
|
||||
onManualProcess: () => _handleManualProcess(matchup, index),
|
||||
);
|
||||
},
|
||||
),
|
||||
@@ -59,24 +94,16 @@ class CompetitionTeamDetailPage extends ConsumerWidget {
|
||||
}
|
||||
|
||||
Future<void> _handleManualProcess(
|
||||
BuildContext context,
|
||||
WidgetRef ref, {
|
||||
required String itemId,
|
||||
required CompetitionMatchup matchup,
|
||||
}) async {
|
||||
CompetitionMatchup matchup,
|
||||
int index,
|
||||
) async {
|
||||
final winnerTeamId = await ManualWinnerDialog.show(
|
||||
context,
|
||||
matchup: matchup,
|
||||
);
|
||||
if (winnerTeamId == null || !context.mounted) return;
|
||||
if (winnerTeamId == null || !mounted) return;
|
||||
|
||||
ref
|
||||
.read(competitionTeamsProvider.notifier)
|
||||
.selectWinner(
|
||||
itemId: itemId,
|
||||
matchupId: matchup.id,
|
||||
winnerTeamId: winnerTeamId,
|
||||
);
|
||||
setState(() => _winners[index] = winnerTeamId);
|
||||
final winnerName = winnerTeamId == matchup.teamA.id
|
||||
? matchup.teamA.name
|
||||
: matchup.teamB.name;
|
||||
@@ -88,15 +115,18 @@ class _MatchupCard extends StatelessWidget {
|
||||
const _MatchupCard({
|
||||
required this.matchup,
|
||||
required this.index,
|
||||
required this.matchTitle,
|
||||
required this.onManualProcess,
|
||||
});
|
||||
|
||||
final CompetitionMatchup matchup;
|
||||
final int index;
|
||||
final String matchTitle;
|
||||
final VoidCallback onManualProcess;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final title = matchTitle.isEmpty ? '第 ${index + 1} 场' : matchTitle;
|
||||
return Container(
|
||||
key: ValueKey('competition-matchup-${matchup.id}'),
|
||||
padding: EdgeInsets.fromLTRB(16.w, 10.h, 16.w, 18.h),
|
||||
@@ -109,14 +139,17 @@ class _MatchupCard extends StatelessWidget {
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'第 ${index + 1} 场',
|
||||
style: TextStyle(
|
||||
fontSize: 14.sp,
|
||||
color: const Color(0xFF7A828E),
|
||||
Expanded(
|
||||
child: Text(
|
||||
title,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: 14.sp,
|
||||
color: const Color(0xFF7A828E),
|
||||
),
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
TextButton(
|
||||
key: ValueKey('manual-process-${matchup.id}'),
|
||||
onPressed: onManualProcess,
|
||||
|
||||
@@ -4,11 +4,13 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:recording_tool/app/router/app_navigator.dart';
|
||||
import 'package:recording_tool/features/competition_teams/model/model_competition_team.dart';
|
||||
import 'package:recording_tool/features/competition_teams/pages/page_competition_team_detail.dart';
|
||||
import 'package:recording_tool/features/competition_teams/server/server_competition_teams.dart';
|
||||
import 'package:recording_tool/features/competition_teams/view_model/view_model_competition_teams.dart';
|
||||
import 'package:recording_tool/shared/widgets/app_empty_view.dart';
|
||||
import 'package:recording_tool/shared/widgets/app_error_view.dart';
|
||||
import 'package:recording_tool/shared/widgets/app_loading_view.dart';
|
||||
import 'package:recording_tool/shared/widgets/app_refresh_list.dart';
|
||||
import 'package:recording_tool/shared/widgets/app_toast.dart';
|
||||
|
||||
class CompetitionTeamListPage extends ConsumerStatefulWidget {
|
||||
const CompetitionTeamListPage({super.key});
|
||||
@@ -60,13 +62,23 @@ class _CompetitionTeamListPageState
|
||||
itemBuilder: (context, item, index) {
|
||||
return _CompetitionScheduleCard(
|
||||
item: item,
|
||||
onTap: () => AppNavigator.push(
|
||||
CompetitionTeamDetailPage(
|
||||
itemId: item.itemId,
|
||||
eventId: item.eventId,
|
||||
),
|
||||
context: context,
|
||||
),
|
||||
onTap: () async {
|
||||
try {
|
||||
final detail = await ref
|
||||
.read(competitionTeamsServerProvider)
|
||||
.fetchTeamDetail(
|
||||
itemId: item.itemId,
|
||||
eventId: item.eventId,
|
||||
);
|
||||
if (!context.mounted) return;
|
||||
AppNavigator.push(
|
||||
CompetitionTeamDetailPage(detail: detail),
|
||||
context: context,
|
||||
);
|
||||
} catch (error) {
|
||||
AppToast.show('对阵详情加载失败,请重试');
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -15,12 +15,12 @@ typedef TeamQrScanner = Future<String?> Function(BuildContext context);
|
||||
class EventTeamMatchPage extends StatefulWidget {
|
||||
const EventTeamMatchPage({
|
||||
super.key,
|
||||
required this.item,
|
||||
required this.playerId,
|
||||
this.qrScanner,
|
||||
required this.detail,
|
||||
});
|
||||
|
||||
final EventRegistrationItem item;
|
||||
final CompetitionTeamDetail detail;
|
||||
final String playerId;
|
||||
final TeamQrScanner? qrScanner;
|
||||
|
||||
@@ -32,55 +32,113 @@ class _EventTeamMatchPageState extends State<EventTeamMatchPage> {
|
||||
final Set<String> _verifiedUserIds = <String>{};
|
||||
String? _winnerTeamId;
|
||||
|
||||
CompetitionTeam get _homeTeam {
|
||||
final leader = widget.item.teamLeader;
|
||||
final teamId = leader?.userId.isNotEmpty == true
|
||||
? leader!.userId
|
||||
: widget.item.userId.isNotEmpty
|
||||
? widget.item.userId
|
||||
: 'home-team';
|
||||
final teamName = leader?.name.isNotEmpty == true
|
||||
? leader!.name
|
||||
: widget.item.playerName.isNotEmpty
|
||||
? widget.item.playerName
|
||||
: '本方队伍';
|
||||
return CompetitionTeam(
|
||||
id: teamId,
|
||||
name: teamName,
|
||||
players: widget.item.teamMembers
|
||||
.map(
|
||||
(member) => CompetitionPlayer(id: member.userId, name: member.name),
|
||||
)
|
||||
.toList(growable: false),
|
||||
);
|
||||
CompetitionTeamDetail get _detail => widget.detail;
|
||||
|
||||
/// 备注:teamA 为红队,teamB 为蓝队。
|
||||
Matchup? get _firstMatchup {
|
||||
final matchups = _detail.matchups;
|
||||
if (matchups == null || matchups.isEmpty) return null;
|
||||
return matchups.first;
|
||||
}
|
||||
|
||||
CompetitionTeam get _opponentTeam {
|
||||
final opponentId = widget.item.opponentId.isNotEmpty
|
||||
? widget.item.opponentId
|
||||
: 'opponent-team';
|
||||
final opponentName = widget.item.opponentName.isNotEmpty
|
||||
? widget.item.opponentName
|
||||
: '对方队伍';
|
||||
return CompetitionTeam(
|
||||
id: opponentId,
|
||||
name: opponentName,
|
||||
players:
|
||||
widget.item.opponentId.isEmpty && widget.item.opponentName.isEmpty
|
||||
? const []
|
||||
: [CompetitionPlayer(id: opponentId, name: opponentName)],
|
||||
);
|
||||
/// 红队(teamA)
|
||||
Team? get _redRawTeam {
|
||||
final teams = _firstMatchup?.teamA;
|
||||
if (teams == null || teams.isEmpty) return null;
|
||||
return teams.first;
|
||||
}
|
||||
|
||||
CompetitionMatchup get _matchup => CompetitionMatchup(
|
||||
id: widget.item.scheduleId.isNotEmpty
|
||||
? widget.item.scheduleId
|
||||
: '${widget.item.itemId}-team-match',
|
||||
teamA: _homeTeam,
|
||||
teamB: _opponentTeam,
|
||||
winnerTeamId: _winnerTeamId,
|
||||
/// 蓝队(teamB)
|
||||
Team? get _blueRawTeam {
|
||||
final teams = _firstMatchup?.teamB;
|
||||
if (teams == null || teams.isEmpty) return null;
|
||||
return teams.first;
|
||||
}
|
||||
|
||||
CompetitionTeam get _redTeam => _toCompetitionTeam(
|
||||
_redRawTeam,
|
||||
fallbackId: 'red-team',
|
||||
fallbackName: '红队',
|
||||
);
|
||||
|
||||
CompetitionTeam get _blueTeam => _toCompetitionTeam(
|
||||
_blueRawTeam,
|
||||
fallbackId: 'blue-team',
|
||||
fallbackName: '蓝队',
|
||||
);
|
||||
|
||||
List<EventTeamMember> get _redMembers =>
|
||||
_toEventMembers(_redRawTeam?.players);
|
||||
|
||||
List<EventTeamMember> get _blueMembers =>
|
||||
_toEventMembers(_blueRawTeam?.players);
|
||||
|
||||
CompetitionMatchup get _matchup {
|
||||
final scheduleId = _detail.scheduleId?.trim() ?? '';
|
||||
final itemId = _detail.itemId?.trim() ?? '';
|
||||
return CompetitionMatchup(
|
||||
id: scheduleId.isNotEmpty ? scheduleId : '$itemId-team-match',
|
||||
teamA: _redTeam,
|
||||
teamB: _blueTeam,
|
||||
winnerTeamId: _winnerTeamId,
|
||||
);
|
||||
}
|
||||
|
||||
/// H5 bridge 仍需要 EventRegistrationItem,从 detail 组装最小对象。
|
||||
/// 备注:红队成员写入 teamMembers,蓝队写入 opponent。
|
||||
EventRegistrationItem get _scoreBridgeItem {
|
||||
final blue = _blueTeam;
|
||||
return EventRegistrationItem(
|
||||
eventId: _detail.eventId?.trim() ?? '',
|
||||
itemId: _detail.itemId?.trim() ?? '',
|
||||
scheduleId: _detail.scheduleId?.trim() ?? '',
|
||||
eventName: '',
|
||||
itemName: _detail.itemName?.trim() ?? '',
|
||||
groupName: _detail.groupName?.trim() ?? '',
|
||||
matchPlace: _detail.matchPlace?.trim() ?? '',
|
||||
matchStartTime: _detail.matchStartTime?.trim() ?? '',
|
||||
matchEndTime: _detail.matchEndTime?.trim() ?? '',
|
||||
opponentId: blue.id == 'blue-team' ? '' : blue.id,
|
||||
opponentName: blue.name == '蓝队' ? '' : blue.name,
|
||||
teamMembers: _redMembers,
|
||||
);
|
||||
}
|
||||
|
||||
CompetitionTeam _toCompetitionTeam(
|
||||
Team? team, {
|
||||
required String fallbackId,
|
||||
required String fallbackName,
|
||||
}) {
|
||||
final id = team?.id?.trim() ?? '';
|
||||
final name = team?.teamName?.trim() ?? '';
|
||||
final players = (team?.players ?? const <Player>[])
|
||||
.map(
|
||||
(player) => CompetitionPlayer(
|
||||
id: player.id?.trim() ?? '',
|
||||
name: player.name?.trim() ?? '',
|
||||
),
|
||||
)
|
||||
.toList(growable: false);
|
||||
return CompetitionTeam(
|
||||
id: id.isNotEmpty ? id : fallbackId,
|
||||
name: name.isNotEmpty ? name : fallbackName,
|
||||
players: players,
|
||||
);
|
||||
}
|
||||
|
||||
List<EventTeamMember> _toEventMembers(List<Player>? players) {
|
||||
if (players == null || players.isEmpty) return const [];
|
||||
return players
|
||||
.map(
|
||||
(player) => EventTeamMember(
|
||||
userId: player.id?.trim() ?? '',
|
||||
name: player.name?.trim() ?? '',
|
||||
isLeader: player.isLeader ?? false,
|
||||
),
|
||||
)
|
||||
.toList(growable: false);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
@@ -92,18 +150,15 @@ class _EventTeamMatchPageState extends State<EventTeamMatchPage> {
|
||||
|
||||
bool _isKnownMember(String userId) {
|
||||
if (userId.isEmpty) return false;
|
||||
if (userId == widget.item.opponentId) return true;
|
||||
return widget.item.teamMembers.any((member) => member.userId == userId);
|
||||
return _redMembers.any((member) => member.userId == userId) ||
|
||||
_blueMembers.any((member) => member.userId == userId);
|
||||
}
|
||||
|
||||
String _memberNameOf(String userId) {
|
||||
if (userId == widget.item.opponentId) {
|
||||
return widget.item.opponentName.isEmpty
|
||||
? '对方队长'
|
||||
: widget.item.opponentName;
|
||||
}
|
||||
for (final member in widget.item.teamMembers) {
|
||||
if (member.userId == userId) return member.name;
|
||||
for (final member in [..._redMembers, ..._blueMembers]) {
|
||||
if (member.userId == userId) {
|
||||
return member.name.isEmpty ? '参赛成员' : member.name;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
@@ -131,23 +186,23 @@ class _EventTeamMatchPageState extends State<EventTeamMatchPage> {
|
||||
);
|
||||
if (!mounted || winnerTeamId == null) return;
|
||||
setState(() => _winnerTeamId = winnerTeamId);
|
||||
final winnerName = winnerTeamId == _homeTeam.id
|
||||
? _homeTeam.name
|
||||
: _opponentTeam.name;
|
||||
final winnerName = winnerTeamId == _redTeam.id
|
||||
? _redTeam.name
|
||||
: _blueTeam.name;
|
||||
AppToast.show('已设置$winnerName直接获胜');
|
||||
}
|
||||
|
||||
void _startDirectly() {
|
||||
AppNavigator.push(
|
||||
buildTeamScorePage(item: widget.item, playerId: widget.playerId),
|
||||
buildTeamScorePage(item: _scoreBridgeItem, playerId: widget.playerId),
|
||||
context: context,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final homeTeam = _homeTeam;
|
||||
final opponentTeam = _opponentTeam;
|
||||
final redTeam = _redTeam;
|
||||
final blueTeam = _blueTeam;
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
appBar: AppBar(),
|
||||
@@ -161,8 +216,16 @@ class _EventTeamMatchPageState extends State<EventTeamMatchPage> {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_MatchMetadata(item: widget.item),
|
||||
SizedBox(height: 16.h),
|
||||
_MatchMetadata(detail: _detail),
|
||||
SizedBox(height: 10.h),
|
||||
Text(
|
||||
'备注:上方红队(teamA),下方蓝队(teamB)',
|
||||
style: TextStyle(
|
||||
fontSize: 14.sp,
|
||||
color: const Color(0xFF7A828E),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 8.h),
|
||||
Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: TextButton(
|
||||
@@ -179,28 +242,24 @@ class _EventTeamMatchPageState extends State<EventTeamMatchPage> {
|
||||
),
|
||||
),
|
||||
_TeamCard(
|
||||
team: homeTeam,
|
||||
members: widget.item.teamMembers,
|
||||
teamLabel: '红队',
|
||||
team: redTeam,
|
||||
members: _redMembers,
|
||||
backgroundColor: const Color(0xFFFFEEF0),
|
||||
accentColor: const Color(0xFFE84B5B),
|
||||
verifiedUserIds: _verifiedUserIds,
|
||||
winner: _winnerTeamId == homeTeam.id,
|
||||
winner: _winnerTeamId == redTeam.id,
|
||||
),
|
||||
SizedBox(height: 16.h),
|
||||
_TeamCard(
|
||||
team: opponentTeam,
|
||||
members: [
|
||||
EventTeamMember(
|
||||
userId: widget.item.opponentId,
|
||||
name: widget.item.opponentName,
|
||||
isLeader: true,
|
||||
),
|
||||
],
|
||||
teamLabel: '蓝队',
|
||||
team: blueTeam,
|
||||
members: _blueMembers,
|
||||
backgroundColor: const Color(0xFFEDF5FF),
|
||||
accentColor: const Color(0xFF287FDD),
|
||||
verifiedUserIds: _verifiedUserIds,
|
||||
winner: _winnerTeamId == opponentTeam.id,
|
||||
emptyMessage: '暂无对方成员数据',
|
||||
winner: _winnerTeamId == blueTeam.id,
|
||||
emptyMessage: '暂无蓝队成员数据',
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -245,12 +304,15 @@ WebviewPage buildTeamScorePage({
|
||||
}
|
||||
|
||||
class _MatchMetadata extends StatelessWidget {
|
||||
const _MatchMetadata({required this.item});
|
||||
const _MatchMetadata({required this.detail});
|
||||
|
||||
final EventRegistrationItem item;
|
||||
final CompetitionTeamDetail detail;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final itemName = detail.itemName?.trim() ?? '';
|
||||
final matchPlace = detail.matchPlace?.trim() ?? '';
|
||||
final groupName = detail.groupName?.trim() ?? '';
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: EdgeInsets.all(18.r),
|
||||
@@ -264,14 +326,14 @@ class _MatchMetadata extends StatelessWidget {
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: _MetadataText(label: '比赛项目', value: item.itemName),
|
||||
child: _MetadataText(label: '比赛项目', value: itemName),
|
||||
),
|
||||
SizedBox(width: 16.w),
|
||||
_MetadataText(label: '场地', value: item.matchPlace),
|
||||
_MetadataText(label: '场地', value: matchPlace),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 14.h),
|
||||
_MetadataText(label: '组别', value: item.groupName),
|
||||
_MetadataText(label: '组别', value: groupName),
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -302,6 +364,7 @@ class _MetadataText extends StatelessWidget {
|
||||
|
||||
class _TeamCard extends StatelessWidget {
|
||||
const _TeamCard({
|
||||
required this.teamLabel,
|
||||
required this.team,
|
||||
required this.members,
|
||||
required this.backgroundColor,
|
||||
@@ -311,6 +374,7 @@ class _TeamCard extends StatelessWidget {
|
||||
this.emptyMessage = '暂无成员数据',
|
||||
});
|
||||
|
||||
final String teamLabel;
|
||||
final CompetitionTeam team;
|
||||
final List<EventTeamMember> members;
|
||||
final Color backgroundColor;
|
||||
@@ -343,7 +407,7 @@ class _TeamCard extends StatelessWidget {
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
'队长:${team.name}',
|
||||
'$teamLabel:${team.name}',
|
||||
style: TextStyle(
|
||||
fontSize: 19.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
|
||||
Reference in New Issue
Block a user