registered_page.dart 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674
  1. import 'dart:async';
  2. import 'dart:convert';
  3. import 'dart:io';
  4. import 'package:bbyyy/beans/login_information_bean_entity.dart';
  5. import 'package:bbyyy/beans/upload_image_bean_entity.dart';
  6. import 'package:bbyyy/https/MyDio.dart';
  7. import 'package:bbyyy/https/my_request.dart';
  8. import 'package:bbyyy/my_tools/my_colors.dart';
  9. import 'package:bbyyy/my_tools/my_cookie.dart';
  10. import 'package:bbyyy/my_tools/my_tools.dart';
  11. import 'package:bbyyy/my_tools/my_views.dart';
  12. import 'package:bbyyy/my_tools/protocol.dart';
  13. import 'package:bbyyy/paegs/login_page/login_page.dart';
  14. import 'package:bbyyy/paegs/root_page/root_page.dart';
  15. import 'package:flutter/cupertino.dart';
  16. import 'package:flutter/gestures.dart';
  17. import 'package:flutter/material.dart';
  18. import 'package:flutter/services.dart';
  19. import 'package:flutter_svg/svg.dart';
  20. import 'package:image_cropper/image_cropper.dart';
  21. import 'package:image_picker/image_picker.dart';
  22. class RegisteredPage extends StatefulWidget {
  23. @override
  24. _RegisteredPageState createState() => _RegisteredPageState();
  25. }
  26. class _RegisteredPageState extends State<RegisteredPage> {
  27. TextEditingController _phoneNum = TextEditingController(text: '');
  28. TextEditingController _verificationCode = TextEditingController(text: '');
  29. TextEditingController _nickname = TextEditingController(text: '');
  30. TextEditingController _pw = TextEditingController(text: '');
  31. bool showPW = true;
  32. int focus = -1;
  33. bool haveRead = false;
  34. String verificationCodeText = '发送验证码';
  35. File _image;
  36. final picker = ImagePicker();
  37. Timer _timer;
  38. @override
  39. Widget build(BuildContext context) {
  40. return GestureDetector(
  41. onTap: () {
  42. MyTools().hideKeyboard(context);
  43. setState(() {
  44. focus = -1;
  45. });
  46. },
  47. child: Scaffold(
  48. body: SingleChildScrollView(
  49. child: Column(
  50. children: [
  51. Column(
  52. children: [
  53. Container(
  54. height: MediaQuery.of(context).size.width * (506 / 750),
  55. child: Stack(
  56. children: [
  57. Image.asset(
  58. 'images/bg_1.png',
  59. width: MediaQuery.of(context).size.width,
  60. height:
  61. MediaQuery.of(context).size.width * (506 / 750),
  62. ),
  63. Positioned(
  64. top: 67,
  65. child: Column(
  66. children: [
  67. Stack(
  68. children: [
  69. Image.asset(
  70. 'images/yuan_bg.png',
  71. height: 147,
  72. width: 147,
  73. ),
  74. GestureDetector(
  75. child: _image == null
  76. ? SvgPicture.asset(
  77. 'images/svg/头像上传.svg',
  78. height: 75,
  79. width: 75,
  80. )
  81. : ClipRRect(
  82. child: Image.file(
  83. _image,
  84. height: 75,
  85. width: 75,
  86. ),
  87. borderRadius: BorderRadius.all(
  88. Radius.circular(75 / 2)),
  89. ),
  90. onTap: () async {
  91. final pickedFile = await picker.getImage(
  92. source: ImageSource.gallery);
  93. print('pickedFile---${pickedFile.path}');
  94. if (pickedFile != null) {
  95. File cropperImg =
  96. await ImageCropper.cropImage(
  97. sourcePath: pickedFile.path,
  98. cropStyle: CropStyle.rectangle,
  99. aspectRatio: CropAspectRatio(
  100. ratioX: 1, ratioY: 1),
  101. aspectRatioPresets: [
  102. CropAspectRatioPreset.square,
  103. ],
  104. androidUiSettings:
  105. AndroidUiSettings(
  106. toolbarTitle: '图片剪裁',
  107. toolbarColor:
  108. MyColors.cFF4233,
  109. toolbarWidgetColor:
  110. Colors.white,
  111. initAspectRatio:
  112. CropAspectRatioPreset
  113. .square,
  114. lockAspectRatio: true),
  115. iosUiSettings: IOSUiSettings(
  116. minimumAspectRatio: 1.0,
  117. resetAspectRatioEnabled:
  118. false,
  119. rotateButtonsHidden: true));
  120. if (cropperImg != null) {
  121. setState(() {
  122. print(
  123. 'cropperImg---${cropperImg.path}');
  124. _image = cropperImg;
  125. print('_image---${_image.path}');
  126. });
  127. }
  128. }
  129. },
  130. behavior: HitTestBehavior.translucent,
  131. )
  132. ],
  133. alignment: Alignment.center,
  134. ),
  135. Container(
  136. child: Text(
  137. '头像上传',
  138. style: TextStyle(
  139. color: Colors.white, fontSize: 14),
  140. ),
  141. margin: EdgeInsets.only(top: 6),
  142. )
  143. ],
  144. ),
  145. )
  146. ],
  147. alignment: Alignment.topCenter,
  148. ),
  149. ),
  150. Container(
  151. padding: EdgeInsets.only(left: 47, right: 47, top: 26),
  152. child: Column(
  153. children: [
  154. // Container(
  155. // child: Text(
  156. // 'Hello Welcome !',
  157. // style: TextStyle(
  158. // color: MyColors.cFF4233, fontSize: 24),
  159. // ),
  160. // margin: EdgeInsets.only(bottom: 25),
  161. // ),
  162. Row(
  163. children: [
  164. Container(
  165. child: SvgPicture.asset(
  166. 'images/svg/手机.svg',
  167. height: 22,
  168. width: 22,
  169. ),
  170. height: 22,
  171. width: 22,
  172. ),
  173. Expanded(
  174. child: TextField(
  175. controller: _phoneNum,
  176. inputFormatters: [
  177. onlyInputNumberAndWorkFormatter(),
  178. LengthLimitingTextInputFormatter(11)
  179. ],
  180. cursorColor: MyColors.cFF4233,
  181. cursorWidth: 1.0,
  182. onTap: () {
  183. setState(() {
  184. focus = 0;
  185. });
  186. },
  187. decoration: InputDecoration(
  188. border: InputBorder.none,
  189. disabledBorder: InputBorder.none,
  190. enabledBorder: InputBorder.none,
  191. focusedBorder: InputBorder.none,
  192. isDense: true,
  193. hintText: '请输入手机号',
  194. hintStyle: TextStyle(
  195. color: MyColors.c999999, fontSize: 16),
  196. contentPadding: const EdgeInsets.fromLTRB(
  197. 14, 4.5, 8, 4.5),
  198. ),
  199. maxLines: 1,
  200. style: TextStyle(
  201. color: MyColors.c333333,
  202. fontSize: 16,
  203. height: 1.3,
  204. letterSpacing: 0.2),
  205. keyboardType: TextInputType.number,
  206. onChanged: (t) {},
  207. ),
  208. )
  209. ],
  210. ),
  211. Container(
  212. height: 1,
  213. color:
  214. focus == 0 ? MyColors.cFF4233 : MyColors.cD7D7D7,
  215. margin: EdgeInsets.only(top: 8, bottom: 39),
  216. ),
  217. Row(
  218. children: [
  219. Container(
  220. child: SvgPicture.asset(
  221. 'images/svg/昵称.svg',
  222. height: 22,
  223. width: 22,
  224. ),
  225. height: 22,
  226. width: 22,
  227. ),
  228. Expanded(
  229. child: TextField(
  230. inputFormatters: [
  231. LengthLimitingTextInputFormatter(12)
  232. ],
  233. controller: _nickname,
  234. cursorColor: MyColors.cFF4233,
  235. cursorWidth: 1.0,
  236. onTap: () {
  237. setState(() {
  238. focus = 2;
  239. });
  240. },
  241. decoration: InputDecoration(
  242. border: InputBorder.none,
  243. disabledBorder: InputBorder.none,
  244. enabledBorder: InputBorder.none,
  245. focusedBorder: InputBorder.none,
  246. hintText: '请输入昵称',
  247. hintStyle: TextStyle(
  248. color: MyColors.c999999, fontSize: 16),
  249. isDense: true,
  250. contentPadding: const EdgeInsets.fromLTRB(
  251. 14, 4.5, 8, 4.5)),
  252. maxLines: 1,
  253. style: TextStyle(
  254. color: MyColors.c333333,
  255. fontSize: 16,
  256. height: 1.3,
  257. letterSpacing: 0.2),
  258. keyboardType: TextInputType.text,
  259. onChanged: (t) {},
  260. ),
  261. ),
  262. ],
  263. ),
  264. Container(
  265. height: 1,
  266. color:
  267. focus == 2 ? MyColors.cFF4233 : MyColors.cD7D7D7,
  268. margin: EdgeInsets.only(top: 8, bottom: 39),
  269. ),
  270. Row(
  271. children: [
  272. Container(
  273. child: SvgPicture.asset(
  274. 'images/svg/验证码.svg',
  275. height: 22,
  276. width: 22,
  277. ),
  278. height: 22,
  279. width: 22,
  280. ),
  281. Expanded(
  282. child: TextField(
  283. controller: _verificationCode,
  284. cursorColor: MyColors.cFF4233,
  285. cursorWidth: 1.0,
  286. inputFormatters: [
  287. onlyInputNumberAndWorkFormatter(),
  288. LengthLimitingTextInputFormatter(6)
  289. ],
  290. onTap: () {
  291. setState(() {
  292. focus = 1;
  293. });
  294. },
  295. decoration: InputDecoration(
  296. border: InputBorder.none,
  297. disabledBorder: InputBorder.none,
  298. enabledBorder: InputBorder.none,
  299. focusedBorder: InputBorder.none,
  300. hintText: '请输入验证码',
  301. hintStyle: TextStyle(
  302. color: MyColors.c999999, fontSize: 16),
  303. isDense: true,
  304. contentPadding:
  305. const EdgeInsets.fromLTRB(14, 4.5, 8, 4.5)),
  306. maxLines: 1,
  307. style: TextStyle(
  308. color: MyColors.c333333,
  309. fontSize: 16,
  310. height: 1.3,
  311. letterSpacing: 0.2),
  312. keyboardType: TextInputType.number,
  313. onChanged: (t) {},
  314. ),
  315. ),
  316. GestureDetector(
  317. onTap: (){
  318. if(verificationCodeText!='发送验证码'){
  319. showToast('验证码发送中');
  320. return;
  321. }
  322. sendTheVerificationCode();
  323. },
  324. behavior: HitTestBehavior.translucent,
  325. child: Container(
  326. decoration: BoxDecoration(
  327. color: MyColors.c19FF4233,
  328. borderRadius:
  329. BorderRadius.all(Radius.circular(4))),
  330. child: Text(verificationCodeText,style: TextStyle(color: MyColors.cFF4233,fontSize: 14),),
  331. alignment: Alignment.center,
  332. height: 34,
  333. width: 90,
  334. ),
  335. )
  336. ],
  337. ),
  338. Container(
  339. height: 1,
  340. color:
  341. focus == 1 ? MyColors.cFF4233 : MyColors.cD7D7D7,
  342. margin: EdgeInsets.only(top: 8, bottom: 39),
  343. ),
  344. Row(
  345. children: [
  346. Container(
  347. child: SvgPicture.asset(
  348. 'images/svg/密码.svg',
  349. height: 22,
  350. width: 22,
  351. ),
  352. height: 22,
  353. width: 22,
  354. ),
  355. Expanded(
  356. child: TextField(
  357. controller: _pw,
  358. inputFormatters: [
  359. onlyInputNumberAndWorkFormatter(),
  360. LengthLimitingTextInputFormatter(8)
  361. ],
  362. cursorColor: MyColors.cFF4233,
  363. cursorWidth: 1.0,
  364. onTap: () {
  365. setState(() {
  366. focus = 3;
  367. });
  368. },
  369. decoration: InputDecoration(
  370. border: InputBorder.none,
  371. disabledBorder: InputBorder.none,
  372. enabledBorder: InputBorder.none,
  373. focusedBorder: InputBorder.none,
  374. hintText: '请输入密码(6到8位)',
  375. hintStyle: TextStyle(
  376. color: MyColors.c999999, fontSize: 16),
  377. isDense: true,
  378. contentPadding: const EdgeInsets.fromLTRB(
  379. 14, 4.5, 8, 4.5)),
  380. maxLines: 1,
  381. style: TextStyle(
  382. color: MyColors.c333333,
  383. fontSize: 16,
  384. height: 1.3,
  385. letterSpacing: 0.2),
  386. keyboardType: TextInputType.visiblePassword,
  387. obscureText: !showPW,
  388. onChanged: (t) {},
  389. ),
  390. ),
  391. GestureDetector(
  392. onTap: () {
  393. setState(() {
  394. showPW = !showPW;
  395. });
  396. },
  397. behavior: HitTestBehavior.translucent,
  398. child: Container(
  399. height: 30,width: 30,
  400. padding: EdgeInsets.all(4),
  401. child: SvgPicture.asset(showPW
  402. ? 'images/svg/不显示.svg'
  403. : 'images/svg/显示.svg'))),
  404. ],
  405. ),
  406. Container(
  407. height: 1,
  408. color:
  409. focus == 3 ? MyColors.cFF4233 : MyColors.cD7D7D7,
  410. margin: EdgeInsets.only(top: 8, bottom: 20),
  411. ),
  412. Row(
  413. children: [
  414. Checkbox(
  415. value: haveRead,
  416. onChanged: (v) {
  417. setState(() {
  418. haveRead = v;
  419. });
  420. },
  421. activeColor: MyColors.cFF4233,
  422. ),
  423. RichText(
  424. text: TextSpan(
  425. text: '我已阅读并同意',
  426. style: TextStyle(
  427. color: MyColors.c999999, fontSize: 12),
  428. children: [
  429. TextSpan(
  430. text: '《使用协议》',
  431. style: TextStyle(
  432. color: MyColors.cFF4233,
  433. fontSize: 12),
  434. recognizer: TapGestureRecognizer()
  435. ..onTap = () {
  436. MyTools().toPage(
  437. context,
  438. PrivacyPolicyPage('使用协议'),
  439. (then) {});
  440. }),
  441. TextSpan(
  442. text: '和',
  443. style: TextStyle(
  444. color: MyColors.c999999,
  445. fontSize: 12),
  446. ),
  447. TextSpan(
  448. text: '《隐私政策》',
  449. style: TextStyle(
  450. color: MyColors.cFF4233,
  451. fontSize: 12),
  452. recognizer: TapGestureRecognizer()
  453. ..onTap = () {
  454. MyTools().toPage(
  455. context,
  456. PrivacyPolicyPage('隐私政策'),
  457. (then) {});
  458. }),
  459. ]),
  460. ),
  461. ],
  462. mainAxisAlignment: MainAxisAlignment.end,
  463. ),
  464. GestureDetector(
  465. onTap: () {
  466. if (_phoneNum.text.isEmpty ||
  467. _phoneNum.text.length != 11) {
  468. showToast('请填写正确的手机号');
  469. return;
  470. }
  471. if (_pw.text.isEmpty || _pw.text.length < 6) {
  472. showToast('请填写正确的密码(由数字和字母组合的至少6位的组合)');
  473. return;
  474. }
  475. if (_nickname.text.isEmpty) {
  476. showToast('请填写昵称');
  477. return;
  478. }
  479. if (_verificationCode.text.isEmpty) {
  480. showToast('请填写验证码');
  481. return;
  482. }
  483. if (_image == null) {
  484. showToast('请设置头像');
  485. return;
  486. }
  487. if (!haveRead) {
  488. showToast('请阅读并同意《隐私政策》');
  489. return;
  490. }
  491. verificationCode();
  492. },
  493. behavior: HitTestBehavior.translucent,
  494. child: Container(
  495. margin: EdgeInsets.only(top: 20),
  496. decoration: BoxDecoration(
  497. borderRadius: BorderRadius.all(
  498. Radius.circular(20),
  499. ),
  500. gradient: LinearGradient(
  501. colors: MyColors.lg,
  502. ),
  503. ),
  504. height: 44,
  505. child: Text(
  506. '注 册',
  507. style:
  508. TextStyle(color: Colors.white, fontSize: 17),
  509. ),
  510. alignment: Alignment.center,
  511. padding: EdgeInsets.only(bottom: 2),
  512. ),
  513. ),
  514. Container(
  515. alignment: Alignment.centerRight,
  516. child: GestureDetector(
  517. onTap: () {
  518. MyTools().toPage(context, LoginPage(), (then) {},
  519. noBack: true);
  520. },
  521. behavior: HitTestBehavior.translucent,
  522. child: Container(
  523. child: Text(
  524. '已有账号,去登录',
  525. style: TextStyle(
  526. color: MyColors.cFF4233, fontSize: 13),
  527. ),
  528. padding: EdgeInsets.all(8),
  529. margin: EdgeInsets.only(top: 20),
  530. ),
  531. ),
  532. ),
  533. ],
  534. crossAxisAlignment: CrossAxisAlignment.start,
  535. ),
  536. ),
  537. ],
  538. ),
  539. ],
  540. ),
  541. ),
  542. ),
  543. );
  544. }
  545. void uploadAvatar() {
  546. upload(_image, (r, hasError) {
  547. if (!hasError) {
  548. UploadImageBeanEntity data =
  549. UploadImageBeanEntity().fromJson(json.decode(r.data.toString()));
  550. registered(data);
  551. }
  552. }, (error) {});
  553. }
  554. void registered(UploadImageBeanEntity data) {
  555. registeredAccountNumber({
  556. 'mobile': _phoneNum.text,
  557. 'name': _nickname.text,
  558. 'password': MyTools.base64Encode(_pw.text),
  559. 'picture': data.data[0].path,
  560. }, (re, hasError) {
  561. if (!hasError) {
  562. // showToast('注册成功');
  563. // MyTools().toPage(
  564. // context, LoginPage(), (then) {},
  565. // noBack: true);
  566. _timer.cancel();
  567. loginAccount({
  568. 'user': _phoneNum.text,
  569. 'password': MyTools.base64Encode(_pw.text),
  570. 'version': MyCookie().packageInfo.version,
  571. 'phone': Platform.isAndroid ? 'Android' : 'IOS'
  572. }, (r, hE) {
  573. if (!hE) {
  574. LoginInformationBeanEntity entity = LoginInformationBeanEntity()
  575. .fromJson(json.decode(r.data.toString()));
  576. MyCookie().saveLoginInformationBeanEntity(entity);
  577. MyDio().initDio();
  578. MyTools().toPage(context, RootPage(), (then) {}, noBack: true);
  579. }
  580. }, (e) {});
  581. }
  582. }, (error) {});
  583. }
  584. int countdown = 60;
  585. void sendTheVerificationCode() {
  586. if(_phoneNum.text.isEmpty||_phoneNum.text.length!=11){
  587. showToast('请输入正确的手机号');
  588. return;
  589. }
  590. MyDio().post('/hms/sendCode', {
  591. 'mobile':_phoneNum.text
  592. }, (response, hasError) {
  593. if(!hasError){
  594. }
  595. }, (error) {
  596. showToast('发送失败');
  597. countdown = 2;
  598. });
  599. setState(() {
  600. setState(() {
  601. verificationCodeText = '$countdown s';
  602. countdown--;
  603. });
  604. });
  605. _timer = Timer.periodic(Duration(seconds: 1), (timer) {
  606. if(countdown==0){
  607. timer.cancel();
  608. setState(() {
  609. countdown = 60;
  610. verificationCodeText = '发送验证码';
  611. });
  612. return;
  613. }
  614. setState(() {
  615. verificationCodeText = '$countdown s';
  616. countdown--;
  617. });
  618. });
  619. }
  620. void verificationCode() {
  621. MyDio().post('/hms/verifyCode', {
  622. 'mobile':_phoneNum.text,
  623. 'code':int.parse(_verificationCode.text),
  624. }, (response, hasError) {
  625. if(!hasError){
  626. uploadAvatar();
  627. }
  628. }, (error) {
  629. showToast('验证码错误');
  630. return;
  631. });
  632. }
  633. }
  634. class PrivacyPolicyPage extends StatefulWidget {
  635. String type;
  636. PrivacyPolicyPage(this.type);
  637. @override
  638. _PrivacyPolicyPageState createState() => _PrivacyPolicyPageState();
  639. }
  640. class _PrivacyPolicyPageState extends State<PrivacyPolicyPage> {
  641. @override
  642. Widget build(BuildContext context) {
  643. return Scaffold(
  644. body: Column(
  645. children: [
  646. MyViews().myAppBar(widget.type, context, []),
  647. Expanded(
  648. child: SingleChildScrollView(
  649. child: Padding(
  650. padding: const EdgeInsets.all(8.0),
  651. child: Text(
  652. widget.type == '使用协议' ? serviceAgreement : privacyPolicy),
  653. ),
  654. ))
  655. ],
  656. ),
  657. );
  658. }
  659. }