diff --git a/frontend/mobile-app/lib/features/authorization/presentation/pages/authorization_apply_page.dart b/frontend/mobile-app/lib/features/authorization/presentation/pages/authorization_apply_page.dart index 14a1fda3..a50d33de 100644 --- a/frontend/mobile-app/lib/features/authorization/presentation/pages/authorization_apply_page.dart +++ b/frontend/mobile-app/lib/features/authorization/presentation/pages/authorization_apply_page.dart @@ -49,6 +49,12 @@ class AuthorizationApplyPage extends ConsumerStatefulWidget { class _AuthorizationApplyPageState extends ConsumerState { + /// 本地存储 key(与认种页面保持一致) + static const String _keyProvinceName = 'planting_province_name'; + static const String _keyProvinceCode = 'planting_province_code'; + static const String _keyCityName = 'planting_city_name'; + static const String _keyCityCode = 'planting_city_code'; + /// 选中的授权类型 AuthorizationType? _selectedType; @@ -73,10 +79,40 @@ class _AuthorizationApplyPageState /// 用户已有的授权 List _existingAuthorizations = []; + /// 保存的省市信息(来自认种时选择) + String? _savedProvinceName; + String? _savedProvinceCode; + String? _savedCityName; + String? _savedCityCode; + + /// 社区名称输入控制器 + final TextEditingController _communityNameController = TextEditingController(); + @override void initState() { super.initState(); _loadUserStatus(); + _loadSavedLocation(); + } + + @override + void dispose() { + _communityNameController.dispose(); + super.dispose(); + } + + /// 从本地存储加载保存的省市信息 + void _loadSavedLocation() { + try { + final localStorage = ref.read(localStorageProvider); + _savedProvinceName = localStorage.getString(_keyProvinceName); + _savedProvinceCode = localStorage.getString(_keyProvinceCode); + _savedCityName = localStorage.getString(_keyCityName); + _savedCityCode = localStorage.getString(_keyCityCode); + debugPrint('[AuthorizationApplyPage] 加载省市: $_savedProvinceName · $_savedCityName'); + } catch (e) { + debugPrint('[AuthorizationApplyPage] 加载省市失败: $e'); + } } /// 加载用户状态 @@ -170,6 +206,164 @@ class _AuthorizationApplyPageState }); } + /// 显示授权确认弹窗 + Future _showAuthorizationConfirmDialog(AuthorizationType type) { + String title; + String locationInfo; + String? additionalField; + + switch (type) { + case AuthorizationType.community: + title = '申请社区授权'; + locationInfo = '请输入您的社区名称'; + additionalField = 'community'; + break; + case AuthorizationType.cityTeam: + title = '申请市团队授权'; + if (_savedCityName == null || _savedCityCode == null) { + _showErrorSnackBar('未找到认种时保存的城市信息,请先完成认种'); + return Future.value(false); + } + locationInfo = '城市: $_savedCityName'; + break; + case AuthorizationType.provinceTeam: + title = '申请省团队授权'; + if (_savedProvinceName == null || _savedProvinceCode == null) { + _showErrorSnackBar('未找到认种时保存的省份信息,请先完成认种'); + return Future.value(false); + } + locationInfo = '省份: $_savedProvinceName'; + break; + } + + return showDialog( + context: context, + barrierDismissible: true, + builder: (context) => AlertDialog( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + ), + title: Text( + title, + style: const TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + color: Color(0xFF5D4037), + ), + ), + content: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (additionalField == 'community') ...[ + const Text( + '社区名称', + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w500, + color: Color(0xFF745D43), + ), + ), + const SizedBox(height: 8), + TextField( + controller: _communityNameController, + decoration: InputDecoration( + hintText: '请输入社区名称', + hintStyle: TextStyle( + color: const Color(0xFF745D43).withOpacity(0.5), + ), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(8), + borderSide: const BorderSide(color: Color(0x4D8B5A2B)), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(8), + borderSide: const BorderSide(color: Color(0xFFD4AF37), width: 2), + ), + contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10), + ), + ), + ] else ...[ + Container( + width: double.infinity, + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: const Color(0xFFFFF5E6), + borderRadius: BorderRadius.circular(8), + border: Border.all(color: const Color(0x33D4AF37)), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + locationInfo, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: Color(0xFF5D4037), + ), + ), + const SizedBox(height: 8), + Text( + '此信息来自您认种时的选择,不可修改', + style: TextStyle( + fontSize: 12, + color: const Color(0xFF745D43).withOpacity(0.7), + ), + ), + ], + ), + ), + ], + const SizedBox(height: 16), + Text( + '确认申请后将使用以上信息提交授权申请', + style: TextStyle( + fontSize: 13, + color: const Color(0xFF745D43).withOpacity(0.8), + ), + ), + ], + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(false), + child: const Text( + '取消', + style: TextStyle(color: Color(0xFF745D43)), + ), + ), + ElevatedButton( + onPressed: () { + if (additionalField == 'community') { + if (_communityNameController.text.trim().isEmpty) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('请输入社区名称'), + backgroundColor: Colors.red, + ), + ); + return; + } + } + Navigator.of(context).pop(true); + }, + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xFFD4AF37), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + ), + child: const Text( + '确认申请', + style: TextStyle(color: Colors.white), + ), + ), + ], + ), + ); + } + /// 提交申请 Future _submitApplication() async { // 验证 @@ -200,6 +394,12 @@ class _AuthorizationApplyPageState return; } + // 显示确认弹窗 + final confirmed = await _showAuthorizationConfirmDialog(_selectedType!); + if (confirmed != true) { + return; + } + setState(() { _isSubmitting = true; }); @@ -220,15 +420,26 @@ class _AuthorizationApplyPageState // 2. 将 AuthorizationType 转换为 SelfApplyAuthorizationType SelfApplyAuthorizationType selfApplyType; + String? communityName; + String? provinceCode; + String? provinceName; + String? cityCode; + String? cityName; + switch (_selectedType!) { case AuthorizationType.community: selfApplyType = SelfApplyAuthorizationType.community; + communityName = _communityNameController.text.trim(); break; case AuthorizationType.cityTeam: selfApplyType = SelfApplyAuthorizationType.cityTeam; + cityCode = _savedCityCode; + cityName = _savedCityName; break; case AuthorizationType.provinceTeam: selfApplyType = SelfApplyAuthorizationType.provinceTeam; + provinceCode = _savedProvinceCode; + provinceName = _savedProvinceName; break; } @@ -236,6 +447,11 @@ class _AuthorizationApplyPageState await authService.selfApplyAuthorization( type: selfApplyType, officePhotoUrls: photoUrls, + communityName: communityName, + provinceCode: provinceCode, + provinceName: provinceName, + cityCode: cityCode, + cityName: cityName, ); if (mounted) { @@ -245,7 +461,7 @@ class _AuthorizationApplyPageState ScaffoldMessenger.of(context).showSnackBar( const SnackBar( - content: Text('申请已提交,请等待审核'), + content: Text('授权申请成功!'), backgroundColor: Color(0xFF4CAF50), ), ); @@ -426,7 +642,7 @@ class _AuthorizationApplyPageState '1. 申请账户必须已完成认种\n' '2. 需提供办公室照片(至少2张)\n' '3. 社区、市团队、省团队支持自助申请\n' - '4. 提交后等待审核,审核通过后生效', + '4. 提交后立即生效,权益需达到考核目标后激活', style: TextStyle( fontSize: 14, fontFamily: 'Inter',