import 'dart:async'; import 'dart:io'; import 'package:eitc_erm_app/utils/Component.dart'; import 'package:eitc_erm_app/utils/Constants.dart'; import 'package:eitc_erm_app/utils/Utils.dart'; import 'package:eitc_erm_app/utils/logger.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:http/http.dart' as http; import 'package:http/http.dart'; import 'agreement.dart'; import 'bean/normal_response.dart'; void main() { WidgetsFlutterBinding.ensureInitialized(); runApp(Register()); } class Register extends StatefulWidget { @override State createState() => RegisterState(); } class RegisterState extends State { @override Widget build(BuildContext context) { return Scaffold( appBar: new AppBar( title: const Text('注册', style: TextStyle( color: Colors.white, )), centerTitle: true, elevation: 0.5, backgroundColor: Global.StatusBarColor, leading: new IconButton( tooltip: '返回上一页', icon: const Icon( Icons.arrow_back_ios, color: Colors.white, ), onPressed: () { Navigator.of(context).pop(); //_nextPage(-1); }, ), ), body: Center( child: MyBody(), ), ); } } class MyBody extends StatefulWidget { @override _MyBodyState createState() => _MyBodyState(); } class _MyBodyState extends State { bool isButtonEnable = true; //按钮状态 是否可点击 String buttonText = '发送验证码'; //初始文本 int count = 60; //初始倒计时时间 Timer? timer; //倒计时的计时器 TextEditingController mController = TextEditingController(); TextEditingController phoneController = TextEditingController(); TextEditingController identificationCardController = TextEditingController(); TextEditingController passwordController = TextEditingController(); bool isPasswordLogin = false; String passText = "验证码"; String loginText = "密码登录"; String hintText = "请输入验证码"; bool _isChecked = false; void _buttonClickListen() { setState(() { if (!Utils.isChinaPhoneLegal(phoneController.text)) { Component.toast("请输入正确手机号码!", 0); return null; } sendCaptchaCode(); if (isButtonEnable) { isButtonEnable = false; //按钮状态标记 _initTimer(); return null; //返回null按钮禁止点击 } else { return null; //返回null按钮禁止点击 } }); } void _initTimer() { timer = Timer.periodic(const Duration(seconds: 1), (Timer timer) { count--; setState(() { if (count == 0) { timer.cancel(); //倒计时结束取消定时器 isButtonEnable = true; //按钮可点击 count = 60; //重置时间 buttonText = '发送验证码'; //重置按钮文本 } else { buttonText = '重新发送($count)'; //更新文本内容 } }); }); } Future sendCaptchaCode() async { var params = { 'phoneNumber': phoneController.text, }; var response = await http.post( Uri.parse('${Global.BaseUrl}sendCaptchaCode'), body: encodeBody(params), headers: jsonHeaders()); if (response.statusCode == 200) { final json = decodeBodyToJson(response.bodyBytes); logd(json); NormalResponse mNormalResponse = NormalResponse.fromJson(json); if (mNormalResponse.code == Global.responseSuccessCode) { Component.toast("短信发送成功,请查收!", 2); } else { Component.toast(mNormalResponse.msg.toString(), 0); } return response.toString(); } else { Component.toast("出错了,请稍后再试!", 0); return null; } } @override void dispose() { timer?.cancel(); super.dispose(); } @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.only(top: 10.0, left: 10.0, right: 10.0), child: Column( children: [ Container( color: Colors.white, padding: const EdgeInsets.only(left: 10, right: 10), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.baseline, textBaseline: TextBaseline.alphabetic, children: [ const Text( '身份证', style: TextStyle(fontSize: 13, color: Color(0xff333333)), ), Expanded( child: Padding( padding: const EdgeInsets.only(left: 5, right: 15, top: 5), child: TextFormField( maxLines: 1, onSaved: (value) {}, controller: identificationCardController, textAlign: TextAlign.left, inputFormatters: [ FilteringTextInputFormatter.digitsOnly, LengthLimitingTextInputFormatter(18) ], decoration: const InputDecoration( hintText: ('请填写身份证号码'), hintStyle: TextStyle( color: Color(0xff999999), fontSize: 13, ), alignLabelWithHint: true, border: OutlineInputBorder(borderSide: BorderSide.none), ), ), ), ), ], ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.baseline, textBaseline: TextBaseline.alphabetic, children: [ const Text( '密码', style: TextStyle(fontSize: 13, color: Color(0xff333333)), ), Expanded( child: Padding( padding: const EdgeInsets.only(left: 20, right: 15, top: 5), child: TextFormField( maxLines: 1, onSaved: (value) {}, controller: passwordController, textAlign: TextAlign.left, inputFormatters: [ FilteringTextInputFormatter.digitsOnly, LengthLimitingTextInputFormatter(20) ], decoration: const InputDecoration( hintText: ('请填写密码'), hintStyle: TextStyle( color: Color(0xff999999), fontSize: 13, ), alignLabelWithHint: true, border: OutlineInputBorder(borderSide: BorderSide.none), ), ), ), ), ], ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.baseline, textBaseline: TextBaseline.alphabetic, children: [ const Text( '+86', style: TextStyle(fontSize: 13, color: Color(0xff333333)), ), Expanded( child: Padding( padding: const EdgeInsets.only(left: 20, right: 15, top: 5), child: TextFormField( maxLines: 1, onSaved: (value) {}, controller: phoneController, textAlign: TextAlign.left, inputFormatters: [ FilteringTextInputFormatter.digitsOnly, LengthLimitingTextInputFormatter(11) ], decoration: const InputDecoration( hintText: ('请填写手机号'), hintStyle: TextStyle( color: Color(0xff999999), fontSize: 13, ), alignLabelWithHint: true, border: OutlineInputBorder(borderSide: BorderSide.none), ), ), ), ), ], ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.baseline, textBaseline: TextBaseline.alphabetic, children: [ Text( passText, style: const TextStyle( fontSize: 13, color: Color(0xff333333)), ), Expanded( child: Padding( padding: const EdgeInsets.only(left: 15, right: 15, top: 0), child: TextFormField( maxLines: 1, onSaved: (value) {}, controller: mController, textAlign: TextAlign.left, inputFormatters: [ FilteringTextInputFormatter.digitsOnly, LengthLimitingTextInputFormatter(6) ], decoration: const InputDecoration( hintText: ('请输入验证码'), contentPadding: EdgeInsets.only(top: -5, bottom: 0), hintStyle: TextStyle( color: Color(0xff999999), fontSize: 13, ), alignLabelWithHint: true, border: OutlineInputBorder(borderSide: BorderSide.none), ), ), ), ), Container( padding: const EdgeInsets.all(0), width: 120, child: Visibility( visible: !isPasswordLogin, child: ElevatedButton( style: ButtonStyle( backgroundColor: WidgetStateProperty.resolveWith( (states) { if (states.contains(WidgetState.disabled)) { return Colors.brown; } return Colors.blue; }), foregroundColor: const WidgetStatePropertyAll(Colors.white), ), onPressed: () { setState(() { _buttonClickListen(); }); }, child: Text( buttonText, style: const TextStyle( fontSize: 12, ), ), ), ), ), ], ), Padding( padding: const EdgeInsets.only(top: 20, bottom: 0), child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ SizedBox( width: 20.0, height: 20.0, child: Checkbox( value: _isChecked, onChanged: (bool? newValue) { setState(() { _isChecked = newValue ?? false; }); }, activeColor: Colors.green, // 选中时的颜色 checkColor: Colors.white, // 选中标记的颜色 ), ), const Text( " 同意", style: TextStyle( fontSize: 13, color: Color(0xff333333)), ), GestureDetector( onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => Agreement()), ); }, child: const Text( "口腔医院相关服务协议及隐私政策", style: TextStyle( fontSize: 14, color: Colors.blueAccent), ), ), ])) ], ), ), Container( width: double.infinity, height: 45, margin: const EdgeInsets.only(top: 20, left: 10, right: 10), child: ElevatedButton( style: ButtonStyle( backgroundColor: WidgetStateProperty.resolveWith((states) { return Colors.blue; // Regular color }), ), onPressed: () { logd('手机号:${phoneController.text},验证码:${mController.text}'); register(); }, child: Text( '注册', style: TextStyle(color: Colors.white, fontSize: 15), ), ), ), ], ), ); } void _showDialog() { showDialog( context: context, builder: (context) { return AlertDialog( title: const Text('提示'), content: const Text('请您阅读《口腔医院相关服务协议及隐私政策》并勾选同意'), actions: [ TextButton( onPressed: () { Navigator.of(context).pop(); }, child: const Text("确定", style: TextStyle(color: Colors.white, fontSize: 13)), ), ], ); }, ); } Future register() async { if (phoneController.text.length < 11) { Component.toast("请正确填写电话号码!", 0); return null; } else if (mController.text.length < 6) { Component.toast("请正确填写验证码!", 0); return null; } else if (!Utils.validateIDCard(identificationCardController.text)) { Component.toast("请正确填写身份证号码!", 0); return null; } else if (passwordController.text.length < 6) { Component.toast("请正确填写密码!", 0); return null; } else if (!Utils.isChinaPhoneLegal(phoneController.text)) { Component.toast("请输入正确手机号码!", 0); return null; } else if (!Utils.isVerifyCode(mController.text)) { Component.toast("请输入正确验证码!", 0); return null; } if (!_isChecked) { _showDialog(); return null; } bool bo = await _checkCaptchaCode(); if (!bo) { Component.toast("验证码错误!", 0); return null; } var params = { 'phoneNumber': phoneController.text, 'captchaCode': mController.text, 'identificationCard': identificationCardController.text, 'password': passwordController.text, }; var response = await http.post(Uri.parse('${Global.BaseUrl}register'), body: encodeBody(params), headers: jsonHeaders()); if (response.statusCode == 200) { final json = decodeBodyToJson(response.bodyBytes); logd(json); NormalResponse mNormalResponse = new NormalResponse.fromJson(json); if (mNormalResponse.code == Global.responseSuccessCode) { Component.toast("注册成功!", 2); Navigator.pushReplacementNamed(context, "/login"); } else { Component.toast(mNormalResponse.msg.toString(), 0); } return response.toString(); } else { Component.toast("出错了,请稍后再试!", 0); return null; } } ///检查验证码 Future _checkCaptchaCode() async { Map params = { "phoneNumber": phoneController.text, "captchaCode": mController.text }; Uri uri = Uri.parse("${Global.BaseUrl}api/checkCaptchaCode"); logd("检查验证码,uri=$uri"); Response response = await http.post(uri, body: encodeBody(params), headers: jsonHeaders()); if (response.statusCode == 200) { final json = decodeBodyToJson(response.bodyBytes); logd("检查验证码结果$json"); NormalResponse mNormalResponse = NormalResponse.fromJson(json); return mNormalResponse.code == 200; } else { logd("检查验证码异常${response.body}"); } return false; } }