|
|
|
@ -24,220 +24,217 @@ class LoginPage extends StatelessWidget { |
|
|
|
width: 1.sw, |
|
|
|
height: 1.sh, |
|
|
|
), |
|
|
|
SingleChildScrollView( |
|
|
|
padding: const EdgeInsets.all(20), |
|
|
|
child: SizedBox( |
|
|
|
height: MediaQuery.of(context).size.height, |
|
|
|
child: Column( |
|
|
|
children: [ |
|
|
|
const SizedBox(height: 130), |
|
|
|
SizedBox( |
|
|
|
height: MediaQuery.of(context).size.height, |
|
|
|
child: Column( |
|
|
|
children: [ |
|
|
|
const SizedBox(height: 130), |
|
|
|
|
|
|
|
// Logo和标题区域 |
|
|
|
Center( |
|
|
|
child: Column( |
|
|
|
children: [ |
|
|
|
Image.asset( |
|
|
|
Assets.imagesLoginLogo, |
|
|
|
height: 60, |
|
|
|
), |
|
|
|
const SizedBox(height: 10), |
|
|
|
const Text( |
|
|
|
'心动就动我 幸福马上行动', |
|
|
|
style: TextStyle( |
|
|
|
fontSize: 14, |
|
|
|
color: Color.fromRGBO(153, 153, 153, 1), |
|
|
|
), |
|
|
|
// Logo和标题区域 |
|
|
|
Center( |
|
|
|
child: Column( |
|
|
|
children: [ |
|
|
|
Image.asset( |
|
|
|
Assets.imagesLoginLogo, |
|
|
|
height: 60, |
|
|
|
), |
|
|
|
const SizedBox(height: 10), |
|
|
|
const Text( |
|
|
|
'心动就动我 幸福马上行动', |
|
|
|
style: TextStyle( |
|
|
|
fontSize: 14, |
|
|
|
color: Color.fromRGBO(153, 153, 153, 1), |
|
|
|
), |
|
|
|
], |
|
|
|
), |
|
|
|
), |
|
|
|
], |
|
|
|
), |
|
|
|
), |
|
|
|
|
|
|
|
const SizedBox(height: 60), |
|
|
|
const SizedBox(height: 60), |
|
|
|
|
|
|
|
// 错误提示已改为SmartDialog.showToast,此处不再需要UI显示 |
|
|
|
const SizedBox(height: 5), |
|
|
|
// 错误提示已改为SmartDialog.showToast,此处不再需要UI显示 |
|
|
|
const SizedBox(height: 5), |
|
|
|
|
|
|
|
// 手机号输入框 - 带+86区号 |
|
|
|
Container( |
|
|
|
decoration: BoxDecoration( |
|
|
|
border: Border.all(color: Colors.grey.shade300), |
|
|
|
borderRadius: BorderRadius.circular(8), |
|
|
|
), |
|
|
|
child: Row( |
|
|
|
children: [ |
|
|
|
// 手机号输入部分 |
|
|
|
Expanded( |
|
|
|
child: TextField( |
|
|
|
decoration: const InputDecoration( |
|
|
|
hintText: '请输入你的手机号', |
|
|
|
border: InputBorder.none, |
|
|
|
contentPadding: EdgeInsets.symmetric(horizontal: 15, vertical: 14), |
|
|
|
counterText: '', |
|
|
|
), |
|
|
|
keyboardType: TextInputType.phone, |
|
|
|
maxLength: 11, |
|
|
|
onChanged: (value) { |
|
|
|
controller.phoneNumber.value = value; |
|
|
|
}, |
|
|
|
style: const TextStyle(fontSize: 16), |
|
|
|
// 手机号输入框 - 带+86区号 |
|
|
|
Container( |
|
|
|
decoration: BoxDecoration( |
|
|
|
border: Border.all(color: Colors.grey.shade300), |
|
|
|
borderRadius: BorderRadius.circular(8), |
|
|
|
), |
|
|
|
child: Row( |
|
|
|
children: [ |
|
|
|
// 手机号输入部分 |
|
|
|
Expanded( |
|
|
|
child: TextField( |
|
|
|
decoration: const InputDecoration( |
|
|
|
hintText: '请输入你的手机号', |
|
|
|
border: InputBorder.none, |
|
|
|
contentPadding: EdgeInsets.symmetric(horizontal: 15, vertical: 14), |
|
|
|
counterText: '', |
|
|
|
), |
|
|
|
keyboardType: TextInputType.phone, |
|
|
|
maxLength: 11, |
|
|
|
onChanged: (value) { |
|
|
|
controller.phoneNumber.value = value; |
|
|
|
}, |
|
|
|
style: const TextStyle(fontSize: 16), |
|
|
|
), |
|
|
|
], |
|
|
|
), |
|
|
|
), |
|
|
|
], |
|
|
|
), |
|
|
|
), |
|
|
|
|
|
|
|
const SizedBox(height: 20), |
|
|
|
const SizedBox(height: 20), |
|
|
|
|
|
|
|
// 验证码输入框和获取验证码按钮 |
|
|
|
Container( |
|
|
|
decoration: BoxDecoration( |
|
|
|
border: Border.all(color: Colors.grey.shade300), |
|
|
|
borderRadius: BorderRadius.circular(8), |
|
|
|
), |
|
|
|
child: Row( |
|
|
|
children: [ |
|
|
|
// 验证码输入部分 |
|
|
|
Expanded( |
|
|
|
child: TextField( |
|
|
|
decoration: const InputDecoration( |
|
|
|
hintText: '请输入验证码', |
|
|
|
border: InputBorder.none, |
|
|
|
contentPadding: EdgeInsets.symmetric(horizontal: 15, vertical: 14), |
|
|
|
counterText: '', |
|
|
|
), |
|
|
|
keyboardType: TextInputType.number, |
|
|
|
maxLength: 6, |
|
|
|
onChanged: (value) { |
|
|
|
controller.verificationCode.value = value; |
|
|
|
}, |
|
|
|
style: const TextStyle(fontSize: 16), |
|
|
|
// 验证码输入框和获取验证码按钮 |
|
|
|
Container( |
|
|
|
decoration: BoxDecoration( |
|
|
|
border: Border.all(color: Colors.grey.shade300), |
|
|
|
borderRadius: BorderRadius.circular(8), |
|
|
|
), |
|
|
|
child: Row( |
|
|
|
children: [ |
|
|
|
// 验证码输入部分 |
|
|
|
Expanded( |
|
|
|
child: TextField( |
|
|
|
decoration: const InputDecoration( |
|
|
|
hintText: '请输入验证码', |
|
|
|
border: InputBorder.none, |
|
|
|
contentPadding: EdgeInsets.symmetric(horizontal: 15, vertical: 14), |
|
|
|
counterText: '', |
|
|
|
), |
|
|
|
keyboardType: TextInputType.number, |
|
|
|
maxLength: 6, |
|
|
|
onChanged: (value) { |
|
|
|
controller.verificationCode.value = value; |
|
|
|
}, |
|
|
|
style: const TextStyle(fontSize: 16), |
|
|
|
), |
|
|
|
// 获取验证码按钮 |
|
|
|
GestureDetector( |
|
|
|
onTap: controller.isSendingCode.value || controller.countdownSeconds.value > 0 |
|
|
|
? null |
|
|
|
: controller.getVerificationCode, |
|
|
|
child: Container( |
|
|
|
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 14), |
|
|
|
child: Text( |
|
|
|
controller.countdownSeconds.value > 0 |
|
|
|
? '${controller.countdownSeconds.value}秒后重试' |
|
|
|
: '获取验证码', |
|
|
|
style: TextStyle( |
|
|
|
fontSize: 14, |
|
|
|
color: (controller.isSendingCode.value || controller.countdownSeconds.value > 0) |
|
|
|
? Colors.grey.shade400 |
|
|
|
: const Color.fromRGBO(74, 99, 235, 1), |
|
|
|
), |
|
|
|
), |
|
|
|
// 获取验证码按钮 |
|
|
|
GestureDetector( |
|
|
|
onTap: controller.isSendingCode.value || controller.countdownSeconds.value > 0 |
|
|
|
? null |
|
|
|
: controller.getVerificationCode, |
|
|
|
child: Container( |
|
|
|
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 14), |
|
|
|
child: Text( |
|
|
|
controller.countdownSeconds.value > 0 |
|
|
|
? '${controller.countdownSeconds.value}秒后重试' |
|
|
|
: '获取验证码', |
|
|
|
style: TextStyle( |
|
|
|
fontSize: 14, |
|
|
|
color: (controller.isSendingCode.value || controller.countdownSeconds.value > 0) |
|
|
|
? Colors.grey.shade400 |
|
|
|
: const Color.fromRGBO(74, 99, 235, 1), |
|
|
|
), |
|
|
|
), |
|
|
|
), |
|
|
|
], |
|
|
|
), |
|
|
|
), |
|
|
|
], |
|
|
|
), |
|
|
|
), |
|
|
|
|
|
|
|
const SizedBox(height: 24), |
|
|
|
const SizedBox(height: 24), |
|
|
|
|
|
|
|
// 协议同意复选框 |
|
|
|
Row( |
|
|
|
children: [ |
|
|
|
Obx(() => Checkbox( |
|
|
|
value: agreeTerms.value, |
|
|
|
onChanged: (value) { |
|
|
|
agreeTerms.value = value ?? false; |
|
|
|
}, |
|
|
|
activeColor: Colors.grey, |
|
|
|
side: const BorderSide(color: Colors.grey), |
|
|
|
shape: const CircleBorder(), |
|
|
|
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, |
|
|
|
)), |
|
|
|
const Text( |
|
|
|
'我已阅读并同意', |
|
|
|
// 协议同意复选框 |
|
|
|
Row( |
|
|
|
children: [ |
|
|
|
Obx(() => Checkbox( |
|
|
|
value: agreeTerms.value, |
|
|
|
onChanged: (value) { |
|
|
|
agreeTerms.value = value ?? false; |
|
|
|
}, |
|
|
|
activeColor: Colors.grey, |
|
|
|
side: const BorderSide(color: Colors.grey), |
|
|
|
shape: const CircleBorder(), |
|
|
|
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, |
|
|
|
)), |
|
|
|
const Text( |
|
|
|
'我已阅读并同意', |
|
|
|
style: TextStyle( |
|
|
|
fontSize: 11, |
|
|
|
color: Color.fromRGBO(153, 153, 153, 1), |
|
|
|
), |
|
|
|
), |
|
|
|
GestureDetector( |
|
|
|
onTap: () { |
|
|
|
// 跳转到用户协议页面 |
|
|
|
}, |
|
|
|
child: const Text( |
|
|
|
'《动我用户协议》', |
|
|
|
style: TextStyle( |
|
|
|
fontSize: 11, |
|
|
|
color: Color.fromRGBO(153, 153, 153, 1), |
|
|
|
color: Color.fromRGBO(74, 99, 235, 1), |
|
|
|
), |
|
|
|
), |
|
|
|
GestureDetector( |
|
|
|
onTap: () { |
|
|
|
// 跳转到用户协议页面 |
|
|
|
}, |
|
|
|
child: const Text( |
|
|
|
'《动我用户协议》', |
|
|
|
style: TextStyle( |
|
|
|
fontSize: 11, |
|
|
|
color: Color.fromRGBO(74, 99, 235, 1), |
|
|
|
), |
|
|
|
), |
|
|
|
), |
|
|
|
const Text( |
|
|
|
'和', |
|
|
|
style: TextStyle( |
|
|
|
fontSize: 11, |
|
|
|
color: Color.fromRGBO(153, 153, 153, 1), |
|
|
|
), |
|
|
|
const Text( |
|
|
|
'和', |
|
|
|
), |
|
|
|
GestureDetector( |
|
|
|
onTap: () { |
|
|
|
// 跳转到隐私政策页面 |
|
|
|
}, |
|
|
|
child: const Text( |
|
|
|
'《隐私政策》', |
|
|
|
style: TextStyle( |
|
|
|
fontSize: 11, |
|
|
|
color: Color.fromRGBO(153, 153, 153, 1), |
|
|
|
color: Color.fromRGBO(74, 99, 235, 1), |
|
|
|
), |
|
|
|
), |
|
|
|
GestureDetector( |
|
|
|
onTap: () { |
|
|
|
// 跳转到隐私政策页面 |
|
|
|
}, |
|
|
|
child: const Text( |
|
|
|
'《隐私政策》', |
|
|
|
style: TextStyle( |
|
|
|
fontSize: 11, |
|
|
|
color: Color.fromRGBO(74, 99, 235, 1), |
|
|
|
), |
|
|
|
), |
|
|
|
), |
|
|
|
], |
|
|
|
), |
|
|
|
SizedBox(height: 50), |
|
|
|
// 注册并登录按钮 |
|
|
|
Container( |
|
|
|
margin: const EdgeInsets.only(bottom: 50), |
|
|
|
child: ElevatedButton( |
|
|
|
onPressed: controller.isLoggingIn.value |
|
|
|
? null |
|
|
|
: () { |
|
|
|
// 登录逻辑 |
|
|
|
if (!agreeTerms.value) { |
|
|
|
SmartDialog.showToast('请阅读并同意用户协议和隐私政策'); |
|
|
|
return; |
|
|
|
} |
|
|
|
), |
|
|
|
], |
|
|
|
), |
|
|
|
SizedBox(height: 50), |
|
|
|
// 注册并登录按钮 |
|
|
|
Container( |
|
|
|
margin: const EdgeInsets.only(bottom: 50), |
|
|
|
child: ElevatedButton( |
|
|
|
onPressed: controller.isLoggingIn.value |
|
|
|
? null |
|
|
|
: () { |
|
|
|
// 登录逻辑 |
|
|
|
if (!agreeTerms.value) { |
|
|
|
SmartDialog.showToast('请阅读并同意用户协议和隐私政策'); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// 调用控制器的登录方法 |
|
|
|
controller.login(); |
|
|
|
}, |
|
|
|
style: ElevatedButton.styleFrom( |
|
|
|
minimumSize: const Size(double.infinity, 50), |
|
|
|
backgroundColor: agreeTerms.value ? const Color.fromRGBO(74, 99, 235, 1) : Colors.grey.shade300, |
|
|
|
shape: RoundedRectangleBorder( |
|
|
|
borderRadius: BorderRadius.circular(25), |
|
|
|
), |
|
|
|
elevation: 0, |
|
|
|
// 调用控制器的登录方法 |
|
|
|
controller.login(); |
|
|
|
}, |
|
|
|
style: ElevatedButton.styleFrom( |
|
|
|
minimumSize: const Size(double.infinity, 50), |
|
|
|
backgroundColor: agreeTerms.value ? const Color.fromRGBO(74, 99, 235, 1) : Colors.grey.shade300, |
|
|
|
shape: RoundedRectangleBorder( |
|
|
|
borderRadius: BorderRadius.circular(25), |
|
|
|
), |
|
|
|
child: controller.isLoggingIn.value |
|
|
|
? const SizedBox( |
|
|
|
width: 20, |
|
|
|
height: 20, |
|
|
|
child: CircularProgressIndicator( |
|
|
|
color: Colors.white, |
|
|
|
strokeWidth: 2, |
|
|
|
), |
|
|
|
) |
|
|
|
: const Text( |
|
|
|
'注册并登录', |
|
|
|
style: TextStyle( |
|
|
|
fontSize: 18, |
|
|
|
fontWeight: FontWeight.bold, |
|
|
|
color: Colors.white, |
|
|
|
), |
|
|
|
elevation: 0, |
|
|
|
), |
|
|
|
child: controller.isLoggingIn.value |
|
|
|
? const SizedBox( |
|
|
|
width: 20, |
|
|
|
height: 20, |
|
|
|
child: CircularProgressIndicator( |
|
|
|
color: Colors.white, |
|
|
|
strokeWidth: 2, |
|
|
|
), |
|
|
|
) |
|
|
|
: const Text( |
|
|
|
'注册并登录', |
|
|
|
style: TextStyle( |
|
|
|
fontSize: 18, |
|
|
|
fontWeight: FontWeight.bold, |
|
|
|
color: Colors.white, |
|
|
|
), |
|
|
|
), |
|
|
|
), |
|
|
|
], |
|
|
|
), |
|
|
|
), |
|
|
|
], |
|
|
|
), |
|
|
|
) |
|
|
|
], |
|
|
|
|