sign_up_view.dart 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. import 'dart:async';
  2. import 'package:flutter_svg/flutter_svg.dart';
  3. import 'package:get/get.dart';
  4. import 'package:flutter/material.dart';
  5. import 'package:get_storage/get_storage.dart';
  6. import 'package:grpc/grpc.dart';
  7. import 'package:trackoffical_app/service/api.dart';
  8. import 'package:trackoffical_app/view/login/logo_widget.dart';
  9. import '../../route.dart';
  10. import '../../styles/theme.dart';
  11. import 'package:trackoffical_app/pb.dart' as pb;
  12. class SignUpController extends GetxController {
  13. var phone = '';
  14. var code = '';
  15. String name = '' ;
  16. final sex = pb.User_Sex.Male.obs;
  17. final codeRetryLeft = 0.seconds.obs;
  18. Timer? ticker;
  19. final isSignUpEnable = true.obs;
  20. @override
  21. void onInit() {
  22. super.onInit();
  23. ticker = Timer.periodic(1.seconds, (timer) {
  24. codeRetryLeft.value -= 1.seconds;
  25. });
  26. }
  27. onGetCode() async{
  28. try{
  29. await ApiService.to.authSendCodeToPhone(phone, pb.SmsType.SignUp);
  30. codeRetryLeft.value = await ApiService.to.getSmsSendLeftTime(phone);
  31. }on GrpcError catch(e){
  32. if (e.code== StatusCode.alreadyExists){
  33. Get.snackbar('已注册', '请直接登录');
  34. }else{
  35. Get.snackbar('发送失败', e.message??'');
  36. }
  37. }catch(e){
  38. Get.snackbar('发送失败', e.toString());
  39. }
  40. }
  41. void onSignUp() async{
  42. if(name.isEmpty){
  43. Get.snackbar('请输入昵称', '不能为空');
  44. return;
  45. }
  46. if(isSignUpEnable.value){
  47. isSignUpEnable.value = false;
  48. try{
  49. await ApiService.to.signUp(phone, code, name, sex.value);
  50. Get.offAllNamed(RouteName.homeSaveUserInfo);
  51. } on GrpcError catch(e){
  52. if (e.code== StatusCode.unauthenticated){
  53. Get.snackbar('验证码错误', '请重新输入');
  54. }else{
  55. Get.snackbar('注册失败', e.message??'');
  56. }
  57. }catch(e){
  58. Get.snackbar('注册失败', e.toString());
  59. }finally {
  60. isSignUpEnable.value = true;
  61. }
  62. }
  63. }
  64. }
  65. class SignUpView extends GetView<SignUpController> {
  66. const SignUpView({super.key});
  67. static void show(){
  68. Get.to(const SignUpView(), binding: BindingsBuilder(() {
  69. Get.put(SignUpController());
  70. }));
  71. }
  72. @override
  73. Widget build(BuildContext context) {
  74. return Stack(
  75. children: [
  76. const SvgPicture(
  77. SvgAssetLoader('assets/images/bk_app.svg'),
  78. fit: BoxFit.fitHeight,
  79. height: double.infinity,
  80. width: double.infinity,
  81. ),
  82. Scaffold(
  83. backgroundColor: Colors.transparent,
  84. appBar: AppBar(
  85. backgroundColor: Colors.transparent,
  86. automaticallyImplyLeading: false,
  87. title: GestureDetector(
  88. onTap: () => Get.back(),
  89. child: Row(
  90. children: [
  91. const Icon(Icons.arrow_back_ios_new, color: Colors.white),
  92. Text(
  93. '返回',
  94. style: context.textTheme.titleMedium
  95. ?.copyWith(color: Colors.white),
  96. )
  97. ],
  98. )),
  99. ),
  100. body: SingleChildScrollView(
  101. child: SizedBox(
  102. // height: MediaQuery.of(context).size.height,
  103. child: Column(
  104. crossAxisAlignment: CrossAxisAlignment.center,
  105. children: [
  106. const LogoWidget(),
  107. Container(
  108. margin: const EdgeInsets.fromLTRB(40, 4, 40, 0),
  109. padding: const EdgeInsets.all(12),
  110. width: double.infinity,
  111. decoration: BoxDecoration(
  112. color: const Color(0x8fffffff),
  113. borderRadius: BorderRadius.circular(7)),
  114. child: Column(
  115. children: [
  116. TextFormField(
  117. decoration:
  118. const TextDecoration(hintText: '请输入手机号'),
  119. validator: (String? value) {
  120. if (value == null || !value.isPhoneNumber) {
  121. return '请输入正确的手机号';
  122. }
  123. return null;
  124. },
  125. onChanged: (value) {
  126. controller.phone = value;
  127. },
  128. keyboardType: TextInputType.phone),
  129. _columnSpace(),
  130. _textFieldCode(),
  131. _columnSpace(),
  132. TextFormField(
  133. decoration:
  134. const TextDecoration(hintText: '昵称'),
  135. onChanged: (value) {
  136. controller.name = value;
  137. },
  138. keyboardType: TextInputType.text),
  139. _columnSpace(),
  140. SignInButton(
  141. width: double.infinity,
  142. height: 46,
  143. onPressed: controller.onSignUp,
  144. color1: const Color(0xffe6ff00),
  145. color2: const Color(0xffffd500),
  146. child: Text(
  147. '注 册',
  148. style: context.textTheme.titleMedium
  149. ?.copyWith(color: const Color(0xff840000)),
  150. ))
  151. ],
  152. ),
  153. ),
  154. Padding(padding: MediaQuery.of(context).viewInsets),
  155. ],
  156. ),
  157. ),
  158. ))
  159. ],
  160. );
  161. }
  162. Widget _columnSpace() {
  163. return const SizedBox(height: 12);
  164. }
  165. Widget _textFieldCode() {
  166. return Stack(
  167. alignment: Alignment.centerRight,
  168. children: [
  169. TextFormField(
  170. decoration: const TextDecoration(
  171. hintText: '请输入验证码',
  172. ),
  173. onChanged: (value) {
  174. controller.code = value;
  175. },
  176. keyboardType: TextInputType.number,
  177. ),
  178. Padding(
  179. padding: const EdgeInsets.only(right: 4),
  180. child: SizedBox(
  181. width: 84,
  182. height: 37,
  183. child: Obx(() => GetCodeButton(
  184. codeRetryLeft: controller.codeRetryLeft.value,
  185. onPressed: () => controller.onGetCode(),
  186. )),
  187. ),
  188. ),
  189. ],
  190. );
  191. }
  192. }
  193. void main() {
  194. runApp(GetMaterialApp(
  195. theme: appThemeData(),
  196. initialBinding: BindingsBuilder(() {
  197. Get.put<SignUpController>(SignUpController());
  198. }),
  199. home: const SignUpView()));
  200. }