verify_code_dialog.dart 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. import 'package:cs_resources/generated/assets.dart';
  2. import 'package:cs_resources/generated/l10n.dart';
  3. import 'package:cs_resources/theme/app_colors_theme.dart';
  4. import 'package:domain/repository/auth_repository.dart';
  5. import 'package:flutter/material.dart';
  6. import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
  7. import 'package:plugin_basic/dialog/verify_code_view_model.dart';
  8. import 'package:widgets/ext/ex_widget.dart';
  9. import 'package:widgets/my_load_image.dart';
  10. import 'dart:ui';
  11. import 'package:flutter/cupertino.dart';
  12. import 'package:flutter/widgets.dart';
  13. import 'package:widgets/my_text_field.dart';
  14. import 'package:widgets/my_text_view.dart';
  15. import 'package:widgets/widget_export.dart';
  16. import 'package:flutter_hooks/flutter_hooks.dart';
  17. import 'package:hooks_riverpod/hooks_riverpod.dart';
  18. /*
  19. * 验证码校验弹窗,输入四位数的验证才能发送短信
  20. */
  21. class VerifyCodeDialog extends HookConsumerWidget {
  22. void Function(String? key, String? code) confirmAction;
  23. VerifyCodeDialog({
  24. required this.confirmAction,
  25. });
  26. @override
  27. Widget build(BuildContext context, WidgetRef ref) {
  28. // 使用 useState 来持久化 TextEditingController 和 FocusNode
  29. final viewModel = ref.watch(verifyCodeProvider.notifier);
  30. final state = ref.watch(verifyCodeProvider);
  31. useEffect(() {
  32. //赋值State的值
  33. Future.microtask(() {
  34. viewModel.fetchCode();
  35. });
  36. return () {
  37. };
  38. }, []);
  39. return Column(
  40. crossAxisAlignment: CrossAxisAlignment.center,
  41. mainAxisAlignment: MainAxisAlignment.center,
  42. children: [
  43. //Title (如果使用 Container 为最外层容器则默认为 match_parent 的效果,除非我们限制宽度和最大高度最小高度)
  44. Container(
  45. width: double.infinity,
  46. height: 55,
  47. decoration: BoxDecoration(
  48. color: context.appColors.btnBgDefault,
  49. borderRadius: const BorderRadius.only(
  50. topRight: Radius.circular(15),
  51. topLeft: Radius.circular(15),
  52. ),
  53. ),
  54. child: Row(
  55. children: [
  56. const SizedBox(width: 45),
  57. MyTextView(
  58. S.current.captcha,
  59. fontSize: 18,
  60. textAlign: TextAlign.center,
  61. isFontMedium: true,
  62. textColor: Colors.white,
  63. ).expanded(),
  64. const MyAssetImage(
  65. Assets.baseServiceDialogDeleteIcon,
  66. width: 25,
  67. height: 25.5,
  68. ).onTap(() {
  69. onCancel();
  70. }, padding: 10)
  71. ],
  72. ),
  73. ),
  74. Container(
  75. width: double.infinity,
  76. padding: const EdgeInsets.only(top: 40),
  77. decoration: BoxDecoration(
  78. color: context.appColors.whiteSecondBG,
  79. borderRadius: const BorderRadius.only(
  80. bottomLeft: Radius.circular(15),
  81. bottomRight: Radius.circular(15),
  82. ),
  83. ),
  84. child: Column(
  85. children: [
  86. //图片与输入框
  87. Row(
  88. mainAxisSize: MainAxisSize.max,
  89. children: [
  90. IgnoreKeyboardDismiss(
  91. child: MyTextField(
  92. 'code',
  93. "",
  94. enabled: true,
  95. fillCornerRadius: 1,
  96. padding: const EdgeInsets.symmetric(horizontal: 10),
  97. fillBackgroundColor: context.appColors.authFiledBG,
  98. border: InputBorder.none,
  99. showDivider: false,
  100. hintText: S.current.enter_captcha,
  101. hintStyle: TextStyle(
  102. color: context.appColors.authFiledHint,
  103. fontSize: 16,
  104. fontWeight: FontWeight.w500,
  105. ),
  106. controller: state.textEditingController,
  107. focusNode: state.focusNode,
  108. style: TextStyle(
  109. color: context.appColors.authFiledText,
  110. fontSize: 16,
  111. fontWeight: FontWeight.w500,
  112. ),
  113. height: 48,
  114. cursorWidth: 1.5,
  115. cursorColor: context.appColors.authFiledText,
  116. margin: const EdgeInsets.only(right: 5),
  117. onSubmit: (formKey, value) {
  118. state.focusNode.unfocus();
  119. confirmAction.call(state.key, state.textEditingController.text.toString());
  120. onCancel();
  121. },
  122. ),
  123. ).expanded(),
  124. //图片验证码
  125. MyLoadImage(
  126. state.imgFilePath,
  127. width: 100,
  128. height: 45,
  129. fit: BoxFit.fill,
  130. onClick: () {
  131. //刷新验证码
  132. viewModel.fetchCode();
  133. },
  134. ),
  135. ],
  136. ).marginOnly(left: 15, right: 15),
  137. //按钮获取验证码
  138. Row(
  139. children: [
  140. InkWell(
  141. onTap: () async {
  142. state.focusNode.unfocus();
  143. confirmAction.call(state.key, state.textEditingController.text.toString());
  144. onCancel();
  145. },
  146. child: MyTextView(
  147. S.current.get_verification_code,
  148. fontSize: 16,
  149. paddingTop: 13,
  150. paddingBottom: 13,
  151. isFontMedium: true,
  152. textAlign: TextAlign.center,
  153. textColor: Colors.white,
  154. backgroundColor: context.appColors.btnBgDefault,
  155. cornerRadius: 7,
  156. ),
  157. ).expanded(),
  158. ],
  159. ).marginOnly(bottom: 30, top: 28, left: 15, right: 15),
  160. ],
  161. ),
  162. ),
  163. ],
  164. ).constrained(width: 300)
  165. //跟随软键盘滚动,适配居中于剩余的空间
  166. .padding(bottom: MediaQuery.of(context).viewInsets.bottom);
  167. }
  168. //取消弹框
  169. void onCancel() async {
  170. SmartDialog.dismiss();
  171. }
  172. }