signup.dart 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. import 'dart:async';
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter/services.dart';
  4. import 'package:get/get.dart';
  5. import 'package:link/view/choose_country.dart';
  6. import 'package:link/view/component/link_btn.dart';
  7. import 'package:link/view/component/toast.dart';
  8. import 'package:dio/dio.dart';
  9. import '../constants.dart';
  10. import '../utils/api.dart';
  11. import '../utils/http_utils.dart';
  12. import '../utils/size_fit.dart';
  13. import 'component/top_container.dart';
  14. class SignUp extends StatefulWidget {
  15. bool _isBind = false;
  16. SignUp({Key? key,bool? isBind}) : super(key: key){
  17. if (isBind!=null){
  18. _isBind = isBind;
  19. }
  20. }
  21. @override
  22. State<SignUp> createState() => _SignUpState();
  23. }
  24. class _SignUpState extends State<SignUp> {
  25. String code = '';
  26. String strContent = '';
  27. bool isPhoneSignup = true;
  28. TextEditingController controller = TextEditingController();
  29. FocusNode focusNode = FocusNode();
  30. FocusNode blankNode = FocusNode();
  31. bool checked = true;
  32. @override
  33. void initState() {
  34. // Map<String, dynamic> data = Get.parameters;
  35. // code = data['code'];
  36. Map<String, dynamic> data = Get.parameters;
  37. if (data.isNotEmpty) {
  38. code = data['code']??'';
  39. isPhoneSignup = data['type'] == 'sms';
  40. }
  41. WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
  42. focusNode.requestFocus();
  43. });
  44. super.initState();
  45. }
  46. @override
  47. void dispose() {
  48. // TODO: implement dispose
  49. focusNode.dispose();
  50. blankNode.dispose();
  51. super.dispose();
  52. }
  53. showLoginAlert(bool isPhone) {
  54. FocusScope.of(context).requestFocus(blankNode);
  55. if (widget._isBind){
  56. Toast().showInfoText('${isPhone ? '手机号' : '邮箱'}已绑定其他账号\n请重新输入', context: context);
  57. return;
  58. }
  59. Toast().showCustomHud(
  60. Container(
  61. alignment: Alignment.center,
  62. padding: EdgeInsets.only(top: 32.px, bottom: 32.px),
  63. child: Column(
  64. children: [
  65. Text(
  66. '该${isPhone ? '手机号' : '邮箱'}已注册!\n可直接前往登录',
  67. style: TextStyle(
  68. color: Colors.white,
  69. fontSize: 16.px,
  70. fontWeight: FontWeight.bold),
  71. ),
  72. SizedBox(
  73. height: 16.px,
  74. ),
  75. AlertButton(
  76. title: '前往登录',
  77. isCancel: false,
  78. width: 220.px,
  79. height: 40.px,
  80. callback: () {
  81. Toast().hideHud();
  82. Get.toNamed('/login', parameters: {
  83. "content": strContent,
  84. "type": isPhone ? 'sms' : 'email'
  85. });
  86. }),
  87. SizedBox(
  88. height: 24.px,
  89. ),
  90. AlertButton(
  91. title: '返回重新输入',
  92. isCancel: true,
  93. width: 220.px,
  94. height: 40.px,
  95. callback: () {
  96. Toast().hideHud();
  97. }),
  98. ],
  99. ),
  100. ),
  101. context: context);
  102. }
  103. Future sendCode() async {
  104. if (!checked){
  105. Toast().showInfoText('请阅读并同意协议', context: context);
  106. return;
  107. }
  108. Toast().showHud(context: context);
  109. try {
  110. if (isPhoneSignup) {
  111. Map<String, dynamic> data = await HttpUtils.get(Api.phoneCanRegister,
  112. params: {'mobile': strContent});
  113. if (data['success'] == false) {
  114. Toast().hideHud();
  115. showLoginAlert(true);
  116. return;
  117. }
  118. Map<String, dynamic> data2 = await HttpUtils.post(Api.phoneSendCode,
  119. data: {'mobile': strContent});
  120. print(data2.toString());
  121. } else {
  122. Map<String, dynamic> data = await HttpUtils.get(Api.emailCanRegister,
  123. params: {'email': strContent});
  124. if (data['success'] == false) {
  125. Toast().hideHud();
  126. showLoginAlert(false);
  127. return;
  128. }
  129. Map<String, dynamic> data2 = await HttpUtils.post(Api.emailSendCode,
  130. data: {'email': strContent});
  131. print(data2.toString());
  132. }
  133. } on DioError catch (e) {
  134. print(e.toString());
  135. }
  136. // ignore: nullable_type_in_catch_clause
  137. Toast().hideHud();
  138. Get.toNamed('/verify_code', parameters: {
  139. "code": code,
  140. "type": isPhoneSignup ? 'sms' : 'email',
  141. "content": strContent,
  142. "bind":widget._isBind?'1':'0'
  143. });
  144. }
  145. choose(){
  146. showDialog(
  147. context: context,
  148. barrierDismissible: false,
  149. barrierColor: Colors.transparent,
  150. useSafeArea: false,
  151. builder: (BuildContext context) {
  152. return ChooseCountry();
  153. });
  154. }
  155. @override
  156. Widget build(BuildContext context) {
  157. SizeFit.initialize(context);
  158. return Material(
  159. color: kBgColor,
  160. child: TopContainer(
  161. child: Stack(children: [
  162. // Positioned(
  163. // left: 0,
  164. // top: 0,
  165. // right: 0,
  166. // child: Container(
  167. // padding: EdgeInsets.only(
  168. // left: 12.px, right: 12.px, top: 14.px, bottom: 14.px),
  169. // alignment: Alignment.topLeft,
  170. // child: Image.asset(
  171. // 'assets/images/navi_back.png',
  172. // width: 20.px,
  173. // height: 20.px,
  174. // ),
  175. // )),
  176. Container(
  177. padding: EdgeInsets.only(top: 71.px),
  178. child: Column(
  179. crossAxisAlignment: CrossAxisAlignment.center,
  180. children: [
  181. Image.asset(
  182. 'assets/images/logo.png',
  183. width: 167.px,
  184. height: 64.px,
  185. ),
  186. SizedBox(
  187. height: 36.px,
  188. ),
  189. Container(
  190. width: 315.px,
  191. height: 68.px,
  192. padding: EdgeInsets.only(left: 16.px, right: 16.px),
  193. decoration: BoxDecoration(
  194. borderRadius: BorderRadius.circular(16.px),
  195. color: const Color(0xFF2C2C2E)),
  196. child: Row(
  197. children: [
  198. if (isPhoneSignup)
  199. GestureDetector(
  200. onTap: (){
  201. choose();
  202. },
  203. child: Row(
  204. children: [
  205. Text(
  206. '+86',
  207. style: TextStyle(
  208. fontFamily: 'Link1',
  209. color: Colors.white,
  210. fontSize: 28.px),
  211. ),
  212. SizedBox(
  213. width: 4.px,
  214. ),
  215. Image.asset(
  216. 'assets/images/arrow.png',
  217. width: 24.px,
  218. height: 24.px,
  219. )
  220. ],
  221. ),
  222. ),
  223. if (isPhoneSignup)
  224. SizedBox(
  225. width: 8.px,
  226. ),
  227. Expanded(
  228. child: TextField(
  229. autofocus: true,
  230. controller: controller,
  231. focusNode: focusNode,
  232. // maxLength: 11,
  233. cursorColor: kBtnColor,
  234. keyboardType: isPhoneSignup
  235. ? TextInputType.number
  236. : TextInputType.emailAddress,
  237. onChanged: (value) {
  238. setState(() {
  239. strContent = value;
  240. });
  241. },
  242. onEditingComplete: (() {
  243. FocusScope.of(context).requestFocus(focusNode);
  244. }),
  245. style: TextStyle(
  246. color: Colors.white,
  247. fontSize: 28.px,
  248. fontFamily: 'Link1'),
  249. decoration: InputDecoration(
  250. border: InputBorder.none,
  251. hintText: isPhoneSignup ? '输入我的手机号' : '输入我的邮箱',
  252. hintStyle: TextStyle(
  253. fontSize: 20.px,
  254. color: const Color(0xFF74747A)),
  255. counterText: "",
  256. ),
  257. // keyboardType: TextInputType.number,
  258. inputFormatters: isPhoneSignup
  259. ? [
  260. FilteringTextInputFormatter(
  261. RegExp("[0-9.]"),
  262. allow: true),
  263. ]
  264. : [
  265. // FilteringTextInputFormatter(RegExp("[0-9.]"),
  266. // allow: true),
  267. ],
  268. )),
  269. Opacity(
  270. opacity: strContent.isNotEmpty ? 1 : 0,
  271. child: GestureDetector(
  272. onTap: () {
  273. setState(() {
  274. strContent = '';
  275. controller.clear();
  276. });
  277. },
  278. child: Image.asset(
  279. 'assets/images/clear.png',
  280. width: 24.px,
  281. height: 24.px,
  282. ),
  283. ),
  284. )
  285. ],
  286. ),
  287. ),
  288. SizedBox(
  289. height: 36.px,
  290. ),
  291. LinkButton(
  292. title: isPhoneSignup ? '发送短信验证码' : '发送邮箱验证码',
  293. disable: false,
  294. isBlack: false,
  295. callback: () {
  296. sendCode();
  297. }),
  298. SizedBox(
  299. height: 37.px,
  300. ),
  301. if (!widget._isBind)
  302. Row(
  303. mainAxisAlignment: MainAxisAlignment.center,
  304. children: [
  305. GestureDetector(
  306. onTap: (){
  307. setState(() {
  308. checked = !checked;
  309. });
  310. },
  311. child: Image.asset(
  312. checked?'assets/images/checked.png':'assets/images/check.png',
  313. width: 18.px,
  314. height: 18.px,
  315. ),
  316. ),
  317. SizedBox(
  318. width: 7.px,
  319. ),
  320. Text(
  321. '已阅读并同意',
  322. style: TextStyle(
  323. color: const Color(0xFF74747A), fontSize: 12.px),
  324. ),
  325. GestureDetector(
  326. child: Text(
  327. '《用户服务协议》',
  328. style: TextStyle(color: kBtnColor, fontSize: 12.px),
  329. ),
  330. ),
  331. GestureDetector(
  332. child: Text(
  333. '《隐私权政策》',
  334. style: TextStyle(color: kBtnColor, fontSize: 12.px),
  335. ),
  336. )
  337. ],
  338. ),
  339. Expanded(
  340. child: Container(),
  341. ),
  342. if (!widget._isBind)
  343. GestureDetector(
  344. onTap: () {
  345. setState(() {
  346. strContent = '';
  347. controller.clear();
  348. isPhoneSignup = !isPhoneSignup;
  349. });
  350. },
  351. child: Text(
  352. isPhoneSignup ? '使用邮箱注册' : '使用手机注册',
  353. style: TextStyle(
  354. color: const Color(0xFF808080), fontSize: 14.px),
  355. ),
  356. ),
  357. SizedBox(
  358. height: 50.px,
  359. )
  360. ]))
  361. ])));
  362. }
  363. }