qrcode_scan_page.dart 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. import 'dart:io';
  2. import 'package:flutter/cupertino.dart';
  3. import 'package:flutter/material.dart';
  4. import 'package:flutter/services.dart';
  5. import 'package:flutter/widgets.dart';
  6. import 'package:lszlgl/page/sample_task/reap_sample_detail/reap_sample_task_page.dart';
  7. import 'package:qr_code_scanner/qr_code_scanner.dart';
  8. import '../../base/base_lifecycle_state.dart';
  9. import '../../widget/button.dart';
  10. class QrCodeScanPage extends StatefulWidget {
  11. const QrCodeScanPage({super.key});
  12. @override
  13. State<QrCodeScanPage> createState() => _QrCodeScanPageState();
  14. }
  15. class _QrCodeScanPageState extends BaseLifecycleState<QrCodeScanPage> with SingleTickerProviderStateMixin {
  16. final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
  17. Barcode? result;
  18. QRViewController? controller;
  19. late AnimationController _ctrl;
  20. late Animation<Offset> animation;
  21. void _onQRViewCreated(QRViewController controller) {
  22. this.controller = controller;
  23. controller.scannedDataStream.listen((scanData) {
  24. debugPrint('code:${scanData.code} format:${scanData.format} rawBytes:${scanData.rawBytes}');
  25. controller.pauseCamera();
  26. parseCode(scanData);
  27. });
  28. }
  29. void parseCode(Barcode data) {
  30. String code = data.code ?? '';
  31. if (code.isEmpty) {
  32. showErrorDialog('内容为空,请扫描正确二维码');
  33. return;
  34. }
  35. // 库房详情 http://121.36.17.6:18089/?ajbm=3291653123710827520U010011
  36. if(code.contains('?ajbm=')){
  37. List<String> list = code.split('ajbm=');
  38. if(list.last.isEmpty){
  39. showErrorDialog(code);
  40. return;
  41. }else{
  42. MyRouter.startStoreHouse(list.last);
  43. return;
  44. }
  45. }
  46. // 121.36.17.6:19090/admin-api/zj/code-sampling-task-details-sgjc/getSamplingTaskDetails?id=47106
  47. List<String> split = code.split('?');
  48. if (!code.contains('?') || split.length <= 1 || !split[0].contains('/')) {
  49. showErrorDialog(code);
  50. return;
  51. }
  52. String api = split[0].split('/').last;
  53. Map<String, String> params = {};
  54. for (String value in split[1].split('&')) {
  55. List<String> kv = value.split('=');
  56. params[kv[0]] = kv[1];
  57. }
  58. switch (api) {
  59. case 'getSamplingTaskDetails':
  60. // 收获扦样详情
  61. if (params['id'] == null) {
  62. showErrorDialog(code);
  63. return;
  64. }
  65. MyRouter.startReapSampleTask(
  66. args: ReapSampleTaskPageArgs(id: num.parse(params['id']!), detail: true),
  67. replace: true,
  68. );
  69. default:
  70. showErrorDialog(code);
  71. }
  72. }
  73. void showErrorDialog(String msg) async {
  74. await showDialog(
  75. context: context,
  76. builder: (_) => AlertDialog(
  77. title: Text(msg),
  78. actions: [MyButton('确定', alignment: null, onTap: () => MyNavigator.pop())],
  79. ),
  80. );
  81. controller?.resumeCamera();
  82. }
  83. // In order to get hot reload to work we need to pause the camera if the platform
  84. // is android, or resume the camera if the platform is iOS.
  85. @override
  86. void reassemble() {
  87. super.reassemble();
  88. if (Platform.isAndroid) {
  89. controller!.pauseCamera();
  90. } else if (Platform.isIOS) {
  91. controller!.resumeCamera();
  92. }
  93. }
  94. @override
  95. void dispose() {
  96. controller?.dispose();
  97. _ctrl.dispose();
  98. super.dispose();
  99. }
  100. @override
  101. void initState() {
  102. super.initState();
  103. // 创建动画控制器
  104. _ctrl = AnimationController(
  105. vsync: this,
  106. duration: const Duration(seconds: 2),
  107. );
  108. animation = Tween<Offset>(
  109. begin: const Offset(0, -0.25),
  110. end: const Offset(0, 0.25),
  111. ).animate(_ctrl);
  112. _ctrl.repeat();
  113. }
  114. @override
  115. Widget build(BuildContext context) {
  116. return myScaffold(child: buildBody());
  117. }
  118. Widget buildBody() {
  119. return AnnotatedRegion<SystemUiOverlayStyle>(
  120. value: SystemUiOverlayStyle.light,
  121. child: Stack(
  122. fit: StackFit.expand,
  123. children: [
  124. // myAppBar(
  125. // title: '扫一扫',
  126. // actions: [buildFlash()],
  127. // ),
  128. Positioned.fill(
  129. child: QRView(
  130. key: qrKey,
  131. onQRViewCreated: _onQRViewCreated,
  132. ),
  133. ),
  134. Positioned(
  135. top: 0,
  136. left: 0,
  137. right: 0,
  138. child: buildAppBar(),
  139. ),
  140. SlideTransition(
  141. position: animation,
  142. child: Image.asset(imgScanScanning, width: double.infinity),
  143. ),
  144. ],
  145. ),
  146. );
  147. }
  148. Widget buildAppBar() {
  149. return Padding(
  150. padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top),
  151. child: Stack(
  152. alignment: Alignment.center,
  153. children: [
  154. Positioned(left: 0, child: buildBack()),
  155. const Text(
  156. '扫一扫',
  157. textAlign: TextAlign.center,
  158. style: TextStyle(color: Colors.white, fontSize: 20),
  159. ),
  160. Positioned(
  161. right: 0,
  162. child: buildFlash(),
  163. ),
  164. ],
  165. ),
  166. );
  167. }
  168. Widget buildBack() {
  169. return GestureDetector(
  170. onTap: () => MyNavigator.pop(),
  171. child: Padding(
  172. padding: const EdgeInsets.symmetric(horizontal: 16),
  173. child: Image.asset(imgScanBack, width: 24, height: 24),
  174. ),
  175. );
  176. }
  177. Widget buildFlash() {
  178. return GestureDetector(
  179. onTap: () => controller?.toggleFlash(),
  180. behavior: HitTestBehavior.opaque,
  181. child: Padding(
  182. padding: const EdgeInsets.symmetric(horizontal: 16),
  183. child: Row(
  184. children: [
  185. Image.asset(imgScanFlash, width: 24, height: 24),
  186. const Text(
  187. '闪光灯',
  188. textAlign: TextAlign.center,
  189. style: TextStyle(color: Colors.white, fontSize: 14),
  190. ),
  191. ],
  192. ),
  193. ),
  194. );
  195. }
  196. }