import 'dart:io'; import 'package:dating_touchme_app/model/mine/bank_card_ocr_data.dart'; import 'package:dating_touchme_app/network/user_api.dart'; import 'package:dating_touchme_app/oss/oss_manager.dart'; import 'package:flustars/flustars.dart'; import 'package:flutter/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; import 'package:get/get_state_manager/src/simple/get_controllers.dart'; import 'package:image_picker/image_picker.dart'; import 'package:permission_handler/permission_handler.dart'; class AddBankcardController extends GetxController { late UserApi _userApi; final username = ''.obs; final usernameController = TextEditingController().obs; final cardNum = ''.obs; final cardNumController = TextEditingController().obs; final bankName = ''.obs; final bankNameController = TextEditingController().obs; final openingBank = ''.obs; final openingBankController = TextEditingController().obs; @override void onInit() { super.onInit(); _userApi = Get.find(); } // 选择头像 - 业务逻辑处理 Future handleCameraCapture() async { try { // 请求相机权限 final ok = await _ensurePermission( Permission.camera, denyToast: '相机权限被拒绝,请在设置中允许访问相机', ); if (!ok) return; // 请求麦克风权限(部分设备拍照/录像会一并请求建议预授权) await _ensurePermission(Permission.microphone, denyToast: '麦克风权限被拒绝'); // 权限通过后拍照 final ImagePicker picker = ImagePicker(); final XFile? photo = await picker.pickImage(source: ImageSource.camera); if (photo != null) { await processSelectedImage(File(photo.path)); } } catch (e) { print('拍照失败: $e'); // 更友好的错误提示 if (e.toString().contains('permission') || e.toString().contains('权限')) { SmartDialog.showToast('相机权限被拒绝,请在设置中允许访问相机'); } else if (e.toString().contains('camera') || e.toString().contains('相机')) { SmartDialog.showToast('设备没有可用的相机'); } else { SmartDialog.showToast('拍照失败,请重试'); } } } Future handleGallerySelection() async { try { // 请求相册/照片权限 // final ok = await _ensurePermission( // Permission.photos, // // Android 上 photos 等价于 storage/mediaLibrary,permission_handler 会映射 // denyToast: '相册权限被拒绝,请在设置中允许访问相册', // ); // if (!ok) return; // 从相册选择图片 final ImagePicker picker = ImagePicker(); final XFile? image = await picker.pickImage(source: ImageSource.gallery); if (image != null) { await processSelectedImage(File(image.path)); } } catch (e) { print('选择图片失败: $e'); // 更友好的错误提示 if (e.toString().contains('permission') || e.toString().contains('权限')) { SmartDialog.showToast('相册权限被拒绝,请在设置中允许访问相册'); } else { SmartDialog.showToast('选择图片失败,请重试'); } } } // 通用权限申请 Future _ensurePermission(Permission permission, {String? denyToast}) async { var status = await permission.status; if (status.isGranted) return true; if (status.isDenied || status.isRestricted || status.isLimited) { status = await permission.request(); if (status.isGranted) return true; if (denyToast != null) SmartDialog.showToast(denyToast); return false; } if (status.isPermanentlyDenied) { if (denyToast != null) SmartDialog.showToast('$denyToast,前往系统设置开启'); // 延迟弹设置,避免与弹窗冲突 Future.delayed(const Duration(milliseconds: 300), openAppSettings); return false; } return false; } // 处理选中的图片 Future processSelectedImage(File imageFile) async { try { // 显示加载提示 SmartDialog.showLoading(msg: '识别银行卡中...'); String objectName = '${DateUtil.getNowDateMs()}.${imageFile.path.split('.').last}'; String imageUrl = await OSSManager.instance.uploadFile(imageFile.readAsBytesSync(), objectName); print('上传成功,图片URL: $imageUrl'); ocrBankCard(imageUrl); // SmartDialog.dismiss(); // SmartDialog.showToast('银行卡上传成功'); } catch (e) { SmartDialog.dismiss(); print('处理图片失败: $e'); SmartDialog.showToast('银行卡上传失败,请重试'); } } ocrBankCard(String url) async { try { final response = await _userApi.recognizeBankCard({ "url":url }); if (response.data.isSuccess) { final BankCardOcrData data = response.data.data ?? BankCardOcrData(); bankName.value = data.bankName ?? ""; bankNameController.value.value = TextEditingValue( text: bankName.value, selection: TextSelection.fromPosition(TextPosition(offset: bankName.value.length)), ); cardNum.value = data.cardNum ?? ""; cardNumController.value.value = TextEditingValue( text: cardNum.value, selection: TextSelection.fromPosition(TextPosition(offset: cardNum.value.length)), ); SmartDialog.dismiss(); SmartDialog.showToast('银行卡识别成功'); } else{ SmartDialog.showToast(response.data.message); return; } } catch (e){ print('银行卡识别失败: $e'); SmartDialog.showToast('银行卡识别失败,请重试'); return; } } saveCard() async { if(username.value == ""){ SmartDialog.showToast('请输入持卡人姓名'); return; } if(cardNum.value == ""){ SmartDialog.showToast('请输入卡号'); return; } if(bankName.value == ""){ SmartDialog.showToast('请输入所属银行'); return; } if(openingBank.value == ""){ SmartDialog.showToast('请输入开户行'); return; } final payload = { "ownerName": username.value, "cardNum": cardNum.value, "bankName": bankName.value, "openingBank": openingBank.value, }; try { final response = await _userApi.createBankCardByIndividual(payload); if (response.data.isSuccess) { SmartDialog.showToast('保存成功'); Get.back(); } else{ SmartDialog.showToast(response.data.message); return; } } catch (e){ print('保存失败: $e'); SmartDialog.showToast('保存失败,请重试'); return; } } }