123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504 |
- import 'dart:async';
- import 'dart:io';
- import 'package:eitc_erm_app/register.dart';
- 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 'bean/login_entity.dart';
- import 'bean/normal_response.dart';
- import 'bottom_navigation.dart';
- import 'doctor_talk_list.dart';
- void main() {
- WidgetsFlutterBinding.ensureInitialized();
- runApp(Login());
- }
- class Login extends StatefulWidget {
- @override
- State<StatefulWidget> createState() => LoginState();
- }
- class LoginState extends State<Login> {
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- appBar: AppBar(title: Text('登录'), centerTitle: true),
- body: Center(
- child: MyBody(),
- ),
- );
- }
- }
- class MyBody extends StatefulWidget {
- @override
- _MyBodyState createState() => _MyBodyState();
- }
- class _MyBodyState extends State<MyBody> {
- bool isButtonEnable = true; //按钮状态 是否可点击
- String buttonText = '发送验证码'; //初始文本
- int count = 60; //初始倒计时时间
- Timer? timer; //倒计时的计时器
- TextEditingController mController = TextEditingController();
- TextEditingController phoneController = TextEditingController();
- bool isPasswordLogin = false;
- String passText = "验证码";
- String loginText = "密码登录";
- String hintText = "请输入验证码";
- int patientOrDoctor = 1;
- void _buttonClickListen() {
- if (!Utils.isChinaPhoneLegal(phoneController.text)) {
- Component.toast("请输入正确手机号码!", 0);
- return null;
- }
- setState(() {
- 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)'; //更新文本内容
- }
- });
- });
- }
- @override
- void dispose() {
- timer?.cancel(); //销毁计时器
- super.dispose();
- }
- @override
- Widget build(BuildContext context) {
- return SingleChildScrollView(
- child: Container(
- padding: const EdgeInsets.only(top: 10.0, left: 10.0, right: 10.0),
- child: Column(
- children: <Widget>[
- Container(
- color: Colors.white,
- padding: const EdgeInsets.only(left: 10, right: 10),
- child: Column(
- children: <Widget>[
- const Padding(
- padding: EdgeInsets.fromLTRB(0, 80, 0, 80),
- child: Center(
- child: Image(
- image: AssetImage('assets/images/logo.png'),
- ),
- ),
- ),
- Opacity(
- opacity: patientOrDoctor == 1 ? 1 : 0,
- child: const Align(
- alignment: Alignment.centerLeft,
- child: Text(
- '未注册的手机号验证后自动创建您的账号',
- style: TextStyle(color: Colors.blue, fontSize: 15),
- textAlign: TextAlign.left,
- overflow: TextOverflow.ellipsis,
- ),
- )),
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- crossAxisAlignment: CrossAxisAlignment.baseline,
- textBaseline: TextBaseline.alphabetic,
- children: <Widget>[
- SizedBox(
- width: 50,
- child: Text(
- patientOrDoctor == 1 ? "+86" : "用户名",
- style: const TextStyle(
- fontSize: 13, color: Color(0xff333333)),
- ),
- ),
- Expanded(
- child: Padding(
- padding:
- const EdgeInsets.only(left: 0, right: 15, top: 5),
- child: TextFormField(
- maxLines: 1,
- onSaved: (value) {},
- controller: phoneController,
- textAlign: TextAlign.left,
- inputFormatters: patientOrDoctor == 1
- ? [
- FilteringTextInputFormatter.digitsOnly,
- LengthLimitingTextInputFormatter(11)
- ]
- : [],
- decoration: InputDecoration(
- hintText:
- (patientOrDoctor == 1 ? '请填写手机号' : "请填写用户名"),
- hintStyle: const TextStyle(
- color: Color(0xff999999),
- fontSize: 13,
- ),
- alignLabelWithHint: true,
- border: const OutlineInputBorder(
- borderSide: BorderSide.none),
- ),
- ),
- ),
- ),
- ],
- ),
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- crossAxisAlignment: CrossAxisAlignment.baseline,
- textBaseline: TextBaseline.alphabetic,
- children: <Widget>[
- SizedBox(
- width: 50,
- child: Text(
- passText,
- style: TextStyle(
- fontSize: 13, color: Color(0xff333333)),
- )),
- Expanded(
- child: Padding(
- padding: EdgeInsets.only(left: 0, right: 15, top: 0),
- child: TextFormField(
- maxLines: 1,
- onSaved: (value) {},
- controller: mController,
- textAlign: TextAlign.left,
- obscureText: isPasswordLogin,
- inputFormatters: isPasswordLogin
- ? []
- : [
- FilteringTextInputFormatter.digitsOnly,
- LengthLimitingTextInputFormatter(6)
- ],
- decoration: InputDecoration(
- counterText: "",
- hintText: (hintText),
- 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<Color>(
- (states) {
- if (states.contains(WidgetState.disabled)) {
- return Colors.brown; // Disabled color
- }
- return Colors.blue; // Regular color
- }),
- foregroundColor:
- const WidgetStatePropertyAll(Colors.white),
- ),
- // backgroundColor : isButtonEnable
- // ? Color(0xff44c5fe)
- // : Colors.grey.withOpacity(0.1), //按钮的颜色
- // splashColor: isButtonEnable
- // ? Colors.white.withOpacity(0.1)
- // : Colors.transparent,
- // shape: StadiumBorder(side: BorderSide.none),
- onPressed: () {
- if (isButtonEnable) {
- setState(() {
- _buttonClickListen();
- });
- }
- },
- child: Text(
- buttonText,
- style: const TextStyle(
- fontSize: 12,
- ),
- ),
- ),
- ),
- ),
- ],
- ),
- ],
- ),
- ),
- Container(
- width: double.infinity,
- height: 45,
- margin: const EdgeInsets.only(top: 30, left: 10, right: 10),
- child: ElevatedButton(
- style: ButtonStyle(
- backgroundColor:
- MaterialStateProperty.resolveWith<Color>((states) {
- return Colors.blue; // Regular color
- }),
- ),
- onPressed: () {
- logd('手机号:${phoneController.text},验证码:${mController.text}');
- login();
- },
- // shape: StadiumBorder(side: BorderSide.none),
- // color: Color(0xff44c5fe),
- child: Text(
- '登录',
- style: TextStyle(color: Colors.white, fontSize: 15),
- ),
- ),
- ),
- Padding(
- padding: EdgeInsets.all(20),
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Row(
- children: <Widget>[
- Text("患者"),
- Radio(
- value: 1,
- onChanged: (value) {
- setState(() {
- this.patientOrDoctor = value!;
- });
- },
- groupValue: patientOrDoctor,
- ),
- SizedBox(
- width: 20,
- ),
- Text("医生"),
- Radio(
- value: 2,
- onChanged: (value) {
- setState(() {
- patientOrDoctor = value!;
- isPasswordLogin = true;
- _updateText();
- });
- },
- groupValue: patientOrDoctor,
- ),
- ],
- ),
- Visibility(
- visible: patientOrDoctor == 1,
- child: GestureDetector(
- onTap: () {
- isPasswordLogin = !isPasswordLogin;
- logd(isPasswordLogin);
- setState(() {
- _updateText();
- });
- },
- child: Text(
- loginText,
- style: const TextStyle(
- color: Colors.blue, fontSize: 15),
- textAlign: TextAlign.right,
- ),
- )),
- ]),
- )
- ],
- ),
- ),
- );
- }
- void _updateText() {
- if (isPasswordLogin) {
- passText = "密 码";
- loginText = "验证码登录";
- hintText = "请输入密码";
- } else {
- passText = "验证码";
- loginText = "密码登录";
- hintText = "请输入验证码";
- }
- }
- Future<void> launchAndroid() async {
- const platform = MethodChannel('com.example.xcx_dashan_app/channel');
- try {
- var result = await platform.invokeMethod('launchApp');
- // var result = await platform.invokeMethod('launchAppOne',{'param1': "这是一个参数"});
- // var result = await platform.invokeMethod('launchAppOne',{'param1': "这是一个参数",'param2': "这是一个参数"});
- logd("结果$result");
- } on PlatformException catch (e) {
- logd("Failed to invoke method: '${e.message}'.");
- }
- }
- Future<String?> sendCaptchaCode() async {
- var params = {
- 'phoneNumber': phoneController.text,
- };
- var response = await http.post(
- Uri.parse('${Global.BaseUrl}sendCaptchaCode'),
- headers: jsonHeaders(),
- body: encodeBody(params));
- logd("encoded=${encodeBody(params)}");
- 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;
- }
- }
- Future<String?> login() async {
- if (patientOrDoctor == 1) {
- if (!Utils.isChinaPhoneLegal(phoneController.text)) {
- Component.toast("请输入正确手机号码!", 0);
- return null;
- }
- } else {
- if (phoneController.text.isEmpty) {
- Component.toast("请输入用户名!", 0);
- return null;
- }
- }
- if (!isPasswordLogin && !Utils.isVerifyCode(mController.text)) {
- Component.toast("请输入正确验证码!", 0);
- return null;
- }
- //验证码登录
- if (!isPasswordLogin) {
- bool bo = await _checkCaptchaCode();
- if (!bo) {
- Component.toast("验证码错误!", 0);
- return null;
- }
- }
- Map<String, dynamic> params;
- if (isPasswordLogin) {
- params = {
- 'phoneNumber': phoneController.text,
- 'password': aesEncrypt(mController.text),
- 'type': patientOrDoctor,
- };
- } else {
- params = {
- 'phoneNumber': phoneController.text,
- 'captchaCode': mController.text,
- 'type': patientOrDoctor,
- };
- }
- String url = 'captcha/login';
- if (isPasswordLogin) {
- url = 'password/login';
- }
- logd("提交数据=$params");
- var response = await http.post(Uri.parse(Global.BaseUrl + url),
- body: encodeBody(params), headers: jsonHeaders());
- logd(response.body.toString());
- if (response.statusCode == 200) {
- final json = decodeBodyToJson(response.bodyBytes);
- logd(json);
- LoginEntity mLoginEntity = LoginEntity.fromJson(json);
- if (mLoginEntity.code == Global.responseSuccessCode) {
- Component.toast("登录成功!", 2);
- Global.loginPhoneNo = phoneController.text;
- Global.token = mLoginEntity.data!.token!;
- Global.user = mLoginEntity;
- if (patientOrDoctor == 2) {
- Utils.saveData("doctorToken", Global.token);
- Navigator.pushReplacement(
- context,
- MaterialPageRoute(builder: (context) => DoctorTalkList()),
- );
- } else {
- Utils.saveData("token", Global.token);
- Utils.saveData("userId", Global.user.data!.id.toString());
- Utils.saveData("userAvatar", mLoginEntity.data?.avatar ?? "");
- Navigator.pushReplacement(
- context,
- MaterialPageRoute(builder: (context) => BottomNavigationWidget()),
- );
- }
- } else {
- Component.toast(mLoginEntity.msg.toString(), 0);
- if (mLoginEntity.msg.toString().contains("用户不存在") &&
- patientOrDoctor == 1) {
- Navigator.push(
- context,
- MaterialPageRoute(builder: (context) => Register()),
- );
- }
- }
- return response.toString();
- } else {
- Component.toast("出错了,请稍后再试!", 0);
- return null;
- }
- }
- ///检查验证码
- Future<bool> _checkCaptchaCode() async {
- Map<String, dynamic> 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;
- }
- }
|