Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0c1fb24685 | ||
|
|
a849457172 | ||
|
|
d6a7e74809 | ||
|
|
df38ecee18 | ||
|
|
9dea31f76e | ||
|
|
7faa8e5c47 | ||
|
|
17799af2e7 | ||
|
|
7d65be0514 | ||
|
|
d4920e2b98 |
+1
-1
@@ -5,4 +5,4 @@ flutter build apk --release --split-per-abi
|
||||
|
||||
# echo "构建完成时间: $(date '+%Y-%m-%d %H:%M:%S')"
|
||||
|
||||
pgyer upload build/app/outputs/flutter-apk/app-arm64-v8a-release.apk --build-update-description "新增可视化请求插件"
|
||||
pgyer upload build/app/outputs/flutter-apk/app-arm64-v8a-release.apk --build-update-description "副裁判 APP $(date '+%Y-%m-%d %H:%M:%S')"
|
||||
@@ -146,6 +146,7 @@ class _AuthPageWidgetState extends ConsumerState<AuthPageWidget> {
|
||||
.auth(_controller.text);
|
||||
if (!mounted) return;
|
||||
if (success) {
|
||||
_controller.clear();
|
||||
AppNavigator.push(const ScanQrCodePage());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -30,15 +30,20 @@ class AuthServer {
|
||||
|
||||
/// 获取赛事列表
|
||||
/// [path] 赛事目录
|
||||
/// [nasIpAddr] NAS IP,由调用方传入,避免在 authProvider 内部再 read(authProvider)。
|
||||
static Future<GetRecordListResModel?> getRecordList(
|
||||
Ref ref,
|
||||
String path,
|
||||
) async {
|
||||
Ref ref, {
|
||||
required String path,
|
||||
required String nasIpAddr,
|
||||
}) async {
|
||||
try {
|
||||
if (nasIpAddr.isEmpty) {
|
||||
throw const FormatException('无法获取NAS IP地址');
|
||||
}
|
||||
final apiClient = ref.read(apiClientProvider);
|
||||
// NAS /api/files 直接返回 {path, items},不是业务网关的 {code,message,data} 包装。
|
||||
final data = await apiClient.get<GetRecordListResModel>(
|
||||
'http://sheling.local:9001/${AuthApi.getRecordList.path}',
|
||||
'http://$nasIpAddr:9001/${AuthApi.getRecordList.path}',
|
||||
queryParameters: {'path': path},
|
||||
wrapResponse: false,
|
||||
parser: (json) {
|
||||
|
||||
@@ -71,7 +71,13 @@ class AuthViewModel extends StateNotifier<AuthState> {
|
||||
/// 获取赛事列表
|
||||
Future<bool> getRecordList(String eventName) async {
|
||||
if (eventName.isEmpty) return false;
|
||||
final data = await AuthServer.getRecordList(_ref, eventName);
|
||||
final nasIpAddr = state.jwtDecodedData?.nasIpAddr?.trim() ?? '';
|
||||
if (nasIpAddr.isEmpty) return false;
|
||||
final data = await AuthServer.getRecordList(
|
||||
_ref,
|
||||
path: eventName,
|
||||
nasIpAddr: nasIpAddr,
|
||||
);
|
||||
if (data == null) return false;
|
||||
if (data.items == null) return false;
|
||||
state = state.copyWith(recordList: data.items);
|
||||
@@ -81,7 +87,13 @@ class AuthViewModel extends StateNotifier<AuthState> {
|
||||
/// 获取指定目录的录像列表(不更新 state,用于目录下钻)
|
||||
Future<List<RecordListItem>?> fetchRecordList(String path) async {
|
||||
if (path.isEmpty) return null;
|
||||
final data = await AuthServer.getRecordList(_ref, path);
|
||||
final nasIpAddr = state.jwtDecodedData?.nasIpAddr?.trim() ?? '';
|
||||
if (nasIpAddr.isEmpty) return null;
|
||||
final data = await AuthServer.getRecordList(
|
||||
_ref,
|
||||
path: path,
|
||||
nasIpAddr: nasIpAddr,
|
||||
);
|
||||
return data?.items;
|
||||
}
|
||||
|
||||
|
||||
@@ -134,6 +134,7 @@ class EventRegistrationItem {
|
||||
required this.itemName,
|
||||
required this.groupName,
|
||||
required this.matchPlace,
|
||||
|
||||
this.matchStartTime = '',
|
||||
this.matchEndTime = '',
|
||||
this.completed = false,
|
||||
@@ -143,6 +144,7 @@ class EventRegistrationItem {
|
||||
this.userId = '',
|
||||
this.playerName = '',
|
||||
this.playerPhone = '',
|
||||
this.playerNo = '',
|
||||
});
|
||||
|
||||
final String eventId;
|
||||
@@ -158,6 +160,7 @@ class EventRegistrationItem {
|
||||
final String opponentId;
|
||||
final String opponentName;
|
||||
final List<EventTeamMember> teamMembers;
|
||||
final String playerNo;
|
||||
|
||||
/// 来自报名列表父级,不在 item JSON 内
|
||||
final String userId;
|
||||
@@ -205,6 +208,7 @@ class EventRegistrationItem {
|
||||
: const [],
|
||||
userId: userId,
|
||||
playerName: playerName,
|
||||
playerNo: _readString(map, const ['playerNo']),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:recording_tool/app/config/app_config.dart';
|
||||
import 'package:recording_tool/app/router/app_navigator.dart';
|
||||
import 'package:recording_tool/core/utils/util_search_nasIp.dart';
|
||||
import 'package:recording_tool/features/events/model/model_event_info.dart';
|
||||
@@ -54,6 +53,14 @@ class _EventInfoPageState extends ConsumerState<EventInfoPage> {
|
||||
time: item.scheduleTime,
|
||||
playerName: item.playerName,
|
||||
playerPhone: item.playerPhone,
|
||||
isTeam: item.opponentId != '0',
|
||||
opponentName: item.opponentName,
|
||||
teamLeaderName: item.teamMembers.isNotEmpty
|
||||
? item.teamMembers
|
||||
.firstWhere((member) => member.isLeader)
|
||||
.name
|
||||
.trim()
|
||||
: '',
|
||||
),
|
||||
streamUrl: streamUrl,
|
||||
),
|
||||
@@ -483,9 +490,10 @@ String _formatTitle(EventRegistrationItem item) {
|
||||
}
|
||||
|
||||
String _formatVenue(EventRegistrationItem item, int scheduleIndex) {
|
||||
final place = item.matchPlace.trim();
|
||||
if (place.isEmpty) return '$scheduleIndex号场馆$scheduleIndex区';
|
||||
return '$place号场馆$scheduleIndex区';
|
||||
return item.matchPlace.trim();
|
||||
// final place = item.matchPlace.trim();
|
||||
// if (place.isEmpty) return '$scheduleIndex号场馆$scheduleIndex区';
|
||||
// return '$place号场馆$scheduleIndex区';
|
||||
}
|
||||
|
||||
String _formatScheduleTime(EventRegistrationItem item) {
|
||||
@@ -518,9 +526,10 @@ String _formatOpponentLine(EventRegistrationItem item) {
|
||||
}
|
||||
|
||||
String _formatNumberBadge(EventRegistrationItem item) {
|
||||
final place = item.matchPlace.trim();
|
||||
if (place.isEmpty) return '';
|
||||
final match = RegExp(r'\d+').firstMatch(place);
|
||||
if (match != null) return '${match.group(0)}号';
|
||||
return place;
|
||||
return item.playerNo.trim().isEmpty ? '' : '${item.playerNo.trim()}号';
|
||||
// final place = item.matchPlace.trim();
|
||||
// if (place.isEmpty) return '';
|
||||
// final match = RegExp(r'\d+').firstMatch(place);
|
||||
// if (match != null) return '${match.group(0)}号';
|
||||
// return place;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,11 @@ class RecordingContext {
|
||||
required this.playerPhone,
|
||||
this.laneNo,
|
||||
this.status,
|
||||
this.isTeam = false,
|
||||
|
||||
/// 对方队长
|
||||
this.opponentName = '',
|
||||
this.teamLeaderName = '',
|
||||
});
|
||||
|
||||
const RecordingContext.empty()
|
||||
@@ -20,7 +25,10 @@ class RecordingContext {
|
||||
playerName = '',
|
||||
playerPhone = '',
|
||||
laneNo = null,
|
||||
status = null;
|
||||
status = null,
|
||||
isTeam = false,
|
||||
opponentName = '',
|
||||
teamLeaderName = '';
|
||||
|
||||
final String eventTitle;
|
||||
final String matchName;
|
||||
@@ -31,8 +39,12 @@ class RecordingContext {
|
||||
final String playerPhone;
|
||||
final String? laneNo;
|
||||
final String? status;
|
||||
final bool isTeam;
|
||||
final String opponentName;
|
||||
final String teamLeaderName;
|
||||
|
||||
String get title => '$matchName $group';
|
||||
String get title =>
|
||||
isTeam ? '$teamLeaderName 队伍 vs $opponentName 队伍' : '$playerName $group';
|
||||
|
||||
String get address => venue;
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import 'package:recording_tool/features/recording/widgets/widget_recording_hud.d
|
||||
import 'package:recording_tool/features/recording/widgets/widget_recording_loading_overlay.dart';
|
||||
import 'package:recording_tool/features/recording/widgets/widget_recording_saved_dialog.dart';
|
||||
import 'package:recording_tool/features/recording/widgets/widget_recording_touch_lock_overlay.dart';
|
||||
import 'package:recording_tool/features/scan_qrcode/pages/page_scan_qrcode.dart';
|
||||
import 'package:recording_tool/features/scan_qrcode/utils/rtmp_stream_target.dart';
|
||||
import 'package:recording_tool/shared/widgets/widgets.dart';
|
||||
|
||||
@@ -403,7 +404,7 @@ class _RecordingPageState extends ConsumerState<RecordingPage> {
|
||||
|
||||
/// 返回扫码页,准备新一轮录制。
|
||||
void _recordNewRound() {
|
||||
AppNavigator.pop(context: context);
|
||||
AppNavigator.pushAndRemoveUntil(const ScanQrCodePage());
|
||||
}
|
||||
|
||||
/// 推流结束后按需弹出完成对话框
|
||||
|
||||
@@ -11,8 +11,8 @@ Future<void> showRecordingSavedDialog(
|
||||
return RecordDialog.showDouble(
|
||||
context,
|
||||
title: '本轮比赛视频已保存\n请选择后续录制信息',
|
||||
leftText: '继续本轮',
|
||||
rightText: '录制新轮',
|
||||
leftText: '继当前选手',
|
||||
rightText: '录新选手',
|
||||
onLeftPressed: onContinueRound,
|
||||
onRightPressed: onRecordNewRound,
|
||||
barrierDismissible: false,
|
||||
|
||||
Reference in New Issue
Block a user