feat(mobile-app): 自助申请授权添加确认弹窗和省市参数传递

- 从本地存储加载认种时保存的省市信息
- 市团队申请时显示城市确认弹窗
- 省团队申请时显示省份确认弹窗
- 社区申请时显示社区名称输入弹窗
- 提交时传递对应的省市/社区参数
- 更新申请说明文字为'立即生效'

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
hailin 2025-12-22 06:29:01 -08:00
parent 21519c1a97
commit 4daee6a650
1 changed files with 218 additions and 2 deletions

View File

@ -49,6 +49,12 @@ class AuthorizationApplyPage extends ConsumerStatefulWidget {
class _AuthorizationApplyPageState class _AuthorizationApplyPageState
extends ConsumerState<AuthorizationApplyPage> { extends ConsumerState<AuthorizationApplyPage> {
/// 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; AuthorizationType? _selectedType;
@ -73,10 +79,40 @@ class _AuthorizationApplyPageState
/// ///
List<String> _existingAuthorizations = []; List<String> _existingAuthorizations = [];
///
String? _savedProvinceName;
String? _savedProvinceCode;
String? _savedCityName;
String? _savedCityCode;
///
final TextEditingController _communityNameController = TextEditingController();
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_loadUserStatus(); _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<bool?> _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<bool>(
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<void> _submitApplication() async { Future<void> _submitApplication() async {
// //
@ -200,6 +394,12 @@ class _AuthorizationApplyPageState
return; return;
} }
//
final confirmed = await _showAuthorizationConfirmDialog(_selectedType!);
if (confirmed != true) {
return;
}
setState(() { setState(() {
_isSubmitting = true; _isSubmitting = true;
}); });
@ -220,15 +420,26 @@ class _AuthorizationApplyPageState
// 2. AuthorizationType SelfApplyAuthorizationType // 2. AuthorizationType SelfApplyAuthorizationType
SelfApplyAuthorizationType selfApplyType; SelfApplyAuthorizationType selfApplyType;
String? communityName;
String? provinceCode;
String? provinceName;
String? cityCode;
String? cityName;
switch (_selectedType!) { switch (_selectedType!) {
case AuthorizationType.community: case AuthorizationType.community:
selfApplyType = SelfApplyAuthorizationType.community; selfApplyType = SelfApplyAuthorizationType.community;
communityName = _communityNameController.text.trim();
break; break;
case AuthorizationType.cityTeam: case AuthorizationType.cityTeam:
selfApplyType = SelfApplyAuthorizationType.cityTeam; selfApplyType = SelfApplyAuthorizationType.cityTeam;
cityCode = _savedCityCode;
cityName = _savedCityName;
break; break;
case AuthorizationType.provinceTeam: case AuthorizationType.provinceTeam:
selfApplyType = SelfApplyAuthorizationType.provinceTeam; selfApplyType = SelfApplyAuthorizationType.provinceTeam;
provinceCode = _savedProvinceCode;
provinceName = _savedProvinceName;
break; break;
} }
@ -236,6 +447,11 @@ class _AuthorizationApplyPageState
await authService.selfApplyAuthorization( await authService.selfApplyAuthorization(
type: selfApplyType, type: selfApplyType,
officePhotoUrls: photoUrls, officePhotoUrls: photoUrls,
communityName: communityName,
provinceCode: provinceCode,
provinceName: provinceName,
cityCode: cityCode,
cityName: cityName,
); );
if (mounted) { if (mounted) {
@ -245,7 +461,7 @@ class _AuthorizationApplyPageState
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
const SnackBar( const SnackBar(
content: Text('申请已提交,请等待审核'), content: Text('授权申请成功!'),
backgroundColor: Color(0xFF4CAF50), backgroundColor: Color(0xFF4CAF50),
), ),
); );
@ -426,7 +642,7 @@ class _AuthorizationApplyPageState
'1. 申请账户必须已完成认种\n' '1. 申请账户必须已完成认种\n'
'2. 需提供办公室照片至少2张\n' '2. 需提供办公室照片至少2张\n'
'3. 社区、市团队、省团队支持自助申请\n' '3. 社区、市团队、省团队支持自助申请\n'
'4. 提交后等待审核,审核通过后生效', '4. 提交后立即生效,权益需达到考核目标后激活',
style: TextStyle( style: TextStyle(
fontSize: 14, fontSize: 14,
fontFamily: 'Inter', fontFamily: 'Inter',