You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

347 lines
11 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import 'dart:async';
import 'package:bot_toast/bot_toast.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:project_telephony/ui/widget/plone_back_button.dart';
import 'package:project_telephony/utils/headers.dart';
import 'package:provider/provider.dart';
import '../../base/base_style.dart';
import '../../constants/api.dart';
import '../../constants/environment/environment.dart';
import '../../model/network/api_client.dart';
import '../../providers/user_provider.dart';
import '../../utils/toast/cloud_toast.dart';
import '../../utils/user_tool.dart';
import '../tab_navigator.dart';
import '../widget/image_scaffold.dart';
import '../widget/plone_bottom.dart';
class LoginPage extends StatefulWidget {
const LoginPage({Key? key}) : super(key: key);
@override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
bool _chooseAgreement = false;
bool _getCodeEnable = true;
late Timer _timer;
///时钟
String _countDownStr = "发送验证码";
///初始化文本
int _countDownNum = 59;
late TextEditingController _phoneController;
late TextEditingController _smsCodeController;
late FocusNode _phoneFocusNode ;
late FocusNode _smsCodeFocusNode;
bool _cantSelected = false;
@override
void initState() {
super.initState();
_phoneFocusNode = FocusNode();
_smsCodeFocusNode = FocusNode();
_phoneController = TextEditingController();
_smsCodeController = TextEditingController();
final userProvider = Provider.of<UserProvider>(context, listen: false);
var env = const String.fromEnvironment('ENV', defaultValue: 'dev');
if (kDebugMode) {
print('env :$env');
}
DevEV.instance.setEnvironment(
context,
environment: env == 'dev',
);
}
@override
void dispose() {
_phoneFocusNode.unfocus();
_smsCodeFocusNode.unfocus();
_phoneController.dispose();
_smsCodeController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return CloudScaffold(
systemStyle: const SystemUiOverlayStyle(
statusBarIconBrightness: Brightness.dark,
),
path: Assets.images.bg.path,
appbar: Row(
children: [
Padding(
padding: EdgeInsets.only(top: 88.w, left: 8.w),
child: const CloudBackButton(isSpecial: true),
),
Padding(
padding: EdgeInsets.only(left: 186.w, top: 88.w),
child: Text(
"",
style: TextStyle(
fontSize: BaseStyle.fontSize34,
color: BaseStyle.color333333,
fontWeight: FontWeight.bold),
))
],
),
extendBody: true,
body: Container(
padding: EdgeInsets.only(left: 64.w, right: 64.w, top: 124.w),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"短信帮手",
style: TextStyle(
fontSize: 64.sp,
fontWeight: FontWeight.bold,
color: Colors.black),
),
32.hb,
Text(
"希望能成为您的短信小助手",
style: TextStyle(fontSize: 32.sp, color: const Color(0xFF999999)),
),
80.hb,
_getBox('+86', 36, _phoneTFWidget()),
_getBox('验证码', 32, _codeWidget()),
112.hb,
PloneBottom(
blM: false,
border: _phoneController.text.length != 11,
opacity: _phoneController.text.length == 11 ? 1 : 0.4,
onTap: () async{
if (_phoneController.text.length < 11) {
BotToast.showText(text: "请输入手机号");
}else if(_smsCodeController.text.length < 6){
BotToast.showText(text: "请输入验证码");
}else if(!_chooseAgreement){
BotToast.showText(text: "请同意并勾选隐私政策");
}else{
var base = await apiClient.request(API.app.login,
data: {'phone': _phoneController.text, 'code': _smsCodeController.text});
if (base.code == 0) {
print(base.data['token']);
await UserTool.userProvider.setToken(base.data['token']);
Get.offAll(() => const TabNavigator());
} else {
CloudToast.show(base.msg);
}
}
},
text: "立即登录",
),
32.hb,
_getText()
],
),
),
);
}
_getBox(String text, int fontSize, Widget plone) {
return Container(
height: 144.w,
width: double.infinity,
padding: EdgeInsets.symmetric(vertical: 48.w),
decoration: BoxDecoration(
// color: Colors.black12,
border: Border(
bottom: BorderSide(color: const Color(0xFFE8E8E8), width: 1.w),
),
),
child: Row(children: [
SizedBox(
width: 112.w,
child: Text(
text,
style: TextStyle(
fontSize: fontSize.sp,
color: BaseStyle.color333333,
fontWeight: FontWeight.bold),
),
),
Container(
width: 2.w,
height: 48.w,
margin: EdgeInsets.symmetric(horizontal: 32.w),
color: const Color(0xFFE8E8E8),
),
plone,
]),
);
}
// 输入手机号
_phoneTFWidget() {
return SizedBox(
// alignment: Alignment.centerLeft,
// padding: EdgeInsets.symmetric(horizontal: 72.w),
width: 430.w,
height: 50.w,
child: TextField(
maxLength: 11,
inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'[0-9]'))],
textCapitalization: TextCapitalization.none,
onChanged: (text) {
_phoneController.text = text;
setState(() {});
},
decoration: InputDecoration(
contentPadding: EdgeInsets.only(bottom: 20.w),
border: InputBorder.none,
counterText: "",
//textfield占位语类似于iOS中的placeholder
hintText: "请输入手机号",
//占位语颜色
hintStyle: const TextStyle(color: Colors.black12),
suffixIcon: GestureDetector(
onTap: !_getCodeEnable
? () {}
: () async {
await apiClient.request(API.app.captcha, data: {
'phone': _phoneController.text,
});
_beginCountDown();
if (_cantSelected) return;
_cantSelected = true;
Future.delayed(const Duration(seconds: 1), () {
_cantSelected = false;
});
},
child: Container(
width: 180.w,
alignment: Alignment.centerRight,
color: Colors.transparent,
child: Text(
_countDownStr,
style: TextStyle(
color: _getCodeEnable
? kPrimaryColor
: BaseStyle.colorcccccc),
),
),
)),
),
);
}
// 输入验证码
_codeWidget() {
return SizedBox(
// alignment: Alignment.centerLeft,
// padding: EdgeInsets.symmetric(horizontal: 72.w),
width: 430.w,
height: 50.w,
child: TextField(
maxLength: 6,
inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'[0-9]'))],
textCapitalization: TextCapitalization.none,
onChanged: (text) {
_smsCodeController.text = text;
setState(() {});
},
decoration: InputDecoration(
contentPadding: EdgeInsets.only(bottom: 20.w),
border: InputBorder.none,
counterText: "",
//textfield占位语类似于iOS中的placeholder
hintText: "请输入验证码",
//占位语颜色
hintStyle: const TextStyle(color: Colors.black12),
),
),
);
}
_beginCountDown() {
///开始倒计时
setState(() {
_getCodeEnable = false;
_countDownStr = "${_countDownNum}s";
});
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
if (!mounted) {
return;
}
setState(() {
if (_countDownNum == 0) {
_countDownNum = 59;
_countDownStr = "获取验证码";
_getCodeEnable = true;
_timer.cancel();
return;
}
_countDownStr = "${_countDownNum--}s";
});
});
}
// 协议
_recognizer(context, int type) {
final TapGestureRecognizer recognizer = TapGestureRecognizer();
recognizer.onTap = () {
if (kDebugMode) {
print("点击协议了");
}
///跳转到用户协议页面
};
return recognizer;
}
_getText() {
return GestureDetector(
onTap: () {
_chooseAgreement = !_chooseAgreement;
setState(() {});
},
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 50.w,
height: 50.w,
padding: EdgeInsets.only(top: 6.w, right: 5.w),
child: !_chooseAgreement
? const Icon(CupertinoIcons.circle,
size: 18, color: Color(0xFFdddddd))
: const Icon(CupertinoIcons.checkmark_circle,
size: 18, color: Colors.blue),
),
RichText(
text: TextSpan(
text: "我已阅读并同意",
style: TextStyle(
color: BaseStyle.colorcccccc, fontSize: 12 * 2.sp),
children: [
TextSpan(
text: '《用户服务协议》',
style: TextStyle(color: kPrimaryColor, fontSize: 12 * 2.sp),
recognizer: _recognizer(context, 2)),
TextSpan(
text: "",
style: TextStyle(
color: BaseStyle.colorcccccc, fontSize: 12 * 2.sp),
),
TextSpan(
text: '《隐私协议》',
style: TextStyle(color: kPrimaryColor, fontSize: 12 * 2.sp),
recognizer: _recognizer(context, 1)),
])),
],
),
);
}
}