1.还原授权页 UI

2.还原扫码页 UI
This commit is contained in:
2026-07-27 16:52:58 +08:00
parent 20d501f673
commit 686db244fd
11 changed files with 445 additions and 195 deletions
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
@@ -12,8 +13,6 @@ import 'package:recording_tool/features/events/model/model_event_info.dart';
import 'package:recording_tool/features/events/pages/page_event_info.dart';
import 'package:recording_tool/features/events/view_model/view_model_event_info.dart';
import 'package:recording_tool/features/recording/model/model_recording_context.dart';
import 'package:recording_tool/shared/widgets/app_bar.dart';
import 'package:recording_tool/shared/widgets/app_button.dart';
import 'package:recording_tool/shared/widgets/app_qr_scanner_dialog.dart';
import 'package:recording_tool/shared/widgets/app_toast.dart';
@@ -34,10 +33,10 @@ class ScanQrCodePage extends ConsumerStatefulWidget {
);
@override
ConsumerState<ScanQrCodePage> createState() => _AuthPageWidgetState();
ConsumerState<ScanQrCodePage> createState() => _ScanQrCodePageState();
}
class _AuthPageWidgetState extends ConsumerState<ScanQrCodePage> {
class _ScanQrCodePageState extends ConsumerState<ScanQrCodePage> {
@override
void initState() {
super.initState();
@@ -58,109 +57,106 @@ class _AuthPageWidgetState extends ConsumerState<ScanQrCodePage> {
@override
Widget build(BuildContext context) {
final eventName = ref.watch(
authProvider.select(
(state) => state.jwtDecodedData?.eventName?.trim() ?? '',
),
);
return PopScope(
canPop: true,
onPopInvokedWithResult: (didPop, result) async {
if (!didPop) return;
await ref.read(authProvider.notifier).clearAuth();
},
child: Scaffold(
appBar: myAppBar(context: context, title: '扫码'),
body: Center(
child: Column(
child: AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle.dark.copyWith(
statusBarColor: Colors.transparent,
systemNavigationBarColor: Colors.white,
),
child: Scaffold(
backgroundColor: Colors.white,
body: Stack(
children: [
SizedBox(height: 100.h),
Text(
'裁判工作台',
style: TextStyle(fontSize: 30, color: Colors.black),
Positioned(
top: 0,
left: 0,
right: 0,
child: Image.asset(
_ScanAssets.pageBg,
width: double.infinity,
fit: BoxFit.fitWidth,
),
),
SizedBox(height: 100.h),
Text(
'扫描选手参赛凭证进行执裁',
style: TextStyle(fontSize: 30, color: Colors.black),
),
SizedBox(height: 20.h),
// Consumer(
// builder: (context, ref, child) {
// return SizedBox(
// width: 280.w,
// height: 80.h,
// child: AppButton(
// label: '查看录像',
// onPressed: () async {
// final data = ref.watch(
// authProvider.select((state) => state.jwtDecodedData),
// );
// if (data == null) return;
// debugPrint('赛事名字: ${data.eventName}');
// final eventName = data.eventName ?? '';
// await ref
// .read(authProvider.notifier)
// .getRecordList(eventName);
// },
// variant: AppButtonVariant.secondary,
// ),
// );
// },
// ),
SizedBox(height: 16.h),
Consumer(
builder: (context, ref, child) {
return SizedBox(
width: 280.w,
height: 80.h,
child: AppButton(
label: '参赛队伍',
onPressed: () async {
await AppNavigator.push(
const CompetitionTeamListPage(),
context: context,
);
},
variant: AppButtonVariant.secondary,
),
);
},
),
SizedBox(height: 16.h),
SizedBox(
width: 280.w,
height: 80.h,
child: AppButton(
label: '扫码',
onPressed: () async {
final String? playerId = await AppQrScannerDialog.show(
context,
);
if (playerId == null || playerId.isEmpty) {
AppToast.show('查询选手信息失败');
return;
}
EasyLoading.show(status: '查询选手信息...');
try {
final success = await ref
.read(eventInfoProvider.notifier)
.loadRegistrationList(
request: PlayerRegistrationListReq(
userId: playerId,
SafeArea(
child: Padding(
padding: EdgeInsets.fromLTRB(16.w, 12.h, 16.w, 32.h),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const _BrandHeader(),
SizedBox(height: 26.h),
Text(
eventName.isEmpty ? '赛事信息' : eventName,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: const Color(0xFF3C3F44),
fontSize: 24.sp,
fontWeight: FontWeight.w700,
height: 1.25,
),
),
const Spacer(flex: 134),
Center(
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: _handleScan,
child: Image.asset(
_ScanAssets.scanQrcode,
width: 166.w,
height: 165.w,
fit: BoxFit.contain,
),
),
),
SizedBox(height: 28.h),
Center(
child: Text(
'扫描选手参赛凭证进行执裁',
style: TextStyle(
color: const Color(0xFFABAFB6),
fontSize: 16.sp,
fontWeight: FontWeight.w400,
height: 1.2,
),
),
),
const Spacer(flex: 211),
Row(
children: [
Expanded(
child: _BottomOutlineButton(
label: '查看录像',
onPressed: _handleViewRecords,
),
);
EasyLoading.dismiss();
if (!success) {
AppToast.show('查询选手信息失败');
return;
}
if (!mounted) return;
AppNavigator.push(EventInfoPage(playerId: playerId));
} catch (error) {
AppToast.show('查询选手信息失败');
EasyLoading.dismiss();
}
},
variant: AppButtonVariant.secondary,
),
SizedBox(width: 12.w),
Expanded(
child: _BottomOutlineButton(
label: '参赛队伍',
onPressed: () async {
await AppNavigator.push(
const CompetitionTeamListPage(),
context: context,
);
},
),
),
],
),
],
),
),
),
],
@@ -169,4 +165,125 @@ class _AuthPageWidgetState extends ConsumerState<ScanQrCodePage> {
),
);
}
Future<void> _handleScan() async {
final String? playerId = await AppQrScannerDialog.show(context);
if (playerId == null || playerId.isEmpty) {
AppToast.show('查询选手信息失败');
return;
}
EasyLoading.show(status: '查询选手信息...');
try {
final success = await ref
.read(eventInfoProvider.notifier)
.loadRegistrationList(
request: PlayerRegistrationListReq(userId: playerId),
);
EasyLoading.dismiss();
if (!success) {
AppToast.show('查询选手信息失败');
return;
}
if (!mounted) return;
AppNavigator.push(EventInfoPage(playerId: playerId));
} catch (error) {
EasyLoading.dismiss();
AppToast.show('查询选手信息失败');
}
}
Future<void> _handleViewRecords() async {
final eventName = ref.read(authProvider).jwtDecodedData?.eventName ?? '';
if (eventName.trim().isEmpty) {
AppToast.show('暂无赛事信息');
return;
}
EasyLoading.show(status: '查询录像...');
try {
final success = await ref
.read(authProvider.notifier)
.getRecordList(eventName);
EasyLoading.dismiss();
if (!success) {
AppToast.show('暂无录像');
return;
}
AppToast.show('录像列表已更新');
} catch (error) {
EasyLoading.dismiss();
AppToast.show('查询录像失败');
}
}
}
class _BrandHeader extends StatelessWidget {
const _BrandHeader();
@override
Widget build(BuildContext context) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
Image.asset(
_ScanAssets.appIcon,
width: 34.w,
height: 34.w,
fit: BoxFit.cover,
),
SizedBox(width: 8.w),
Image.asset(
_ScanAssets.appNameText,
width: 117.w,
height: 29.w,
fit: BoxFit.contain,
),
],
);
}
}
class _BottomOutlineButton extends StatelessWidget {
const _BottomOutlineButton({required this.label, required this.onPressed});
final String label;
final VoidCallback onPressed;
@override
Widget build(BuildContext context) {
return SizedBox(
height: 38.h,
child: Material(
color: Colors.white.withValues(alpha: 0.08),
shape: StadiumBorder(
side: BorderSide(color: const Color(0xFF9CCEFF), width: 1.r),
),
child: InkWell(
onTap: onPressed,
customBorder: const StadiumBorder(),
child: Center(
child: Text(
label,
style: TextStyle(
color: const Color(0xFF53A7F3),
fontSize: 14.sp,
fontWeight: FontWeight.w500,
height: 1.2,
),
),
),
),
),
);
}
}
class _ScanAssets {
const _ScanAssets._();
static const pageBg = 'assets/images/image_page_bg.png';
static const appIcon = 'assets/images/image_app_icon.png';
static const appNameText = 'assets/images/image_app_name_text.png';
static const scanQrcode = 'assets/images/image_scan_qrcode.png';
}