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 'package:makemoney/ui/mine/add_team.dart';
|
import 'package:makemoney/utils/config_util.dart';
|
import 'package:makemoney/utils/wx_util.dart';
|
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';
|
import 'add_team.dart';
|
|
class LoginPage extends StatefulWidget {
|
//阿里云一键登录
|
static const messageChannel =
|
BasicMessageChannel('AliyunPhoneNumberAuth', StandardMessageCodec());
|
|
LoginPage({Key? key, required this.title, this.bindPhone = false})
|
: 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;
|
|
final bool bindPhone;
|
|
@override
|
_LoginPageState createState() => _LoginPageState();
|
}
|
|
class _LoginPageState extends State<LoginPage>
|
with SingleTickerProviderStateMixin {
|
bool wxLogin = true;
|
bool checked = false;
|
TextEditingController? phoneController = TextEditingController();
|
TextEditingController? codeController = TextEditingController();
|
String phone = "";
|
Timer? timer;
|
|
//重新发送验证码倒计时
|
int? reSendSMSTimeLeft;
|
|
@override
|
void initState() {
|
super.initState();
|
|
WXAuthUtil.init(context, (s) {
|
_loginWX(s);
|
});
|
|
if (widget.bindPhone) {
|
wxLogin = false;
|
}
|
reSendSMSTimeLeft = -1;
|
}
|
|
void _loginWX(code) {
|
UserApiUtil.loginByWX(context, code).then((value) {
|
if (value!["code"] == 0) {
|
UserInfo user = UserInfo.fromJson(value["data"]);
|
_loginSuccess(user);
|
} else {
|
ToastUtil.toast(value["msg"], context);
|
}
|
});
|
}
|
|
bool _aliyunLogin = false;
|
|
void aliyunOneKeyLogin() async {
|
if (_aliyunLogin) {
|
return;
|
}
|
_aliyunLogin = true;
|
Future.delayed(const Duration(milliseconds: 1000), () {
|
_aliyunLogin = false;
|
});
|
|
showLoading(context);
|
|
Map value =
|
await LoginPage.messageChannel.send({"method": "checkEnv"}) as Map;
|
dismissDialog(context);
|
if (value["code"] == 0) {
|
value =
|
await LoginPage.messageChannel.send({"method": "startLogin"}) as Map;
|
print("返回内容:${jsonEncode(value)}");
|
if (value["code"] == 0) {
|
Map<String, dynamic>? resultValue =
|
await UserApiUtil.loginByPhone(context, "", "", value["token"]);
|
|
LoginPage.messageChannel.send({"method": "closeLogin"});
|
|
if (resultValue == null) return;
|
|
if (resultValue["code"] == 0) {
|
UserInfo user = UserInfo.fromJson(resultValue["data"]);
|
_loginSuccess(user);
|
} else {
|
ToastUtil.toast(value["msg"], context);
|
}
|
} else if (value["code"] == 700000) {
|
//Fluttertoast.showToast(msg: "取消登录了");
|
}
|
} else {
|
ToastUtil.toast(value["msg"], context);
|
setState(() {
|
// oneKeyLogin = false;
|
});
|
}
|
}
|
|
void qqLogin() async {
|
Map value = await UserUtil.loginQQ();
|
}
|
|
void _loginSuccess(UserInfo user) {
|
UserUtil.setUserInfo(user).then((value) {
|
eventBus.fire(LoginEventBus(true));
|
PushUtil.setAlias(user.id!.toString()).then((value) {});
|
//是否需要填写邀请码
|
if (user.hasBoss != null && user.hasBoss == false) {
|
print("跳转到加入队员页面");
|
|
NavigatorUtil.navigateToNextPage(
|
context, AddTeamPage(title: "", skip: true), (data) {
|
popPage(context);
|
});
|
} else {
|
ToastUtil.toast("登录成功", context);
|
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: 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: Padding(
|
padding: const EdgeInsets.fromLTRB(40, 0, 40, 40),
|
child: Column(
|
crossAxisAlignment: CrossAxisAlignment.center,
|
children: [
|
Expanded(
|
child: Container(
|
alignment: Alignment.center,
|
child: getLoginContent())),
|
wxLogin
|
? Column(children: [
|
const Text(
|
"其他方式登录",
|
style: TextStyle(
|
color: Color(0xFF666666),
|
fontSize: 14),
|
),
|
Container(
|
height: 21,
|
),
|
Row(
|
mainAxisAlignment:
|
MainAxisAlignment.spaceAround,
|
children: [
|
getThirdLoginItem("手机号登录",
|
"assets/imgs/mine/ic_login_phone.png")
|
],
|
)
|
])
|
: Container()
|
]))),
|
//用户协议与隐私政策
|
Row( mainAxisAlignment: MainAxisAlignment.center, children: [
|
|
RoundCheckBox(
|
value: checked,
|
onChanged: (value) {
|
setState(() {
|
checked = value;
|
});
|
},
|
),
|
HtmlWidget(
|
"<p>${widget.bindPhone ? "绑定" : "登录"}即表明同意 <a href='${Constant.PROTOCOL_URL}'>用户协议</a> 和 <a href='${Constant.PRIVACY_URL}'>隐私政策</a> </p>",
|
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;
|
}),
|
const SizedBox(width: 10,)
|
])
|
]),
|
//关闭按钮
|
Positioned(
|
top: 40,
|
left: 20,
|
right: 20,
|
child: Wrap(
|
crossAxisAlignment: WrapCrossAlignment.center,
|
alignment: WrapAlignment.spaceBetween,
|
children: [
|
InkWell(
|
onTap: () {
|
if (wxLogin || widget.bindPhone) {
|
popPage(context);
|
} else {
|
setState(() {
|
wxLogin = !wxLogin;
|
});
|
}
|
},
|
child: Container(
|
padding: EdgeInsets.all(10),
|
child: wxLogin || widget.bindPhone
|
? Image.asset(
|
"assets/imgs/mine/ic_login_close.png",
|
height: 16.5,
|
)
|
: Image.asset(
|
"assets/imgs/ic_back.png",
|
width: 14,
|
))),
|
InkWell(
|
onTap: () {
|
ConfigUtil.getConfig(context, "helpLink")
|
.then((value) {
|
if (value == null) {
|
return;
|
}
|
NavigatorUtil.navigateToNextPage(
|
context,
|
BrowserPage(title: "帮助中心", url: value),
|
(data) {});
|
});
|
},
|
child: const Text(
|
"帮助",
|
style: TextStyle(
|
color: Color(0xFF333333), fontSize: 15),
|
)),
|
]))
|
],
|
));
|
}
|
|
Widget getLoginContent() {
|
return wxLogin
|
? Column(mainAxisAlignment: MainAxisAlignment.center, children: [
|
InkWell(
|
onTap: () {
|
if (!checked) {
|
ToastUtil.toast("请同意用户协议与隐私政策", context);
|
return;
|
}
|
|
WXAuthUtil.startAuth(context);
|
},
|
child: Container(
|
height: 42,
|
decoration: BoxDecoration(
|
color: const Color(0xFF08BA06),
|
borderRadius: BorderRadius.circular(13)),
|
child: Row(
|
mainAxisAlignment: MainAxisAlignment.center,
|
children: [
|
Image.asset(
|
"assets/imgs/mine/ic_login_wx.png",
|
height: 22.5,
|
),
|
const SizedBox(
|
width: 8,
|
),
|
const Text(
|
"微信授权登录",
|
style: TextStyle(color: Colors.white, fontSize: 15),
|
)
|
]),
|
))
|
])
|
: Column(
|
crossAxisAlignment: CrossAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.center,
|
children: [
|
Container(
|
alignment: Alignment.centerLeft,
|
padding: const 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/mine/icon_login_phone.png",
|
width: 14,
|
height: 20,
|
),
|
Container(width: 14),
|
Expanded(
|
child: TextField(
|
style: const TextStyle(
|
color: Color(0xFF333333), fontSize: 15),
|
onChanged: (value) {
|
setState(() {
|
phone = value;
|
});
|
},
|
textAlign: TextAlign.start,
|
keyboardType: TextInputType.phone,
|
controller: phoneController,
|
maxLength: 11,
|
decoration: const InputDecoration(
|
counterText: "",
|
hintText: "请输入手机号",
|
hintStyle:
|
TextStyle(color: Color(0xFFCCCCCC), fontSize: 15),
|
contentPadding: EdgeInsets.only(bottom: 3),
|
border: InputBorder.none,
|
focusedBorder: InputBorder.none,
|
),
|
)),
|
],
|
),
|
),
|
Container(height: 15),
|
Row(
|
children: [
|
Expanded(
|
child: 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/mine/icon_login_code.png",
|
width: 16,
|
),
|
Container(width: 14),
|
Expanded(
|
child: TextField(
|
style: const TextStyle(
|
color: Color(0xFF333333), fontSize: 15),
|
onChanged: (value) {
|
setState(() {
|
phone = value;
|
});
|
},
|
textAlign: TextAlign.start,
|
keyboardType: TextInputType.phone,
|
controller: codeController,
|
maxLength: 8,
|
decoration: const InputDecoration(
|
counterText: "",
|
hintText: "请输入验证码",
|
hintStyle: TextStyle(
|
color: Color(0xFFCCCCCC), fontSize: 15),
|
contentPadding: EdgeInsets.only(bottom: 3),
|
border: InputBorder.none,
|
focusedBorder: InputBorder.none,
|
),
|
)),
|
],
|
),
|
)),
|
const SizedBox(
|
width: 6,
|
),
|
MyFillButton(
|
(reSendSMSTimeLeft! > 0
|
? (reSendSMSTimeLeft.toString() + "S重新获取")
|
: reSendSMSTimeLeft == -1
|
? "获取验证码"
|
: "重新获取")
|
.toString(),
|
13,
|
height: 48,
|
fontSize: 15,
|
padding: const EdgeInsets.fromLTRB(12, 0, 12, 0),
|
enable: (reSendSMSTimeLeft! < 1 &&
|
StringUtil.isMobile(phoneController!.value.text)),
|
onClick: () {
|
if (!(reSendSMSTimeLeft! < 1 &&
|
StringUtil.isMobile(phoneController!.value.text))) {
|
return;
|
}
|
//发送验证码
|
UserApiUtil.sendSMS(context, phoneController!.value.text)
|
.then((value) {
|
if (value != null && value["code"] == 0) {
|
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!["msg"], context);
|
}
|
});
|
},
|
),
|
],
|
),
|
Container(height: 35),
|
MyFillButton(
|
widget.bindPhone ? "绑定手机号" : "登录",
|
13,
|
height: 45,
|
color: const Color(0xFFFF2B4B),
|
fontSize: 17,
|
enable: StringUtil.isMobile(phoneController!.value.text) &&
|
codeController!.value.text.length >= 4,
|
onClick: () {
|
if (!(StringUtil.isMobile(phoneController!.value.text) &&
|
codeController!.value.text.length >= 4)) {
|
return;
|
}
|
|
if (!checked) {
|
ToastUtil.toast("请同意用户协议与隐私政策", context);
|
return;
|
}
|
|
if (widget.bindPhone) {
|
UserApiUtil.bindPhone(context, phoneController!.value.text,
|
codeController!.value.text, null)
|
.then((value) {
|
print("结果: $value");
|
if (value!["code"] == 0) {
|
ToastUtil.toast("绑定成功", context);
|
popPage(context);
|
return;
|
} else {
|
ToastUtil.toast(value["msg"], context);
|
}
|
});
|
} else {
|
UserApiUtil.loginByPhone(
|
context,
|
phoneController!.value.text,
|
codeController!.value.text,
|
"")
|
.then((value) {
|
print("结果: $value");
|
if (value!["code"] == 0) {
|
UserInfo user = UserInfo.fromJson(value["data"]);
|
_loginSuccess(user);
|
} else {
|
ToastUtil.toast(value["msg"], context);
|
}
|
});
|
}
|
},
|
),
|
],
|
);
|
}
|
|
Widget getThirdLoginItem(String name, String iconAsset) {
|
return InkWell(
|
onTap: () {
|
if (name == "一键登录" || name == "手机号登录") {
|
setState(() {
|
wxLogin = !wxLogin;
|
});
|
} else if (name == "QQ登录") {
|
qqLogin();
|
} else if (name == "微信登录") {
|
WXAuthUtil.startAuth(context);
|
}
|
},
|
child: Container(
|
constraints: BoxConstraints(minWidth: 80),
|
child: Column(
|
children: [
|
Image.asset(
|
iconAsset,
|
height: 49,
|
),
|
Container(
|
height: 8,
|
),
|
Text(
|
name,
|
style: const TextStyle(color: Color(0xFF9DAAB3), fontSize: 12),
|
)
|
],
|
)),
|
);
|
}
|
}
|