verify_code_dialog.dart 6.9 KB

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