login_page.dart 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. import 'dart:async';
  2. import 'package:flustars/flustars.dart' as FlutterStars;
  3. import 'package:flutter/cupertino.dart';
  4. import 'package:flutter/foundation.dart';
  5. import 'package:flutter/material.dart';
  6. import 'package:fluwx/fluwx.dart' as fluwx;
  7. import 'package:keyboard_actions/keyboard_actions.dart';
  8. import 'package:liftmanager/common/common.dart';
  9. import 'package:liftmanager/common/user_db.dart';
  10. import 'package:liftmanager/internal/account/account_router.dart';
  11. import 'package:liftmanager/internal/account/model/user_entity.dart';
  12. import 'package:liftmanager/internal/work/work_router.dart';
  13. import 'package:liftmanager/net/api_service.dart';
  14. import 'package:liftmanager/res/resources.dart';
  15. import 'package:liftmanager/routers/fluro_navigator.dart';
  16. import 'package:liftmanager/routers/routers.dart';
  17. import 'package:liftmanager/utils/theme_utils.dart';
  18. import 'package:liftmanager/utils/toast.dart';
  19. import 'package:liftmanager/utils/utils.dart';
  20. import 'package:liftmanager/widgets/app_bar.dart';
  21. import 'package:liftmanager/widgets/load_image.dart';
  22. import 'package:liftmanager/widgets/my_button.dart';
  23. import 'package:liftmanager/widgets/text_field.dart';
  24. class LoginPage extends StatefulWidget {
  25. @override
  26. State<StatefulWidget> createState() {
  27. return _LoginState();
  28. }
  29. }
  30. class _LoginState extends State<LoginPage> {
  31. TextEditingController _nameController = TextEditingController();
  32. TextEditingController _passwordController = TextEditingController();
  33. final FocusNode _nodeText1 = FocusNode();
  34. final FocusNode _nodeText2 = FocusNode();
  35. bool _isClick = false;
  36. bool _isWechatInstalled = false; //是否安装微信
  37. StreamSubscription<fluwx.WeChatAuthResponse> _wxlogin;
  38. bool checkXY = false; //是否勾选协议
  39. @override
  40. void initState() {
  41. super.initState();
  42. print("initState() {");
  43. _initFluwx();
  44. _nameController.addListener(_verify);
  45. _passwordController.addListener(_verify);
  46. _nameController.text = FlutterStars.SpUtil.getString(Constant.phone);
  47. checkXY = FlutterStars.SpUtil.getBool("xieyi");
  48. _wxlogin = fluwx.responseFromAuth.listen((res) {
  49. switch (res.errCode) {
  50. case -4:
  51. {
  52. //拒绝
  53. toasts("已拒绝");
  54. break;
  55. }
  56. case -2:
  57. {
  58. //取消
  59. toasts("已取消");
  60. break;
  61. }
  62. case 0:
  63. {
  64. if (res.type != 2) {
  65. print(res.code);
  66. ApiService(context: context).wxLogin(res.code, onSuccess: (res) {
  67. User().setCurrentUser(res);
  68. FlutterStars.SpUtil.putString(
  69. Constant.phone, _nameController.text);
  70. NavigatorUtils.push(context, Routers.home, clearStack: true);
  71. }, onError: (code, msg) {
  72. if (code == 0) {
  73. showAlert(
  74. context,
  75. "提示",
  76. msg,
  77. ""
  78. "确定", () {
  79. Navigator.pop(context);
  80. });
  81. }
  82. });
  83. }
  84. break;
  85. }
  86. }
  87. });
  88. }
  89. _initFluwx() async {
  90. await fluwx.registerWxApi(
  91. appId: "wx0f10e6386fb9969e",
  92. doOnAndroid: true,
  93. doOnIOS: true,
  94. universalLink: "https://www.edtyun.com/");
  95. var result = await fluwx.isWeChatInstalled();
  96. _isWechatInstalled = result;
  97. setState(() {});
  98. }
  99. void _verify() {
  100. String name = _nameController.text;
  101. String password = _passwordController.text;
  102. bool isClick = true;
  103. if (name.isEmpty || name.length < 11) {
  104. isClick = false;
  105. }
  106. if (password.isEmpty || password.length < 6) {
  107. isClick = false;
  108. }
  109. /// 状态不一样在刷新,避免重复不必要的setState
  110. if (isClick != _isClick) {
  111. setState(() {
  112. _isClick = isClick;
  113. });
  114. }
  115. }
  116. void custom_login() {
  117. showLoading(context, "正在登录...");
  118. ApiService(context: context)
  119. .login("12345678910", Utils.generateMd5("123456789"),
  120. onSuccess: (UserEntity res) {
  121. // FlutterStars.SpUtil.putObject(Constant.user, res);
  122. dismissLoading(context);
  123. User().setCurrentUser(res);
  124. print("==============");
  125. FlutterStars.SpUtil.putString(Constant.phone, _nameController.text);
  126. NavigatorUtils.push(context, Routers.home, clearStack: true);
  127. }, onError: (code, errMsg) {
  128. toasts(errMsg);
  129. dismissLoading(context);
  130. });
  131. }
  132. void _login() {
  133. var phone = _nameController.text.toString().trim();
  134. var password = _passwordController.text.toString().trim();
  135. RegExp exp = RegExp(
  136. r'^((13[0-9])|(14[0-9])|(15[0-9])|(16[0-9])|(17[0-9])|(18[0-9])|(19[0-9]))\d{8}$');
  137. bool matched = exp.hasMatch(phone);
  138. if (!matched) {
  139. toasts("请输入正确手机号码");
  140. return;
  141. }
  142. if (!checkXY) {
  143. toasts("请阅读并同意电梯管家协议");
  144. return;
  145. }
  146. showLoading(context, "正在登录...");
  147. ApiService(context: context).login(phone, Utils.generateMd5(password),
  148. onSuccess: (UserEntity res) {
  149. // FlutterStars.SpUtil.putObject(Constant.user, res);
  150. dismissLoading(context);
  151. FlutterStars.SpUtil.putBool("xieyi", true);
  152. User().setCurrentUser(res);
  153. FlutterStars.SpUtil.putString(Constant.phone, _nameController.text);
  154. NavigatorUtils.push(context, Routers.home, clearStack: true);
  155. }, onError: (code, errMsg) {
  156. toasts(errMsg);
  157. dismissLoading(context);
  158. });
  159. }
  160. void _wechatLogin() {
  161. fluwx.sendWeChatAuth(
  162. scope: "snsapi_userinfo",
  163. );
  164. }
  165. @override
  166. void dispose() {
  167. super.dispose();
  168. _wxlogin.cancel();
  169. }
  170. @override
  171. Widget build(BuildContext context) {
  172. return Scaffold(
  173. backgroundColor: ThemeUtils.getTabsBg(context),
  174. appBar: MyAppBar(
  175. centerTitle: "登录",
  176. isBack: false,
  177. ),
  178. body: defaultTargetPlatform == TargetPlatform.iOS
  179. ? FormKeyboardActions(
  180. child: _buildBody(),
  181. )
  182. : SingleChildScrollView(
  183. child: _buildBody(),
  184. ));
  185. }
  186. _buildBody() {
  187. double width = MediaQuery.of(context).size.width;
  188. return Padding(
  189. padding: EdgeInsets.only(left: 34.0, right: 34.0, top: 27.0),
  190. child: Column(
  191. crossAxisAlignment: CrossAxisAlignment.start,
  192. children: <Widget>[
  193. Center(
  194. child: LoadAssetImage(
  195. "login/icon_logo",
  196. // key: Key('${widget.keyName}_delete'),
  197. width: 111.5,
  198. height: 111.5,
  199. )),
  200. Gaps.vGap28,
  201. MyTextField(
  202. key: const Key('phone'),
  203. focusNode: _nodeText1,
  204. controller: _nameController,
  205. maxLength: 11,
  206. keyboardType: TextInputType.phone,
  207. hintText: "请输入手机号",
  208. ),
  209. Gaps.vGap8,
  210. MyTextField(
  211. key: const Key('password'),
  212. keyName: 'password',
  213. focusNode: _nodeText2,
  214. config: Utils.getKeyboardActionsConfig(
  215. context, [_nodeText1, _nodeText2]),
  216. isInputPwd: true,
  217. controller: _passwordController,
  218. keyboardType: TextInputType.visiblePassword,
  219. maxLength: 16,
  220. hintText: "请输入密码",
  221. ),
  222. Gaps.vGap16,
  223. Row(
  224. mainAxisAlignment: MainAxisAlignment.end,
  225. children: <Widget>[
  226. Container(
  227. child: GestureDetector(
  228. onTap: () {
  229. custom_login();
  230. },
  231. child: Text(
  232. "游客登录",
  233. textAlign: TextAlign.right,
  234. style: TextStyle(
  235. // fontSize: 14,
  236. color: Colours.app_main,
  237. ),
  238. ),
  239. )),
  240. ],
  241. ),
  242. Gaps.vGap12,
  243. MyButton(
  244. key: const Key('login'),
  245. onPressed: _isClick ? _login : null,
  246. colors:
  247. _isClick ? null : [Colours.text_gray_c, Colours.text_gray_c],
  248. text: "登录",
  249. ),
  250. Gaps.vGap8,
  251. Row(
  252. children: <Widget>[
  253. Checkbox(
  254. activeColor: Colours.app_main,
  255. tristate: false,
  256. value: checkXY,
  257. onChanged: (bol) {
  258. checkXY = bol;
  259. setState(() {});
  260. },
  261. ),
  262. Expanded(
  263. flex: 1,
  264. child: Wrap(
  265. children: <Widget>[
  266. Text("阅读并同意电梯管家"),
  267. GestureDetector(
  268. onTap: () {
  269. NavigatorUtils.push(
  270. context,
  271. "${WorkRouter.webview}?title=" +
  272. Uri.encodeComponent("电梯管家协议") +
  273. "&url=" +
  274. Uri.encodeComponent(
  275. "http://dl.edtyun.com/xieyi.html"));
  276. },
  277. child: Text("用户协议",
  278. style: TextStyle(
  279. color: Colours.app_main,
  280. )),
  281. ),
  282. Text("及相关"),
  283. GestureDetector(
  284. onTap: () {
  285. NavigatorUtils.push(
  286. context,
  287. "${WorkRouter.webview}?title=" +
  288. Uri.encodeComponent("电梯管家协议") +
  289. "&url=" +
  290. Uri.encodeComponent(
  291. "http://dl.edtyun.com/xieyi.html"));
  292. },
  293. child: Text("隐私声明",
  294. style: TextStyle(
  295. color: Colours.app_main,
  296. )),
  297. ),
  298. ],
  299. ),
  300. )
  301. ],
  302. ),
  303. Gaps.vGap21,
  304. Row(
  305. children: <Widget>[
  306. Expanded(
  307. flex: 1,
  308. child: Container(
  309. height: 20.0,
  310. alignment: Alignment.centerRight,
  311. child: GestureDetector(
  312. child: Text(
  313. '注册账号',
  314. style: TextStyles.textDarkBlue14,
  315. ),
  316. onTap: () => NavigatorUtils.push(
  317. context, "${AccountRouter.registerPage}?authCode="),
  318. ),
  319. ),
  320. ),
  321. SizedBox(
  322. child: Container(
  323. margin: EdgeInsets.fromLTRB(17.5, 0, 17.5, 0),
  324. color: Color(0xFFDDDDDD),
  325. width: 1.5,
  326. height: 19,
  327. ),
  328. ),
  329. Expanded(
  330. flex: 1,
  331. child: Container(
  332. height: 20.0,
  333. alignment: Alignment.centerLeft,
  334. child: GestureDetector(
  335. child: Text(
  336. '忘记密码',
  337. style: TextStyles.textDarkBlue14,
  338. ),
  339. onTap: () => NavigatorUtils.push(
  340. context, AccountRouter.resetPasswordPage),
  341. ),
  342. ),
  343. ),
  344. ],
  345. ),
  346. Gaps.vGap28,
  347. Offstage(
  348. offstage: !_isWechatInstalled,
  349. child: Row(
  350. children: <Widget>[
  351. Expanded(
  352. flex: 1,
  353. child: SizedBox(
  354. height: 1,
  355. child: Container(
  356. color: Color(0xFFDDDDDD),
  357. ),
  358. ),
  359. ),
  360. Container(
  361. margin: EdgeInsets.fromLTRB(12, 0, 12, 0),
  362. alignment: Alignment.center,
  363. child: GestureDetector(
  364. child: Text(
  365. '更多登录方式',
  366. style: TextStyles.textGray12,
  367. ),
  368. onTap: () => NavigatorUtils.push(
  369. context, AccountRouter.registerPage),
  370. )),
  371. Expanded(
  372. flex: 1,
  373. child: SizedBox(
  374. height: 1,
  375. child: Container(
  376. color: Color(0xFFDDDDDD),
  377. ),
  378. ),
  379. ),
  380. ],
  381. )),
  382. Gaps.vGap22,
  383. Offstage(
  384. offstage: !_isWechatInstalled,
  385. child: MyButton(
  386. key: const Key('wxlogin'),
  387. onPressed: _wechatLogin,
  388. text: "微信登录",
  389. borderColor: Theme.of(context).textSelectionHandleColor,
  390. borderWidth: 0.5,
  391. textColor: Colors.white,
  392. colors: [Color(0xFFFFFFFF), Color(0xFFFFFFFF)]),
  393. )
  394. ],
  395. ),
  396. );
  397. }
  398. }