import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:lszlgl/page/sample_task/reap_sample_detail/reap_sample_task_page.dart'; import 'package:qr_code_scanner/qr_code_scanner.dart'; import '../../base/base_lifecycle_state.dart'; import '../../widget/button.dart'; class QrCodeScanPage extends StatefulWidget { const QrCodeScanPage({super.key}); @override State createState() => _QrCodeScanPageState(); } class _QrCodeScanPageState extends BaseLifecycleState with SingleTickerProviderStateMixin { final GlobalKey qrKey = GlobalKey(debugLabel: 'QR'); Barcode? result; QRViewController? controller; late AnimationController _ctrl; late Animation animation; void _onQRViewCreated(QRViewController controller) { this.controller = controller; controller.scannedDataStream.listen((scanData) { debugPrint('code:${scanData.code} format:${scanData.format} rawBytes:${scanData.rawBytes}'); controller.pauseCamera(); parseCode(scanData); }); } void parseCode(Barcode data) { String code = data.code ?? ''; if (code.isEmpty) { showErrorDialog('内容为空,请扫描正确二维码'); return; } // 库房详情 http://121.36.17.6:18089/?ajbm=3291653123710827520U010011 if(code.contains('?ajbm=')){ List list = code.split('ajbm='); if(list.last.isEmpty){ showErrorDialog(code); return; }else{ MyRouter.startStoreHouse(list.last); return; } } // 121.36.17.6:19090/admin-api/zj/code-sampling-task-details-sgjc/getSamplingTaskDetails?id=47106 List split = code.split('?'); if (!code.contains('?') || split.length <= 1 || !split[0].contains('/')) { showErrorDialog(code); return; } String api = split[0].split('/').last; Map params = {}; for (String value in split[1].split('&')) { List kv = value.split('='); params[kv[0]] = kv[1]; } switch (api) { case 'getSamplingTaskDetails': // 收获扦样详情 if (params['id'] == null) { showErrorDialog(code); return; } MyRouter.startReapSampleTask( args: ReapSampleTaskPageArgs(id: num.parse(params['id']!), detail: true), replace: true, ); default: showErrorDialog(code); } } void showErrorDialog(String msg) async { await showDialog( context: context, builder: (_) => AlertDialog( title: Text(msg), actions: [MyButton('确定', alignment: null, onTap: () => MyNavigator.pop())], ), ); controller?.resumeCamera(); } // In order to get hot reload to work we need to pause the camera if the platform // is android, or resume the camera if the platform is iOS. @override void reassemble() { super.reassemble(); if (Platform.isAndroid) { controller!.pauseCamera(); } else if (Platform.isIOS) { controller!.resumeCamera(); } } @override void dispose() { controller?.dispose(); _ctrl.dispose(); super.dispose(); } @override void initState() { super.initState(); // 创建动画控制器 _ctrl = AnimationController( vsync: this, duration: const Duration(seconds: 2), ); animation = Tween( begin: const Offset(0, -0.25), end: const Offset(0, 0.25), ).animate(_ctrl); _ctrl.repeat(); } @override Widget build(BuildContext context) { return myScaffold(child: buildBody()); } Widget buildBody() { return AnnotatedRegion( value: SystemUiOverlayStyle.light, child: Stack( fit: StackFit.expand, children: [ // myAppBar( // title: '扫一扫', // actions: [buildFlash()], // ), Positioned.fill( child: QRView( key: qrKey, onQRViewCreated: _onQRViewCreated, ), ), Positioned( top: 0, left: 0, right: 0, child: buildAppBar(), ), SlideTransition( position: animation, child: Image.asset(imgScanScanning, width: double.infinity), ), ], ), ); } Widget buildAppBar() { return Padding( padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top), child: Stack( alignment: Alignment.center, children: [ Positioned(left: 0, child: buildBack()), const Text( '扫一扫', textAlign: TextAlign.center, style: TextStyle(color: Colors.white, fontSize: 20), ), Positioned( right: 0, child: buildFlash(), ), ], ), ); } Widget buildBack() { return GestureDetector( onTap: () => MyNavigator.pop(), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Image.asset(imgScanBack, width: 24, height: 24), ), ); } Widget buildFlash() { return GestureDetector( onTap: () => controller?.toggleFlash(), behavior: HitTestBehavior.opaque, child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Row( children: [ Image.asset(imgScanFlash, width: 24, height: 24), const Text( '闪光灯', textAlign: TextAlign.center, style: TextStyle(color: Colors.white, fontSize: 14), ), ], ), ), ); } }