feat(kyc): 首次验证手机号成功后显示选择页面

- 添加 verifySuccess 步骤替代弹窗
- 显示"恭喜您!手机号已验证成功"
- 提供两个选择按钮:
  - "仅验证手机号,不更换" - 返回上一页
  - "继续更换手机号" - 进入输入新手机号步骤
- 已验证过的用户直接进入更换流程

🤖 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-24 22:23:13 -08:00
parent 941253dd77
commit a51fa39a2d
1 changed files with 168 additions and 119 deletions

View File

@ -8,10 +8,11 @@ import 'kyc_entry_page.dart'; // 导入 kycServiceProvider
///
enum ChangePhoneStep {
verifyOld, //
inputNew, //
verifyNew, //
success, //
verifyOld, //
verifySuccess, //
inputNew, //
verifyNew, //
success, //
}
///
@ -149,15 +150,16 @@ class _ChangePhonePageState extends ConsumerState<ChangePhonePage> {
_countdown = 0;
});
//
if (!response.wasAlreadyVerified && mounted) {
await _showCongratulationsDialog();
}
//
//
if (mounted) {
setState(() {
_currentStep = ChangePhoneStep.inputNew;
if (!response.wasAlreadyVerified) {
//
_currentStep = ChangePhoneStep.verifySuccess;
} else {
//
_currentStep = ChangePhoneStep.inputNew;
}
});
}
} catch (e) {
@ -176,114 +178,6 @@ class _ChangePhonePageState extends ConsumerState<ChangePhonePage> {
}
}
///
Future<void> _showCongratulationsDialog() async {
return showDialog(
context: context,
barrierDismissible: false,
builder: (context) => AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16.r),
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(height: 16.h),
Container(
width: 64.w,
height: 64.w,
decoration: const BoxDecoration(
color: Color(0xFFE8F5E9),
shape: BoxShape.circle,
),
child: Icon(
Icons.check_circle,
color: const Color(0xFF2E7D32),
size: 40.sp,
),
),
SizedBox(height: 16.h),
Text(
'恭喜您!',
style: TextStyle(
fontSize: 20.sp,
fontWeight: FontWeight.w600,
color: const Color(0xFF333333),
),
),
SizedBox(height: 8.h),
Text(
'您的手机号已验证成功',
style: TextStyle(
fontSize: 14.sp,
color: const Color(0xFF666666),
),
textAlign: TextAlign.center,
),
SizedBox(height: 8.h),
Text(
'您可以继续更换新手机号,或点击返回完成验证',
style: TextStyle(
fontSize: 12.sp,
color: const Color(0xFF999999),
),
textAlign: TextAlign.center,
),
SizedBox(height: 24.h),
Row(
children: [
Expanded(
child: OutlinedButton(
onPressed: () {
Navigator.of(context).pop(); //
this.context.pop(); //
},
style: OutlinedButton.styleFrom(
padding: EdgeInsets.symmetric(vertical: 12.h),
side: const BorderSide(color: Color(0xFF2E7D32)),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.r),
),
),
child: Text(
'完成',
style: TextStyle(
fontSize: 14.sp,
color: const Color(0xFF2E7D32),
),
),
),
),
SizedBox(width: 12.w),
Expanded(
child: ElevatedButton(
onPressed: () {
Navigator.of(context).pop(); //
},
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF2E7D32),
padding: EdgeInsets.symmetric(vertical: 12.h),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.r),
),
),
child: Text(
'继续更换',
style: TextStyle(
fontSize: 14.sp,
color: Colors.white,
),
),
),
),
],
),
],
),
),
);
}
///
Future<void> _sendNewPhoneCode() async {
final newPhone = _newPhoneController.text.trim();
@ -415,6 +309,8 @@ class _ChangePhonePageState extends ConsumerState<ChangePhonePage> {
switch (_currentStep) {
case ChangePhoneStep.verifyOld:
return _buildVerifyOldStep();
case ChangePhoneStep.verifySuccess:
return _buildVerifySuccessStep();
case ChangePhoneStep.inputNew:
return _buildInputNewStep();
case ChangePhoneStep.verifyNew:
@ -477,6 +373,159 @@ class _ChangePhonePageState extends ConsumerState<ChangePhonePage> {
);
}
///
Widget _buildVerifySuccessStep() {
return SingleChildScrollView(
padding: EdgeInsets.symmetric(horizontal: 24.w),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(height: 60.h),
//
Container(
width: 80.w,
height: 80.w,
decoration: const BoxDecoration(
color: Color(0xFFE8F5E9),
shape: BoxShape.circle,
),
child: Icon(
Icons.check_circle,
color: const Color(0xFF2E7D32),
size: 50.sp,
),
),
SizedBox(height: 24.h),
Text(
'恭喜您!',
style: TextStyle(
fontSize: 28.sp,
fontWeight: FontWeight.w700,
color: const Color(0xFF333333),
),
),
SizedBox(height: 12.h),
Text(
'您的手机号已验证成功',
style: TextStyle(
fontSize: 16.sp,
color: const Color(0xFF666666),
),
),
if (_oldPhoneNumber != null) ...[
SizedBox(height: 8.h),
Text(
_oldPhoneNumber!,
style: TextStyle(
fontSize: 20.sp,
fontWeight: FontWeight.w600,
color: const Color(0xFF2E7D32),
),
),
],
SizedBox(height: 48.h),
Text(
'请选择下一步操作',
style: TextStyle(
fontSize: 14.sp,
color: const Color(0xFF999999),
),
),
SizedBox(height: 24.h),
//
SizedBox(
width: double.infinity,
child: OutlinedButton(
onPressed: () {
context.pop(); //
},
style: OutlinedButton.styleFrom(
padding: EdgeInsets.symmetric(vertical: 16.h),
side: const BorderSide(color: Color(0xFF2E7D32), width: 1.5),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.r),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.check, color: const Color(0xFF2E7D32), size: 20.sp),
SizedBox(width: 8.w),
Text(
'仅验证手机号,不更换',
style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.w600,
color: const Color(0xFF2E7D32),
),
),
],
),
),
),
SizedBox(height: 16.h),
//
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: () {
setState(() {
_currentStep = ChangePhoneStep.inputNew;
});
},
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF2E7D32),
padding: EdgeInsets.symmetric(vertical: 16.h),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.r),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.swap_horiz, color: Colors.white, size: 20.sp),
SizedBox(width: 8.w),
Text(
'继续更换手机号',
style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.w600,
color: Colors.white,
),
),
],
),
),
),
SizedBox(height: 32.h),
//
Container(
padding: EdgeInsets.all(16.w),
decoration: BoxDecoration(
color: const Color(0xFFF5F5F5),
borderRadius: BorderRadius.circular(8.r),
),
child: Row(
children: [
Icon(Icons.info_outline, color: const Color(0xFF999999), size: 18.sp),
SizedBox(width: 8.w),
Expanded(
child: Text(
'如需更换手机号,验证码将发送至新手机',
style: TextStyle(
fontSize: 12.sp,
color: const Color(0xFF666666),
),
),
),
],
),
),
],
),
);
}
/// 2:
Widget _buildInputNewStep() {
return SingleChildScrollView(