import 'dart:async'; import 'dart:convert'; import 'dart:ui'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:fluwx_no_pay/fluwx_no_pay.dart' as fluwx; import '../../api/user_api.dart'; import 'package:html/dom.dart' as dom; import '../../api/http.dart'; import '../../model/user/user_info.dart'; import '../../ui/common/browser.dart'; import '../../ui/widget/button.dart'; import '../../utils/event_bus_util.dart'; import '../../utils/pageutils.dart'; import '../../utils/push_util.dart'; import '../../utils/string_util.dart'; import '../../utils/ui_constant.dart'; import '../../utils/ui_utils.dart'; import '../../utils/user_util.dart'; import 'package:flutter_widget_from_html_core/flutter_widget_from_html_core.dart'; import '../widget/nav.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: '注册', theme: ThemeData(primaryColor: Color(0xFFF5F5F5)), home: EmailRegisterPage(title: ''), ); } } class EmailRegisterPage extends StatefulWidget { //阿里云一键登录 static const messageChannel = BasicMessageChannel('AliyunPhoneNumberAuth', StandardMessageCodec()); EmailRegisterPage({Key? key, required this.title}) : super(key: key); // This widget is the home page of your application. It is stateful, meaning // that it has a State object (defined below) that contains fields that affect // how it looks. // This class is the configuration for the state. It holds the values (in this // case the title) provided by the parent (in this case the App widget) and // used by the build method of the State. Fields in a Widget subclass are // always marked "final". final String title; @override _EmailRegisterPageState createState() => _EmailRegisterPageState(); } class _EmailRegisterPageState extends State with SingleTickerProviderStateMixin { bool checked = false; TextEditingController? emailController = TextEditingController(); TextEditingController? codeController = TextEditingController(); TextEditingController? pwdController = TextEditingController(); String email = ""; String code = ""; Timer? timer; //重新发送验证码倒计时 int? reSendSMSTimeLeft; @override void initState() { super.initState(); reSendSMSTimeLeft = -1; //初始化微信登录监听 fluwx.weChatResponseEventHandler.distinct((a, b) => a == b).listen((res) { if (res is fluwx.WeChatAuthResponse) { int errCode = res.errCode; if (errCode == 0) { String? code = res.code; //TODO 把微信登录返回的code传给后台,剩下的事就交给后台处理 } else if (errCode == -4) { //showToast("用户拒绝授权"); } else if (errCode == -2) { // showToast("用户取消授权"); } } }); } void _loginSuccess(UserInfo user) { UserUtil.setUserInfo(user).then((value) { print("登录成功"); eventBus.fire(LoginEventBus(true)); PushUtil.setAlias(user.id!.toString()).then((value) { popPage(context); }); }); } @override void dispose() { if (timer != null) { timer!.cancel(); } super.dispose(); } BoxDecoration getItemDecoration(Color bgColor, Color shadowColor) { return BoxDecoration( borderRadius: const BorderRadius.all(Radius.elliptical(10, 10)), color: bgColor, boxShadow: [ BoxShadow( color: shadowColor, blurRadius: 2.0, offset: const Offset(0.0, 5.0), //阴影y轴偏移量 spreadRadius: 1 //阴影扩散程度 ) ]); } @override Widget build(BuildContext context) { return Scaffold( resizeToAvoidBottomInset: false, backgroundColor: Colors.white, body: Stack( children: [ Column(children: [ //登录内容区域 Expanded( child: SingleChildScrollView( child: Padding( padding: const EdgeInsets.fromLTRB(40, 120, 40, 14), child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ Image.asset( "assets/imgs/login/ic_login_logo.png", width: 131, ), Container( height: 70, ), Container( constraints: const BoxConstraints(minHeight: 200), child: getLoginContent()), Container( height: 30, ) ])))), //用户协议与隐私政策 Row(children: [ Container( width: 25, ), RoundCheckBox( value: checked, onChanged: (value) { setState(() { checked = value; }); }, ), Expanded( child: HtmlWidget( "

登录即表明同意 用户协议 和 隐私政策 

", textStyle: const TextStyle(color: Color(0xFF999999)), onTapUrl: (url) { String? title = ""; if (url == Constant.PROTOCOL_URL) { title = "用户协议"; } else { title = "隐私政策"; } NavigatorUtil.navigateToNextPage( context, BrowserPage( title: title, url: url, ), (data) {}); return true; })), ]) ]), //关闭按钮 Positioned( top: 30, left: 20, child: InkWell( onTap: () { popPage(context); }, child: const Icon( Icons.arrow_back_ios_new, size: 25, ))) ], )); } Widget getLoginContent() { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( alignment: Alignment.centerLeft, padding: EdgeInsets.fromLTRB(20, 0, 5, 0), decoration: BoxDecoration( color: const Color(0xFFF5F5F5), borderRadius: BorderRadius.circular(10)), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Image.asset( "assets/imgs/login/icon_email.png", width: 17, height: 15, ), Container(width: 14), Expanded( child: TextField( style: TextStyle(color: Color(0xFF333333), fontSize: 17), onChanged: (value) { setState(() { email = value; }); }, textAlign: TextAlign.start, keyboardType: TextInputType.emailAddress, controller: emailController, maxLength: 60, decoration: const InputDecoration( counterText: "", hintText: "请输入邮箱", hintStyle: TextStyle(color: Color(0xFFCCCCCC), fontSize: 17), contentPadding: EdgeInsets.only(bottom: 3), border: InputBorder.none, focusedBorder: InputBorder.none, ), )), ], ), ), Container(height: 10), Container( alignment: Alignment.centerLeft, padding: EdgeInsets.fromLTRB(20, 0, 7, 0), decoration: BoxDecoration( color: const Color(0xFFF5F5F5), borderRadius: BorderRadius.circular(10)), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Image.asset( "assets/imgs/login/icon_code.png", width: 16.5, ), Container(width: 14), Expanded( child: TextField( style: TextStyle(color: Color(0xFF333333), fontSize: 17), onChanged: (value) { setState(() { email = value; }); }, textAlign: TextAlign.start, keyboardType: TextInputType.phone, controller: codeController, maxLength: 8, decoration: const InputDecoration( counterText: "", hintText: "请输入验证码", hintStyle: TextStyle(color: Color(0xFFCCCCCC), fontSize: 17), contentPadding: EdgeInsets.only(bottom: 3), border: InputBorder.none, focusedBorder: InputBorder.none, ), )), MyFillButton( (reSendSMSTimeLeft! > 0 ? (reSendSMSTimeLeft.toString() + "S重新获取") : reSendSMSTimeLeft == -1 ? "获取验证码" : "重新获取") .toString(), 10, height: 34, padding: const EdgeInsets.fromLTRB(10, 0, 10, 0), enable: (reSendSMSTimeLeft! < 1 && StringUtil.isEmail(emailController!.value.text)), onClick: () { if (!(reSendSMSTimeLeft! < 1 && StringUtil.isEmail(emailController!.value.text))) { return; } //发送验证码 UserApiUtil.sendEmailCode(context, emailController!.value.text) .then((value) { if (value != null && value["IsPost"] == "true") { setState(() { reSendSMSTimeLeft = 60; //倒计时 timer = Timer.periodic(const Duration(seconds: 1), (timer) { if (reSendSMSTimeLeft! > 0) { setState(() { reSendSMSTimeLeft = reSendSMSTimeLeft! - 1; }); } else { timer.cancel(); } }); }); } else { ToastUtil.toast(value!["Error"], context); } }); }, ), ], ), ), Container(height: 10), Container( alignment: Alignment.centerLeft, padding: const EdgeInsets.fromLTRB(20, 0, 7, 0), decoration: BoxDecoration( color: const Color(0xFFF5F5F5), borderRadius: BorderRadius.circular(10)), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Image.asset( "assets/imgs/login/icon_pwd.png", width: 16.5, ), Container(width: 14), Expanded( child: TextField( style: const TextStyle(color: Color(0xFF333333), fontSize: 17), onChanged: (value) { setState(() { email = value; }); }, obscureText: true, textAlign: TextAlign.start, keyboardType: TextInputType.visiblePassword, controller: pwdController, maxLength: 32, decoration: const InputDecoration( counterText: "", hintText: "请输入密码", hintStyle: TextStyle(color: Color(0xFFCCCCCC), fontSize: 17), contentPadding: EdgeInsets.only(bottom: 3), border: InputBorder.none, focusedBorder: InputBorder.none, ), )), ], ), ), Container(height: 52), MyFillButton( "注 册", 10, height: 45, color: ColorConstant.theme, fontSize: 17, enable: StringUtil.isEmail(emailController!.value.text) && codeController!.value.text.length >= 4 && pwdController!.value.text.length >= 6, onClick: () { if (!(StringUtil.isEmail(emailController!.value.text) && codeController!.value.text.length >= 4 && pwdController!.value.text.length >= 6)) { return; } if (!checked) { ToastUtil.toast("请同意用户协议与隐私政策", context); return; } UserApiUtil.registerByEmail(context, emailController!.value.text, pwdController!.value.text, codeController!.value.text) .then((value) { print("结果: $value"); if (value!["IsPost"] == "true") { ToastUtil.toast("注册成功", context); //去登录 UserApiUtil.loginByEmail( context, email, pwdController!.value.text) .then((value) { if (value!["IsPost"] == "true") { UserInfo user = UserInfo.fromJson(value["Data"]); _loginSuccess(user); } }); } else { ToastUtil.toast(value["Error"], context); } }); }, ), ], ); } }