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/router/app_navigator.dart'; import 'package:recording_tool/core/cache/app_storage.dart'; import 'package:recording_tool/core/cache/storage_keys.dart'; import 'package:recording_tool/core/utils/device_utils.dart'; import 'package:recording_tool/features/auth/view_model_auth/view_model_auth.dart'; import 'package:recording_tool/features/scan_qrcode/pages/page_scan_qrcode.dart'; import 'package:recording_tool/gen/assets.gen.dart'; import 'package:recording_tool/shared/widgets/app_dialog.dart'; import 'package:recording_tool/shared/widgets/app_toast.dart'; class AuthPageWidget extends ConsumerStatefulWidget { const AuthPageWidget({super.key}); @override ConsumerState createState() => _AuthPageWidgetState(); } class _AuthPageWidgetState extends ConsumerState { late final TextEditingController _controller; /// 记录点击次数 int _clickCount = 0; @override void initState() { super.initState(); _controller = TextEditingController(text: ''); WidgetsBinding.instance.addPostFrameCallback((_) async { final token = AppStorage.getString(StorageKeys.authToken); if (token?.isNotEmpty ?? false) { final success = await ref .read(authProvider.notifier) .parseTokenSetState(); if (!success) { return; } AppNavigator.push(const ScanQrCodePage()); } }); } @override void dispose() { _controller.dispose(); super.dispose(); } void _showDeviceCodeDialog() async { final deviceCode = await DeviceUtils.deviceCode(); if (!mounted) return; AppDialog.confirm(context, title: '设备码:$deviceCode'); } @override Widget build(BuildContext context) { final authState = ref.watch(authProvider); return AnnotatedRegion( value: SystemUiOverlayStyle.dark.copyWith( statusBarColor: Colors.transparent, systemNavigationBarColor: Colors.white, ), child: Scaffold( backgroundColor: Colors.white, body: Stack( children: [ Positioned.fill( child: Image.asset( _AuthAssets.pageBg, width: double.infinity, fit: BoxFit.fill, ), ), SafeArea( child: Padding( padding: EdgeInsets.symmetric(horizontal: 32.w), child: SingleChildScrollView( child: Column( children: [ SizedBox(height: 190.h), ClipRRect( borderRadius: BorderRadius.circular(24.r), child: GestureDetector( onTap: () { _clickCount++; if (_clickCount >= 5) { _showDeviceCodeDialog(); _clickCount = 0; } }, child: Image.asset( _AuthAssets.appIcon, width: 82.w, height: 82.w, fit: BoxFit.cover, ), ), ), SizedBox(height: 18.h), Image.asset( _AuthAssets.appNameText, width: 132.w, height: 28.w, fit: BoxFit.cover, ), SizedBox(height: 78.h), _PassCodeInput(controller: _controller), SizedBox(height: 20.h), _GradientConfirmButton( isLoading: authState.isLoading, onPressed: _handleSubmit, ), // SizedBox(height: 20.h), // AppButton( // onPressed: () async { // final deviceCode = await DeviceUtils.deviceCode(); // if (!mounted) return; // AppDialog.confirm(context, title: '设备码:$deviceCode'); // }, // label: '获取设备码', // ), ], ), ), ), ), ], ), ), ); } Future _handleSubmit() async { final success = await ref .read(authProvider.notifier) .auth(_controller.text); if (!mounted) return; if (success) { AppNavigator.push(const ScanQrCodePage()); return; } final message = ref.read(authProvider).errorMessage; if (message != null && message.isNotEmpty) { AppToast.show(message); } } } class _PassCodeInput extends StatelessWidget { const _PassCodeInput({required this.controller}); final TextEditingController controller; @override Widget build(BuildContext context) { return Container( height: 50.h, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12.r), boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.08), blurRadius: 10.r, offset: Offset(0, 2.h), ), ], ), child: TextField( controller: controller, keyboardType: TextInputType.number, textAlign: TextAlign.center, maxLength: 6, inputFormatters: [ FilteringTextInputFormatter.digitsOnly, LengthLimitingTextInputFormatter(6), ], style: TextStyle( color: const Color(0xFF2F3338), fontSize: 16.sp, fontWeight: FontWeight.w500, ), decoration: InputDecoration( hintText: '请输入执裁口令', hintStyle: TextStyle( color: const Color(0xFFB6B9BF), fontSize: 16.sp, fontWeight: FontWeight.w400, ), counterText: '', border: InputBorder.none, contentPadding: EdgeInsets.symmetric( horizontal: 16.w, vertical: 14.h, ), ), ), ); } } class _GradientConfirmButton extends StatelessWidget { const _GradientConfirmButton({ required this.isLoading, required this.onPressed, }); final bool isLoading; final VoidCallback onPressed; @override Widget build(BuildContext context) { return Opacity( opacity: isLoading ? 0.72 : 1, child: GestureDetector( onTap: isLoading ? null : onPressed, child: Container( height: 50.h, width: double.infinity, alignment: Alignment.center, decoration: BoxDecoration( borderRadius: BorderRadius.circular(25.r), gradient: const LinearGradient( colors: [Color(0xFF268DFF), Color(0xFF5DD4F6)], ), boxShadow: [ BoxShadow( color: const Color(0xFF2196F3).withValues(alpha: 0.28), blurRadius: 14.r, offset: Offset(0, 6.h), ), ], ), child: isLoading ? SizedBox.square( dimension: 18.r, child: CircularProgressIndicator( strokeWidth: 2.r, valueColor: const AlwaysStoppedAnimation( Colors.white, ), ), ) : Text( '确定', style: TextStyle( color: Colors.white, fontSize: 16.sp, fontWeight: FontWeight.w500, ), ), ), ), ); } } class _AuthAssets { const _AuthAssets._(); static String pageBg = Assets.images.imagePageBg.path; static String appIcon = Assets.images.imageAppIcon.path; static String appNameText = Assets.images.imageAppNameText.path; }