裁判打分页面编辑按钮调整
This commit is contained in:
parent
5480427d65
commit
0be9c0d3c1
@ -66,6 +66,19 @@ abstract final class RemoteScoringAdapter {
|
||||
sheet.header.judgeRole.trim().toUpperCase() ==
|
||||
session.judgeRole.trim().toUpperCase();
|
||||
|
||||
/// Returns the business session number shown on the judge task card.
|
||||
///
|
||||
/// [JudgeEntry.playOrder] is the entry order inside an EventSession. The
|
||||
/// arrangement order identifies the first business session represented by
|
||||
/// that EventSession, so both values are needed for a stable display number.
|
||||
static int sessionDisplayOrder(JudgeSession session, JudgeEntry entry) {
|
||||
final playOrder = entry.playOrder > 0 ? entry.playOrder : 1;
|
||||
final arrangementOrder = session.arrangementOrder;
|
||||
return arrangementOrder > 0 && arrangementOrder < 0x7fffffff
|
||||
? arrangementOrder + playOrder - 1
|
||||
: playOrder;
|
||||
}
|
||||
|
||||
static JudgeAccount accountForSession(
|
||||
JudgeSession session, {
|
||||
required String userId,
|
||||
|
||||
@ -44,7 +44,6 @@ class _HomePageState extends State<HomePage> {
|
||||
late final Worker _syncStatusWorker;
|
||||
Timer? _messageTimer;
|
||||
int _unreadMessages = 0;
|
||||
int _correctionTaskCount = 0;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@ -56,9 +55,6 @@ class _HomePageState extends State<HomePage> {
|
||||
_loadUnreadMessages();
|
||||
_messageTimer = Timer.periodic(const Duration(seconds: 30), (_) {
|
||||
_loadUnreadMessages();
|
||||
if (_allSessions.isNotEmpty) {
|
||||
_loadCorrectionTaskCount(_allSessions);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -122,7 +118,6 @@ class _HomePageState extends State<HomePage> {
|
||||
sessionsResult.fromCache || batches.any((item) => item.fromCache);
|
||||
_loading = false;
|
||||
});
|
||||
unawaited(_loadCorrectionTaskCount(sessionsResult.data));
|
||||
} on ApiException catch (error) {
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
@ -172,9 +167,7 @@ class _HomePageState extends State<HomePage> {
|
||||
userName: userName,
|
||||
roleSummary: roleSummary,
|
||||
unreadMessages: _unreadMessages,
|
||||
correctionTaskCount: _correctionTaskCount,
|
||||
onMessages: _openMessages,
|
||||
onCorrections: _openCorrections,
|
||||
onResults: chiefSessions.isNotEmpty ? _openResults : null,
|
||||
onLogout: _logout,
|
||||
),
|
||||
@ -209,6 +202,11 @@ class _HomePageState extends State<HomePage> {
|
||||
padding: const EdgeInsets.only(bottom: 16),
|
||||
child: _TaskCard(
|
||||
task: entry.$2,
|
||||
sessionDisplayOrder: RemoteScoringAdapter
|
||||
.sessionDisplayOrder(
|
||||
_remoteTasks[entry.$1].session,
|
||||
_remoteTasks[entry.$1].entry,
|
||||
),
|
||||
roleLabel:
|
||||
RemoteScoringAdapter.roleLabelForSession(
|
||||
_remoteTasks[entry.$1].session,
|
||||
@ -332,41 +330,6 @@ class _HomePageState extends State<HomePage> {
|
||||
if (mounted) setState(() {});
|
||||
}
|
||||
|
||||
Future<void> _openCorrections() async {
|
||||
final entryId = await Get.toNamed(
|
||||
AppRoutes.corrections,
|
||||
arguments: _sessions,
|
||||
);
|
||||
if (!mounted) return;
|
||||
await _loadTasks();
|
||||
if (!mounted || entryId is! String) return;
|
||||
final index = _remoteTasks.indexWhere(
|
||||
(item) => item.entry.sessionEntryId == entryId,
|
||||
);
|
||||
if (index >= 0) {
|
||||
await _openTask(index, _remoteTasks[index], correction: true);
|
||||
} else {
|
||||
await _openCorrectionTask(entryId);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _loadCorrectionTaskCount(List<JudgeSession> sessions) async {
|
||||
try {
|
||||
final batches = await Future.wait(
|
||||
sessions.map(
|
||||
(session) => _api.loadCorrectionCandidates(session.sessionId),
|
||||
),
|
||||
);
|
||||
final count = batches
|
||||
.expand((items) => items)
|
||||
.where((item) => item.isAssignedTask)
|
||||
.length;
|
||||
if (mounted) setState(() => _correctionTaskCount = count);
|
||||
} on ApiException {
|
||||
// Badge refresh failure must not block the scoring task list.
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _openResults() async {
|
||||
await Get.toNamed(AppRoutes.results, arguments: _chiefSessions);
|
||||
}
|
||||
@ -696,9 +659,7 @@ class _TopBar extends StatelessWidget {
|
||||
required this.userName,
|
||||
required this.roleSummary,
|
||||
required this.unreadMessages,
|
||||
required this.correctionTaskCount,
|
||||
required this.onMessages,
|
||||
required this.onCorrections,
|
||||
required this.onResults,
|
||||
required this.onLogout,
|
||||
});
|
||||
@ -707,9 +668,7 @@ class _TopBar extends StatelessWidget {
|
||||
final String userName;
|
||||
final String roleSummary;
|
||||
final int unreadMessages;
|
||||
final int correctionTaskCount;
|
||||
final VoidCallback onMessages;
|
||||
final VoidCallback onCorrections;
|
||||
final VoidCallback? onResults;
|
||||
final VoidCallback onLogout;
|
||||
|
||||
@ -762,19 +721,7 @@ class _TopBar extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 18),
|
||||
Badge(
|
||||
isLabelVisible: correctionTaskCount > 0,
|
||||
label: Text(
|
||||
correctionTaskCount > 99 ? '99+' : '$correctionTaskCount',
|
||||
),
|
||||
child: IconButton.outlined(
|
||||
onPressed: onCorrections,
|
||||
tooltip: '成绩修正任务',
|
||||
icon: const Icon(Icons.edit_note_rounded, size: 21),
|
||||
),
|
||||
),
|
||||
if (onResults != null) ...[
|
||||
const SizedBox(width: 8),
|
||||
IconButton.outlined(
|
||||
onPressed: onResults,
|
||||
tooltip: '场次成绩',
|
||||
@ -944,6 +891,7 @@ class _PageHeading extends StatelessWidget {
|
||||
class _TaskCard extends StatelessWidget {
|
||||
const _TaskCard({
|
||||
required this.task,
|
||||
required this.sessionDisplayOrder,
|
||||
required this.roleLabel,
|
||||
required this.status,
|
||||
required this.isCurrent,
|
||||
@ -951,6 +899,7 @@ class _TaskCard extends StatelessWidget {
|
||||
required this.onTap,
|
||||
});
|
||||
final ScoringTask task;
|
||||
final int sessionDisplayOrder;
|
||||
final String roleLabel;
|
||||
final String status;
|
||||
final bool isCurrent;
|
||||
@ -1050,7 +999,7 @@ class _TaskCard extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(height: 3),
|
||||
Text(
|
||||
'#${task.displayOrder}',
|
||||
'#${sessionDisplayOrder.toString().padLeft(2, '0')}',
|
||||
style: TextStyle(
|
||||
color: color,
|
||||
fontSize: 14,
|
||||
|
||||
@ -220,6 +220,63 @@ void main() {
|
||||
expect(task.session, isNot(contains(task.project)));
|
||||
expect(task.session, isNot(contains(task.groupName)));
|
||||
});
|
||||
|
||||
test('任务卡场次号由编排起始场次和出场顺序计算', () {
|
||||
final firstSession = _session(
|
||||
id: 'session-1',
|
||||
role: 'DJ1',
|
||||
roleType: 'DJ',
|
||||
arrangementOrder: 1,
|
||||
);
|
||||
final secondSession = _session(
|
||||
id: 'session-2',
|
||||
role: 'DJ1',
|
||||
roleType: 'DJ',
|
||||
arrangementOrder: 2,
|
||||
);
|
||||
const firstEntry = JudgeEntry(
|
||||
sessionEntryId: 'entry-1',
|
||||
entryNo: '01',
|
||||
playOrder: 1,
|
||||
participantName: '测试队',
|
||||
groupName: '青年组',
|
||||
entryStatus: 0,
|
||||
isRematch: false,
|
||||
scoreStatus: 0,
|
||||
scoreStatusName: '待评分',
|
||||
isDisqualified: false,
|
||||
scoreSheetId: '',
|
||||
);
|
||||
const secondEntryInSameSession = JudgeEntry(
|
||||
sessionEntryId: 'entry-2',
|
||||
entryNo: '02',
|
||||
playOrder: 2,
|
||||
participantName: '测试队',
|
||||
groupName: '青年组',
|
||||
entryStatus: 0,
|
||||
isRematch: false,
|
||||
scoreStatus: 0,
|
||||
scoreStatusName: '待评分',
|
||||
isDisqualified: false,
|
||||
scoreSheetId: '',
|
||||
);
|
||||
|
||||
expect(
|
||||
RemoteScoringAdapter.sessionDisplayOrder(firstSession, firstEntry),
|
||||
1,
|
||||
);
|
||||
expect(
|
||||
RemoteScoringAdapter.sessionDisplayOrder(secondSession, firstEntry),
|
||||
2,
|
||||
);
|
||||
expect(
|
||||
RemoteScoringAdapter.sessionDisplayOrder(
|
||||
firstSession,
|
||||
secondEntryInSameSession,
|
||||
),
|
||||
2,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
JudgeSession _session({
|
||||
@ -227,6 +284,7 @@ JudgeSession _session({
|
||||
required String role,
|
||||
required String roleType,
|
||||
String roleName = '',
|
||||
int arrangementOrder = 0,
|
||||
}) => JudgeSession(
|
||||
sessionId: id,
|
||||
eventId: 'event-1',
|
||||
@ -244,6 +302,7 @@ JudgeSession _session({
|
||||
judgeRoleName: roleName,
|
||||
entryCount: 2,
|
||||
scoredCount: 0,
|
||||
arrangementOrder: arrangementOrder,
|
||||
);
|
||||
|
||||
JudgeScoreSheet _sheet({
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user