Browse Source

忘记密码与忘记密码的验证页面

liukai 2 weeks ago
parent
commit
16dfd1372c
25 changed files with 1060 additions and 18 deletions
  1. 2 2
      packages/cpt_auth/lib/modules/auth_login/auth_login_page.dart
  2. 5 4
      packages/cpt_auth/lib/modules/auth_login/auth_login_view_model.dart
  3. 1 1
      packages/cpt_auth/lib/modules/auth_login/auth_login_view_model.g.dart
  4. 182 0
      packages/cpt_auth/lib/modules/forgot_input/forgot_input_page.dart
  5. 50 0
      packages/cpt_auth/lib/modules/forgot_input/forgot_input_state.dart
  6. 91 0
      packages/cpt_auth/lib/modules/forgot_input/forgot_input_view_model.dart
  7. 27 0
      packages/cpt_auth/lib/modules/forgot_input/forgot_input_view_model.g.dart
  8. 232 0
      packages/cpt_auth/lib/modules/forgot_verify/forgot_verify_page.dart
  9. 78 0
      packages/cpt_auth/lib/modules/forgot_verify/forgot_verify_state.dart
  10. 155 0
      packages/cpt_auth/lib/modules/forgot_verify/forgot_verify_view_model.dart
  11. 27 0
      packages/cpt_auth/lib/modules/forgot_verify/forgot_verify_view_model.g.dart
  12. 2 3
      packages/cpt_auth/lib/router/component/auth_component_service.dart
  13. 4 1
      packages/cpt_auth/lib/router/page/auth_page_router.dart
  14. 41 1
      packages/cpt_auth/lib/router/page/auth_page_router.gr.dart
  15. 3 1
      packages/cpt_main/lib/modules/home/page/home_page.dart
  16. 15 1
      packages/cs_resources/lib/generated/intl/messages_en.dart
  17. 10 1
      packages/cs_resources/lib/generated/intl/messages_zh_CN.dart
  18. 10 1
      packages/cs_resources/lib/generated/intl/messages_zh_HK.dart
  19. 90 0
      packages/cs_resources/lib/generated/l10n.dart
  20. 9 0
      packages/cs_resources/lib/l10n/intl_en.arb
  21. 9 0
      packages/cs_resources/lib/l10n/intl_zh_CN.arb
  22. 9 0
      packages/cs_resources/lib/l10n/intl_zh_HK.arb
  23. 2 2
      packages/cs_resources/lib/theme/app_colors_theme.dart
  24. 2 0
      packages/cs_router/lib/path/router_path.dart
  25. 4 0
      packages/cs_widgets/lib/my_text_field.dart

+ 2 - 2
packages/cpt_auth/lib/modules/auth_login/auth_login_page.dart

@@ -29,9 +29,9 @@ class AuthLoginPage extends HookConsumerWidget {
   //启动当前页面
   //启动当前页面
   static void startInstance({BuildContext? context}) {
   static void startInstance({BuildContext? context}) {
     if (context != null) {
     if (context != null) {
-      context.router.push(const AuthLoginPageRoute());
+      context.router.navigate(const AuthLoginPageRoute());
     } else {
     } else {
-      appRouter.push(const AuthLoginPageRoute());
+      appRouter.navigate(const AuthLoginPageRoute());
     }
     }
   }
   }
 
 

+ 5 - 4
packages/cpt_auth/lib/modules/auth_login/auth_login_view_model.dart

@@ -4,6 +4,7 @@ import 'package:riverpod_annotation/riverpod_annotation.dart';
 import 'package:shared/utils/log_utils.dart';
 import 'package:shared/utils/log_utils.dart';
 import 'package:shared/utils/util.dart';
 import 'package:shared/utils/util.dart';
 
 
+import '../forgot_input/forgot_input_page.dart';
 import 'auth_login_state.dart';
 import 'auth_login_state.dart';
 
 
 part 'auth_login_view_model.g.dart';
 part 'auth_login_view_model.g.dart';
@@ -44,13 +45,12 @@ class AuthLoginViewModel extends _$AuthLoginViewModel {
     Log.d('当前待提交的 账号:${account} password:${password}');
     Log.d('当前待提交的 账号:${account} password:${password}');
 
 
     if (Utils.isEmpty(account)) {
     if (Utils.isEmpty(account)) {
-      state = state.copyWith(accountErrorText: "The Phone/Email cannot be empty!");
+      state = state.copyWith(accountErrorText: "Phone/Email cannot be empty!");
       return;
       return;
     }
     }
 
 
     if (Utils.isEmpty(password)) {
     if (Utils.isEmpty(password)) {
-      state = state.copyWith(passwordErrorText: "The password cannot be empty!");
-      Log.d('The password cannot be empty!');
+      state = state.copyWith(passwordErrorText: "Password cannot be empty!");
       return;
       return;
     }
     }
 
 
@@ -65,7 +65,7 @@ class AuthLoginViewModel extends _$AuthLoginViewModel {
 
 
   //去忘记密码页面
   //去忘记密码页面
   void gotoForgotPage() {
   void gotoForgotPage() {
-    ToastEngine.show("去忘记密码页面");
+    ForgotInputPage.startInstance();
   }
   }
 
 
   //去注册页面
   //去注册页面
@@ -124,6 +124,7 @@ class AuthLoginViewModel extends _$AuthLoginViewModel {
     passwordFocusNode.dispose();
     passwordFocusNode.dispose();
     accountController.dispose();
     accountController.dispose();
     passwordController.dispose();
     passwordController.dispose();
+    Log.d("LoginViewModel 销毁 onDispose");
   }
   }
 
 
 }
 }

+ 1 - 1
packages/cpt_auth/lib/modules/auth_login/auth_login_view_model.g.dart

@@ -7,7 +7,7 @@ part of 'auth_login_view_model.dart';
 // **************************************************************************
 // **************************************************************************
 
 
 String _$authLoginViewModelHash() =>
 String _$authLoginViewModelHash() =>
-    r'1ff8058ae78c878e2ab15e300ecf0d0457e73589';
+    r'1556a80c857673abab8a1062452673469ca2aa1e';
 
 
 /// See also [AuthLoginViewModel].
 /// See also [AuthLoginViewModel].
 @ProviderFor(AuthLoginViewModel)
 @ProviderFor(AuthLoginViewModel)

+ 182 - 0
packages/cpt_auth/lib/modules/forgot_input/forgot_input_page.dart

@@ -0,0 +1,182 @@
+import 'package:cpt_auth/modules/auth_login/auth_login_page.dart';
+import 'package:cs_resources/generated/assets.dart';
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:flutter/material.dart';
+import 'package:auto_route/auto_route.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:router/ext/auto_router_extensions.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_appbar.dart';
+import 'package:widgets/my_button.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/my_text_field.dart';
+import 'package:widgets/my_text_view.dart';
+import 'package:widgets/widget_export.dart';
+
+import '../../router/page/auth_page_router.dart';
+import 'forgot_input_state.dart';
+import 'forgot_input_view_model.dart';
+
+@RoutePage()
+class ForgotInputPage extends HookConsumerWidget {
+  const ForgotInputPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const ForgotInputPageRoute());
+    } else {
+      appRouter.push(const ForgotInputPageRoute());
+    }
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final viewModel = ref.read(forgotInputViewModelProvider.notifier);
+    final state = ref.watch(forgotInputViewModelProvider);
+
+    return Scaffold(
+      appBar: MyAppBar.appBar(context, ""),
+      backgroundColor: context.appColors.backgroundDefault,
+      body: SingleChildScrollView(
+        scrollDirection: Axis.vertical,
+        physics: const BouncingScrollPhysics(),
+        child: Container(
+          margin: const EdgeInsets.symmetric(horizontal: 38),
+          width: double.infinity,
+          child: Column(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              //顶部图片
+              const MyAssetImage(
+                Assets.authForgotInputEmailPhoneImg,
+                width: 260,
+                height: 170,
+              ).marginOnly(top: 25, bottom: 29),
+
+              //提示文本
+              MyTextView(
+                S.current.forgot_text,
+                fontSize: 24,
+                marginBottom: 23,
+                isFontMedium: true,
+                textColor: context.appColors.textBlack,
+              ),
+
+              //邮箱输入框
+              _buildInputLayout(
+                context,
+                state,
+                "email",
+                textInputType: TextInputType.emailAddress,
+                textInputAction: TextInputAction.next,
+                errorText: state.emailErrorText,
+                onSubmit: (formKey, value) {
+                  state.formData[formKey]!['focusNode'].unfocus();
+                  FocusScope.of(context).requestFocus(state.formData['phone']!['focusNode']);
+                },
+              ),
+
+              //电话号码
+              Row(
+                mainAxisSize: MainAxisSize.max,
+                crossAxisAlignment: CrossAxisAlignment.center,
+                children: [
+                  const MyAssetImage(
+                    Assets.authCountrySg,
+                    width: 45,
+                    height: 30,
+                  ),
+                  MyTextView(
+                    "+65",
+                    textColor: context.appColors.textBlack,
+                    fontSize: 20,
+                    marginLeft: 15,
+                    marginRight: 12,
+                    isFontMedium: true,
+                  ),
+                  //电话输入框
+                  _buildInputLayout(
+                    context,
+                    state,
+                    "phone",
+                    textInputType: TextInputType.number,
+                    textInputAction: TextInputAction.done,
+                    errorText: state.phoneErrorText,
+                    onSubmit: (formKey, value) {
+                      state.formData[formKey]!['focusNode'].unfocus();
+                      viewModel.submitInput();
+                    },
+                  ).expanded(),
+                ],
+              ).marginOnly(top: 15),
+
+              MyButton(
+                onPressed: viewModel.submitInput,
+                text: S.current.next,
+                textColor: Colors.white,
+                backgroundColor: context.appColors.btnBgDefault,
+                fontWeight: FontWeight.w500,
+                type: ClickType.throttle,
+                fontSize: 16,
+                minHeight: 50,
+                radius: 5,
+              ).marginOnly(top: 25, bottom: 30),
+            ],
+          ),
+        ),
+      ),
+    );
+  }
+
+  /// 输入框
+  Widget _buildInputLayout(
+    BuildContext context,
+    ForgotInputState state,
+    String key, {
+    double marginTop = 0,
+    bool? showRightIcon = false, //是否展示右侧的布局
+    Widget? rightWidget, //右侧的布局
+    TextInputType textInputType = TextInputType.text,
+    String? errorText,
+    bool obscureText = false,
+    TextInputAction textInputAction = TextInputAction.done,
+    Function? onSubmit,
+  }) {
+    return IgnoreKeyboardDismiss(
+      child: MyTextField(
+        key,
+        fillBackgroundColor: context.appColors.authFiledBG,
+        state.formData[key]!['value'],
+        hintText: state.formData[key]!['hintText'],
+        hintStyle: TextStyle(
+          color: context.appColors.authFiledHint,
+          fontSize: 16.0,
+          fontWeight: FontWeight.w500,
+        ),
+        controller: state.formData[key]!['controller'],
+        focusNode: state.formData[key]!['focusNode'],
+        margin: EdgeInsets.only(top: marginTop),
+        padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 3),
+        showDivider: false,
+        height: 44,
+        style: TextStyle(
+          color: context.appColors.authFiledText,
+          fontSize: 16.0,
+          fontWeight: FontWeight.w500,
+        ),
+        inputType: textInputType,
+        textInputAction: textInputAction,
+        onSubmit: onSubmit,
+        cursorColor: context.appColors.authFiledText,
+        obscureText: obscureText,
+        errorText: errorText,
+        showLeftIcon: true,
+        showRightIcon: showRightIcon,
+        rightWidget: rightWidget,
+      ),
+    );
+  }
+}

+ 50 - 0
packages/cpt_auth/lib/modules/forgot_input/forgot_input_state.dart

@@ -0,0 +1,50 @@
+/*
+ * 登录的状态类
+ */
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:flutter/material.dart';
+
+class ForgotInputState {
+  //表单的校验与数据
+  final Map<String, Map<String, dynamic>> formData;
+
+  //表单的错误信息展示
+  String? emailErrorText;
+  String? phoneErrorText;
+
+
+  // ===================================  Begin  ↓  ===================================
+
+  ForgotInputState({
+    Map<String, Map<String, dynamic>>? formData,
+    this.emailErrorText,
+    this.phoneErrorText,
+  }) : formData = formData ??
+      {
+        'email': {
+          'value': '',
+          'controller': TextEditingController(),
+          'hintText': S.current.email,
+          'focusNode': FocusNode(),
+          'obsecure': false,
+        },
+        'phone': {
+          'value': '',
+          'controller': TextEditingController(),
+          'hintText': S.current.mobile_phone,
+          'focusNode': FocusNode(),
+          'obsecure': false,
+        },
+      };
+
+  ForgotInputState copyWith({
+    String? emailErrorText,
+    String? phoneErrorText,
+  }) {
+    return ForgotInputState(
+      formData: this.formData,
+      emailErrorText: emailErrorText,
+      phoneErrorText: phoneErrorText,
+    );
+  }
+}

+ 91 - 0
packages/cpt_auth/lib/modules/forgot_input/forgot_input_view_model.dart

@@ -0,0 +1,91 @@
+import 'package:cpt_auth/modules/forgot_verify/forgot_verify_page.dart';
+import 'package:flutter/material.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:shared/utils/util.dart';
+
+import 'forgot_input_state.dart';
+
+part 'forgot_input_view_model.g.dart';
+
+@riverpod
+class ForgotInputViewModel extends _$ForgotInputViewModel {
+  @override
+  ForgotInputState build() {
+    final state = ForgotInputState();
+    initListener(state);
+    ref.onDispose(() {
+      onDispose(state);
+    });
+    return state;
+  }
+
+  //提交忘记密码表单,发送验证码
+  void submitInput() {
+    state = state.copyWith(emailErrorText: null, phoneErrorText: null);
+
+    final FocusNode emailFocusNode = state.formData['email']!['focusNode'];
+    final FocusNode phoneFocusNode = state.formData['phone']!['focusNode'];
+    final TextEditingController emailController = state.formData['email']!['controller'];
+    final TextEditingController phoneController = state.formData['phone']!['controller'];
+
+    emailFocusNode.unfocus();
+    phoneFocusNode.unfocus();
+
+    final email = emailController.text;
+    final phone = phoneController.text;
+
+    Log.d('当前待提交的 邮箱:${email} 电话:${phone}');
+
+    // if (Utils.isEmpty(email)) {
+    //   state = state.copyWith(emailErrorText: "Email cannot be empty!");
+    //   return;
+    // }
+    //
+    // if (Utils.isEmpty(phone)) {
+    //   state = state.copyWith(phoneErrorText: "Phone cannot be empty!");
+    //   return;
+    // }
+
+    //执行密码登录
+    ToastEngine.show('准备执行请求发送验证码 邮箱:${email} 电话:${phone}');
+
+    gotoForgotVerifyPage();
+  }
+
+  //去忘记密码验证页面
+  void gotoForgotVerifyPage() {
+    ForgotVerifyPage.startInstance();
+  }
+
+  //初始化监听
+  void initListener(ForgotInputState initState) {
+    final FocusNode emailFocusNode = initState.formData['email']!['focusNode'];
+    final FocusNode phoneFocusNode = initState.formData['phone']!['focusNode'];
+
+    emailFocusNode.addListener(() {
+      // 获取焦点的时候清空错误文本
+      if (emailFocusNode.hasFocus) {
+        state = state.copyWith(emailErrorText: null);
+      }
+    });
+
+    phoneFocusNode.addListener(() {
+      // 获取焦点的时候清空错误文本
+      if (phoneFocusNode.hasFocus) {
+        state = state.copyWith(phoneErrorText: null);
+      }
+    });
+  }
+
+  //销毁资源
+  void onDispose(ForgotInputState initState) {
+    final FocusNode emailFocusNode = initState.formData['email']!['focusNode'];
+    final FocusNode phoneFocusNode = initState.formData['phone']!['focusNode'];
+    emailFocusNode.dispose();
+    phoneFocusNode.dispose();
+    Log.d("ForgotInputViewModel 销毁 onDispose");
+  }
+
+}

+ 27 - 0
packages/cpt_auth/lib/modules/forgot_input/forgot_input_view_model.g.dart

@@ -0,0 +1,27 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'forgot_input_view_model.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$forgotInputViewModelHash() =>
+    r'bb02a71836308ecaf111114fba9d1cdbd5396275';
+
+/// See also [ForgotInputViewModel].
+@ProviderFor(ForgotInputViewModel)
+final forgotInputViewModelProvider = AutoDisposeNotifierProvider<
+    ForgotInputViewModel, ForgotInputState>.internal(
+  ForgotInputViewModel.new,
+  name: r'forgotInputViewModelProvider',
+  debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+      ? null
+      : _$forgotInputViewModelHash,
+  dependencies: null,
+  allTransitiveDependencies: null,
+);
+
+typedef _$ForgotInputViewModel = AutoDisposeNotifier<ForgotInputState>;
+// ignore_for_file: type=lint
+// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package

+ 232 - 0
packages/cpt_auth/lib/modules/forgot_verify/forgot_verify_page.dart

@@ -0,0 +1,232 @@
+import 'package:cpt_auth/modules/forgot_verify/forgot_verify_state.dart';
+import 'package:cs_resources/generated/assets.dart';
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:flutter/material.dart';
+import 'package:auto_route/auto_route.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:router/ext/auto_router_extensions.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_appbar.dart';
+import 'package:widgets/my_button.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/my_text_field.dart';
+import 'package:widgets/my_text_view.dart';
+import 'package:widgets/widget_export.dart';
+
+import '../../router/page/auth_page_router.dart';
+import 'forgot_verify_view_model.dart';
+
+@RoutePage()
+class ForgotVerifyPage extends HookConsumerWidget {
+  const ForgotVerifyPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const ForgotVerifyPageRoute());
+    } else {
+      appRouter.push(const ForgotVerifyPageRoute());
+    }
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final viewModel = ref.read(forgotVerifyViewModelProvider.notifier);
+    final state = ref.watch(forgotVerifyViewModelProvider);
+
+    return Scaffold(
+      appBar: MyAppBar.appBar(context, ""),
+      backgroundColor: context.appColors.backgroundDefault,
+      body: SingleChildScrollView(
+        scrollDirection: Axis.vertical,
+        physics: const BouncingScrollPhysics(),
+        child: Container(
+          margin: const EdgeInsets.symmetric(horizontal: 38),
+          width: double.infinity,
+          child: Column(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              //顶部图片
+              const MyAssetImage(
+                Assets.authForgotResetPasswordImg,
+                width: 260,
+                height: 170,
+              ).marginOnly(top: 25, bottom: 29),
+
+              //提示文本
+              MyTextView(
+                S.current.mobile_phone,
+                fontSize: 15,
+                marginBottom: 23,
+                isFontMedium: true,
+                textColor: context.appColors.textBlack,
+              ),
+
+              MyTextView(
+                "+65 88249621",
+                fontSize: 23,
+                marginBottom: 23,
+                isFontMedium: true,
+                textColor: context.appColors.textBlack,
+              ),
+
+              // 表单 - 验证码
+              _buildInputLayout(
+                context,
+                state,
+                "code",
+                textInputType: TextInputType.number,
+                textInputAction: TextInputAction.next,
+                errorText: state.codeErrorText,
+                showRightIcon: true,
+                rightWidget: MyTextView(
+                  state.isCounting? "${state.countdownTime} s": S.current.get_code,
+                  textAlign: TextAlign.center,
+                  textColor: context.appColors.textPrimary,
+                  fontSize: 15,
+                  paddingRight: 5,
+                  isFontMedium: true,
+                  onClick: state.isCounting ? null : () => viewModel.showVerifyCodedDialog(),
+                ).paddingOnly(top: 15, bottom: 15),
+                onSubmit: (formKey, value) {
+                  state.formData[formKey]!['focusNode'].unfocus();
+                  FocusScope.of(context).requestFocus(state.formData['password']!['focusNode']);
+                },
+              ),
+
+              // 表单 - 重置密码
+              _buildInputLayout(
+                context,
+                state,
+                "password",
+                marginTop: 15,
+                obscureText: !state.pwdVisibility,
+                errorText: state.passwordErrorText,
+                textInputAction: TextInputAction.next,
+                showRightIcon: true,
+                rightWidget: IconButton(
+                  highlightColor: Colors.transparent,
+                  splashColor: Colors.transparent,
+                  icon: state.pwdVisibility
+                      ? const MyAssetImage(
+                          Assets.authPasswordHide,
+                          width: 22.5,
+                          height: 16.5,
+                        )
+                      : const MyAssetImage(
+                          Assets.authPasswordShow,
+                          width: 22.5,
+                          height: 16.5,
+                        ),
+                  onPressed: () {
+                    viewModel.switchPwdVisibility();
+                  },
+                ),
+                onSubmit: (formKey, value) {
+                  state.formData[formKey]!['focusNode'].unfocus();
+                  FocusScope.of(context).requestFocus(state.formData['confirm_password']!['focusNode']);
+                },
+              ),
+
+              // 表单 - 确认密码
+              _buildInputLayout(
+                context,
+                state,
+                "confirm_password",
+                marginTop: 15,
+                obscureText: !state.confirmPwdVisibility,
+                errorText: state.confirmPasswordErrorText,
+                showRightIcon: true,
+                rightWidget: IconButton(
+                  highlightColor: Colors.transparent,
+                  splashColor: Colors.transparent,
+                  icon: state.confirmPwdVisibility
+                      ? const MyAssetImage(
+                          Assets.authPasswordHide,
+                          width: 22.5,
+                          height: 16.5,
+                        )
+                      : const MyAssetImage(
+                          Assets.authPasswordShow,
+                          width: 22.5,
+                          height: 16.5,
+                        ),
+                  onPressed: () {
+                    viewModel.switchConfirmPwdVisibility();
+                  },
+                ),
+                onSubmit: (formKey, value) {
+                  state.formData[formKey]!['focusNode'].unfocus();
+                  viewModel.submitVerify();
+                },
+              ),
+
+              MyButton(
+                onPressed: viewModel.submitVerify,
+                text: S.current.next,
+                textColor: Colors.white,
+                backgroundColor: context.appColors.btnBgDefault,
+                fontWeight: FontWeight.w500,
+                type: ClickType.throttle,
+                fontSize: 16,
+                minHeight: 50,
+                radius: 5,
+              ).marginOnly(top: 25, bottom: 30),
+            ],
+          ),
+        ),
+      ),
+    );
+  }
+
+  /// 输入框
+  Widget _buildInputLayout(
+    BuildContext context,
+    ForgotVerifyState state,
+    String key, {
+    double marginTop = 0,
+    bool? showRightIcon = false, //是否展示右侧的布局
+    Widget? rightWidget, //右侧的布局
+    TextInputType textInputType = TextInputType.text,
+    String? errorText,
+    bool obscureText = false,
+    TextInputAction textInputAction = TextInputAction.done,
+    Function? onSubmit,
+  }) {
+    return IgnoreKeyboardDismiss(
+      child: MyTextField(
+        key,
+        fillBackgroundColor: context.appColors.authFiledBG,
+        state.formData[key]!['value'],
+        hintText: state.formData[key]!['hintText'],
+        hintStyle: TextStyle(
+          color: context.appColors.authFiledHint,
+          fontSize: 16.0,
+          fontWeight: FontWeight.w500,
+        ),
+        controller: state.formData[key]!['controller'],
+        focusNode: state.formData[key]!['focusNode'],
+        margin: EdgeInsets.only(top: marginTop),
+        padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 3),
+        showDivider: false,
+        height: 44,
+        style: TextStyle(
+          color: context.appColors.authFiledText,
+          fontSize: 16.0,
+          fontWeight: FontWeight.w500,
+        ),
+        inputType: textInputType,
+        textInputAction: textInputAction,
+        onSubmit: onSubmit,
+        cursorColor: context.appColors.authFiledText,
+        obscureText: obscureText,
+        errorText: errorText,
+        showLeftIcon: true,
+        showRightIcon: showRightIcon,
+        rightWidget: rightWidget,
+      ),
+    );
+  }
+}

+ 78 - 0
packages/cpt_auth/lib/modules/forgot_verify/forgot_verify_state.dart

@@ -0,0 +1,78 @@
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:flutter/material.dart';
+
+class ForgotVerifyState {
+//表单的校验与数据
+  final Map<String, Map<String, dynamic>> formData;
+
+  //表单的错误信息展示
+  String? codeErrorText;
+  String? passwordErrorText;
+  String? confirmPasswordErrorText;
+
+  //是否明文展示密码
+  bool pwdVisibility;
+
+  bool confirmPwdVisibility;
+
+  //获取验证码的倒计时
+  bool isCounting;
+  int countdownTime;
+
+  // ===================================  Begin  ↓  ===================================
+
+  ForgotVerifyState({
+    Map<String, Map<String, dynamic>>? formData,
+    this.pwdVisibility = false,
+    this.confirmPwdVisibility = false,
+    this.isCounting = false,
+    this.countdownTime = 0,
+    this.codeErrorText,
+    this.passwordErrorText,
+    this.confirmPasswordErrorText,
+  }) : formData = formData ??
+            {
+              'code': {
+                'value': '',
+                'controller': TextEditingController(),
+                'hintText': S.current.verification_code,
+                'focusNode': FocusNode(),
+                'obsecure': false,
+              },
+              'password': {
+                'value': '',
+                'controller': TextEditingController(),
+                'hintText': S.current.reset_password,
+                'focusNode': FocusNode(),
+                'obsecure': true,
+              },
+              'confirm_password': {
+                'value': '',
+                'controller': TextEditingController(),
+                'hintText': S.current.confirm_password,
+                'focusNode': FocusNode(),
+                'obsecure': true,
+              },
+            };
+
+  ForgotVerifyState copyWith({
+    String? codeErrorText,
+    String? passwordErrorText,
+    String? confirmPasswordErrorText,
+    bool? pwdVisibility,
+    bool? confirmPwdVisibility,
+    bool? isCounting,
+    int? countdownTime,
+  }) {
+    return ForgotVerifyState(
+      formData: this.formData,
+      pwdVisibility: pwdVisibility ?? this.pwdVisibility,
+      confirmPwdVisibility: confirmPwdVisibility ?? this.confirmPwdVisibility,
+      isCounting: isCounting ?? this.isCounting,
+      countdownTime: countdownTime ?? this.countdownTime,
+      codeErrorText: codeErrorText,
+      passwordErrorText: passwordErrorText,
+      confirmPasswordErrorText: confirmPasswordErrorText,
+    );
+  }
+}

+ 155 - 0
packages/cpt_auth/lib/modules/forgot_verify/forgot_verify_view_model.dart

@@ -0,0 +1,155 @@
+import 'dart:async';
+
+import 'package:flutter/material.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:shared/utils/util.dart';
+
+import '../auth_login/auth_login_page.dart';
+import 'forgot_verify_state.dart';
+
+part 'forgot_verify_view_model.g.dart';
+
+@riverpod
+class ForgotVerifyViewModel extends _$ForgotVerifyViewModel {
+  @override
+  ForgotVerifyState build() {
+    final state = ForgotVerifyState();
+    initListener(state);
+    ref.onDispose(() {
+      onDispose(state);
+    });
+    return state;
+  }
+
+  //提交重置密码的校验
+  void submitVerify() {
+    state = state.copyWith(codeErrorText: null, passwordErrorText: null, confirmPasswordErrorText: null);
+
+    final FocusNode codeFocusNode = state.formData['code']!['focusNode'];
+    final FocusNode passwordFocusNode = state.formData['password']!['focusNode'];
+    final FocusNode confirmPasswordFocusNode = state.formData['confirm_password']!['focusNode'];
+
+    final TextEditingController codeController = state.formData['code']!['controller'];
+    final TextEditingController passwordController = state.formData['password']!['controller'];
+    final TextEditingController confirmPasswordController = state.formData['confirm_password']!['controller'];
+
+    codeFocusNode.unfocus();
+    passwordFocusNode.unfocus();
+    confirmPasswordFocusNode.unfocus();
+
+    final code = codeController.text;
+    final password = passwordController.text;
+    final confirmPassword = confirmPasswordController.text;
+
+    Log.d('当前待提交的 code:$code password:$password confirmPassword:$confirmPassword');
+
+    if (Utils.isEmpty(code)) {
+      state = state.copyWith(codeErrorText: "Verification Code cannot be empty!");
+      return;
+    }
+
+    if (Utils.isEmpty(password)) {
+      state = state.copyWith(passwordErrorText: "Password cannot be empty!");
+      return;
+    }
+
+    if (Utils.isEmpty(confirmPassword)) {
+      state = state.copyWith(confirmPasswordErrorText: "Confirm Password cannot be empty!");
+      return;
+    }
+
+    if (confirmPassword != password) {
+      state = state.copyWith(confirmPasswordErrorText: "Password mismatch, please check password");
+      return;
+    }
+
+    //执行密码登录
+    ToastEngine.show('准备执行请求发送验证码 code:$code password:$password confirmPassword:$confirmPassword');
+
+    gotoLoginPage();
+  }
+
+  //去登录页面
+  void gotoLoginPage() {
+    AuthLoginPage.startInstance();
+  }
+
+  //切换隐藏显示密码
+  void switchPwdVisibility() {
+    state = state.copyWith(pwdVisibility: !state.pwdVisibility);
+  }
+
+  void switchConfirmPwdVisibility() {
+    state = state.copyWith(confirmPwdVisibility: !state.confirmPwdVisibility);
+  }
+
+  // 验证弹窗
+  void showVerifyCodedDialog() {
+    _startCountDown();
+  }
+
+  Timer? countdownTimer;
+
+  /// 开启倒计时
+  void _startCountDown() {
+    //60秒倒计时
+    state = state.copyWith(isCounting: true, countdownTime: 60);
+
+    //每秒的倒计时
+    countdownTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
+      int time = state.countdownTime;
+      Log.d('倒计时-->$time');
+      if (time > 0) {
+        time--;
+        state = state.copyWith(isCounting: true, countdownTime: time);
+      } else {
+        state = state.copyWith(isCounting: false, countdownTime: 0);
+        countdownTimer?.cancel(); // 取消计时器
+      }
+    });
+  }
+
+  //初始化监听
+  void initListener(ForgotVerifyState initState) {
+    final FocusNode codeFocusNode = initState.formData['code']!['focusNode'];
+    final FocusNode passwordFocusNode = initState.formData['password']!['focusNode'];
+    final FocusNode confirmPasswordFocusNode = initState.formData['confirm_password']!['focusNode'];
+
+    codeFocusNode.addListener(() {
+      // 获取焦点的时候清空错误文本
+      if (codeFocusNode.hasFocus) {
+        state = state.copyWith(codeErrorText: null);
+      }
+    });
+
+    passwordFocusNode.addListener(() {
+      // 获取焦点的时候清空错误文本
+      if (passwordFocusNode.hasFocus) {
+        state = state.copyWith(passwordErrorText: null);
+      }
+    });
+
+    confirmPasswordFocusNode.addListener(() {
+      // 获取焦点的时候清空错误文本
+      if (confirmPasswordFocusNode.hasFocus) {
+        state = state.copyWith(confirmPasswordErrorText: null);
+      }
+    });
+  }
+
+  //销毁资源
+  void onDispose(ForgotVerifyState initState) {
+    final FocusNode codeFocusNode = initState.formData['code']!['focusNode'];
+    final FocusNode passwordFocusNode = initState.formData['password']!['focusNode'];
+    final FocusNode confirmPasswordFocusNode = initState.formData['confirm_password']!['focusNode'];
+    codeFocusNode.dispose();
+    passwordFocusNode.dispose();
+    confirmPasswordFocusNode.dispose();
+
+    countdownTimer?.cancel();
+
+    Log.d("ForgotVerifyViewModel 销毁 onDispose");
+  }
+}

+ 27 - 0
packages/cpt_auth/lib/modules/forgot_verify/forgot_verify_view_model.g.dart

@@ -0,0 +1,27 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'forgot_verify_view_model.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$forgotVerifyViewModelHash() =>
+    r'4ccebc971866331f140df84ccc403acd956f4f32';
+
+/// See also [ForgotVerifyViewModel].
+@ProviderFor(ForgotVerifyViewModel)
+final forgotVerifyViewModelProvider = AutoDisposeNotifierProvider<
+    ForgotVerifyViewModel, ForgotVerifyState>.internal(
+  ForgotVerifyViewModel.new,
+  name: r'forgotVerifyViewModelProvider',
+  debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+      ? null
+      : _$forgotVerifyViewModelHash,
+  dependencies: null,
+  allTransitiveDependencies: null,
+);
+
+typedef _$ForgotVerifyViewModel = AutoDisposeNotifier<ForgotVerifyState>;
+// ignore_for_file: type=lint
+// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package

+ 2 - 3
packages/cpt_auth/lib/router/component/auth_component_service.dart

@@ -1,6 +1,7 @@
 /*
 /*
  * Auth 组件的组件路由
  * Auth 组件的组件路由
  */
  */
+import 'package:cpt_auth/modules/forgot_input/forgot_input_page.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:router/componentRouter/auth_service.dart';
 import 'package:router/componentRouter/auth_service.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
@@ -17,7 +18,6 @@ AuthService authService(Ref ref) {
 }
 }
 
 
 class AuthComponentService extends AuthService {
 class AuthComponentService extends AuthService {
-
   @override
   @override
   void startLoginPage() {
   void startLoginPage() {
     AuthLoginPage.startInstance();
     AuthLoginPage.startInstance();
@@ -25,7 +25,6 @@ class AuthComponentService extends AuthService {
 
 
   @override
   @override
   void startResetPasswordPage() {
   void startResetPasswordPage() {
-
+    ForgotInputPage.startInstance();
   }
   }
-
 }
 }

+ 4 - 1
packages/cpt_auth/lib/router/page/auth_page_router.dart

@@ -4,6 +4,8 @@ import 'package:router/ext/auto_router_extensions.dart';
 import 'package:router/path/router_path.dart';
 import 'package:router/path/router_path.dart';
 
 
 import '../../modules/auth_login/auth_login_page.dart';
 import '../../modules/auth_login/auth_login_page.dart';
+import '../../modules/forgot_input/forgot_input_page.dart';
+import '../../modules/forgot_verify/forgot_verify_page.dart';
 
 
 
 
 
 
@@ -16,7 +18,8 @@ part 'auth_page_router.gr.dart';
 class AuthPageRouter extends _$AuthPageRouter {
 class AuthPageRouter extends _$AuthPageRouter {
   @override
   @override
   List<AutoRoute> get routes => [
   List<AutoRoute> get routes => [
-
     CustomRoute(page: AuthLoginPageRoute.page, path: RouterPath.authLogin, transitionsBuilder: applySlideTransition),
     CustomRoute(page: AuthLoginPageRoute.page, path: RouterPath.authLogin, transitionsBuilder: applySlideTransition),
+    CustomRoute(page: ForgotInputPageRoute.page, path: RouterPath.authForgotInput, transitionsBuilder: applySlideTransition),
+    CustomRoute(page: ForgotVerifyPageRoute.page, path: RouterPath.authForgotVerify, transitionsBuilder: applySlideTransition),
   ];
   ];
 }
 }

+ 41 - 1
packages/cpt_auth/lib/router/page/auth_page_router.gr.dart

@@ -20,7 +20,19 @@ abstract class _$AuthPageRouter extends RootStackRouter {
         routeData: routeData,
         routeData: routeData,
         child: const AuthLoginPage(),
         child: const AuthLoginPage(),
       );
       );
-    }
+    },
+    ForgotInputPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const ForgotInputPage(),
+      );
+    },
+    ForgotVerifyPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const ForgotVerifyPage(),
+      );
+    },
   };
   };
 }
 }
 
 
@@ -37,3 +49,31 @@ class AuthLoginPageRoute extends PageRouteInfo<void> {
 
 
   static const PageInfo<void> page = PageInfo<void>(name);
   static const PageInfo<void> page = PageInfo<void>(name);
 }
 }
+
+/// generated route for
+/// [ForgotInputPage]
+class ForgotInputPageRoute extends PageRouteInfo<void> {
+  const ForgotInputPageRoute({List<PageRouteInfo>? children})
+      : super(
+          ForgotInputPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'ForgotInputPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
+/// [ForgotVerifyPage]
+class ForgotVerifyPageRoute extends PageRouteInfo<void> {
+  const ForgotVerifyPageRoute({List<PageRouteInfo>? children})
+      : super(
+          ForgotVerifyPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'ForgotVerifyPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}

+ 3 - 1
packages/cpt_main/lib/modules/home/page/home_page.dart

@@ -95,7 +95,9 @@ class HomePage extends HookConsumerWidget {
                   child: Text('Login'),
                   child: Text('Login'),
                 ),
                 ),
                 ElevatedButton(
                 ElevatedButton(
-                  onPressed: () {},
+                  onPressed: () {
+                    ComponentServiceManager().authService.startResetPasswordPage();
+                  },
                   child: Text('Forgot'),
                   child: Text('Forgot'),
                 ),
                 ),
                 ElevatedButton(
                 ElevatedButton(

+ 15 - 1
packages/cs_resources/lib/generated/intl/messages_en.dart

@@ -23,21 +23,35 @@ class MessageLookup extends MessageLookupByLibrary {
   final messages = _notInlinedMessages(_notInlinedMessages);
   final messages = _notInlinedMessages(_notInlinedMessages);
   static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
   static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
         "agree_to": MessageLookupByLibrary.simpleMessage("Agree to"),
         "agree_to": MessageLookupByLibrary.simpleMessage("Agree to"),
+        "confirm_password":
+            MessageLookupByLibrary.simpleMessage("Confirm Password"),
         "create_new_yy_home_account":
         "create_new_yy_home_account":
             MessageLookupByLibrary.simpleMessage("Create New YY Home Account"),
             MessageLookupByLibrary.simpleMessage("Create New YY Home Account"),
+        "email": MessageLookupByLibrary.simpleMessage("Email"),
         "facility": MessageLookupByLibrary.simpleMessage("Facility"),
         "facility": MessageLookupByLibrary.simpleMessage("Facility"),
         "forgot_password":
         "forgot_password":
             MessageLookupByLibrary.simpleMessage("Forgot Password?"),
             MessageLookupByLibrary.simpleMessage("Forgot Password?"),
+        "forgot_text": MessageLookupByLibrary.simpleMessage(
+            "Enter your email and mobile phone number"),
         "form": MessageLookupByLibrary.simpleMessage("Form"),
         "form": MessageLookupByLibrary.simpleMessage("Form"),
+        "get_code": MessageLookupByLibrary.simpleMessage("Get Code"),
         "login": MessageLookupByLibrary.simpleMessage("Log In"),
         "login": MessageLookupByLibrary.simpleMessage("Log In"),
+        "mobile_phone": MessageLookupByLibrary.simpleMessage("Mobile Phone"),
+        "next": MessageLookupByLibrary.simpleMessage("Next"),
         "notice_board": MessageLookupByLibrary.simpleMessage("Notice Board"),
         "notice_board": MessageLookupByLibrary.simpleMessage("Notice Board"),
         "notification": MessageLookupByLibrary.simpleMessage("Notification"),
         "notification": MessageLookupByLibrary.simpleMessage("Notification"),
         "other": MessageLookupByLibrary.simpleMessage("Other"),
         "other": MessageLookupByLibrary.simpleMessage("Other"),
         "password": MessageLookupByLibrary.simpleMessage("Password"),
         "password": MessageLookupByLibrary.simpleMessage("Password"),
+        "password_format":
+            MessageLookupByLibrary.simpleMessage("8 Digits Alphanumeric"),
         "payment": MessageLookupByLibrary.simpleMessage("Payment"),
         "payment": MessageLookupByLibrary.simpleMessage("Payment"),
         "phone_email": MessageLookupByLibrary.simpleMessage("Phone/Email"),
         "phone_email": MessageLookupByLibrary.simpleMessage("Phone/Email"),
+        "reset_password":
+            MessageLookupByLibrary.simpleMessage("Reset Password"),
         "rewards": MessageLookupByLibrary.simpleMessage("Rewards"),
         "rewards": MessageLookupByLibrary.simpleMessage("Rewards"),
         "terms_of_service":
         "terms_of_service":
-            MessageLookupByLibrary.simpleMessage("Terms of Service")
+            MessageLookupByLibrary.simpleMessage("Terms of Service"),
+        "verification_code":
+            MessageLookupByLibrary.simpleMessage("Verification Code")
       };
       };
 }
 }

+ 10 - 1
packages/cs_resources/lib/generated/intl/messages_zh_CN.dart

@@ -23,19 +23,28 @@ class MessageLookup extends MessageLookupByLibrary {
   final messages = _notInlinedMessages(_notInlinedMessages);
   final messages = _notInlinedMessages(_notInlinedMessages);
   static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
   static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
         "agree_to": MessageLookupByLibrary.simpleMessage("同意"),
         "agree_to": MessageLookupByLibrary.simpleMessage("同意"),
+        "confirm_password": MessageLookupByLibrary.simpleMessage("确认密码"),
         "create_new_yy_home_account":
         "create_new_yy_home_account":
             MessageLookupByLibrary.simpleMessage("创建新的 YY Home 账户"),
             MessageLookupByLibrary.simpleMessage("创建新的 YY Home 账户"),
+        "email": MessageLookupByLibrary.simpleMessage("邮箱"),
         "facility": MessageLookupByLibrary.simpleMessage("设施"),
         "facility": MessageLookupByLibrary.simpleMessage("设施"),
         "forgot_password": MessageLookupByLibrary.simpleMessage("忘记密码?"),
         "forgot_password": MessageLookupByLibrary.simpleMessage("忘记密码?"),
+        "forgot_text": MessageLookupByLibrary.simpleMessage("请输入您的邮箱和手机号码"),
         "form": MessageLookupByLibrary.simpleMessage("表单"),
         "form": MessageLookupByLibrary.simpleMessage("表单"),
+        "get_code": MessageLookupByLibrary.simpleMessage("获取验证码"),
         "login": MessageLookupByLibrary.simpleMessage("登录"),
         "login": MessageLookupByLibrary.simpleMessage("登录"),
+        "mobile_phone": MessageLookupByLibrary.simpleMessage("手机号码"),
+        "next": MessageLookupByLibrary.simpleMessage("下一步"),
         "notice_board": MessageLookupByLibrary.simpleMessage("消息板"),
         "notice_board": MessageLookupByLibrary.simpleMessage("消息板"),
         "notification": MessageLookupByLibrary.simpleMessage("通知"),
         "notification": MessageLookupByLibrary.simpleMessage("通知"),
         "other": MessageLookupByLibrary.simpleMessage("其他"),
         "other": MessageLookupByLibrary.simpleMessage("其他"),
         "password": MessageLookupByLibrary.simpleMessage("密码"),
         "password": MessageLookupByLibrary.simpleMessage("密码"),
+        "password_format": MessageLookupByLibrary.simpleMessage("8位数字或字母"),
         "payment": MessageLookupByLibrary.simpleMessage("支付"),
         "payment": MessageLookupByLibrary.simpleMessage("支付"),
         "phone_email": MessageLookupByLibrary.simpleMessage("电话或邮箱"),
         "phone_email": MessageLookupByLibrary.simpleMessage("电话或邮箱"),
+        "reset_password": MessageLookupByLibrary.simpleMessage("重置密码"),
         "rewards": MessageLookupByLibrary.simpleMessage("奖励"),
         "rewards": MessageLookupByLibrary.simpleMessage("奖励"),
-        "terms_of_service": MessageLookupByLibrary.simpleMessage("服务条款")
+        "terms_of_service": MessageLookupByLibrary.simpleMessage("服务条款"),
+        "verification_code": MessageLookupByLibrary.simpleMessage("验证码")
       };
       };
 }
 }

+ 10 - 1
packages/cs_resources/lib/generated/intl/messages_zh_HK.dart

@@ -23,19 +23,28 @@ class MessageLookup extends MessageLookupByLibrary {
   final messages = _notInlinedMessages(_notInlinedMessages);
   final messages = _notInlinedMessages(_notInlinedMessages);
   static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
   static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
         "agree_to": MessageLookupByLibrary.simpleMessage("同意"),
         "agree_to": MessageLookupByLibrary.simpleMessage("同意"),
+        "confirm_password": MessageLookupByLibrary.simpleMessage("确认密码"),
         "create_new_yy_home_account":
         "create_new_yy_home_account":
             MessageLookupByLibrary.simpleMessage("创建新的 YY Home 账户"),
             MessageLookupByLibrary.simpleMessage("创建新的 YY Home 账户"),
+        "email": MessageLookupByLibrary.simpleMessage("邮箱"),
         "facility": MessageLookupByLibrary.simpleMessage("設施"),
         "facility": MessageLookupByLibrary.simpleMessage("設施"),
         "forgot_password": MessageLookupByLibrary.simpleMessage("忘记密码?"),
         "forgot_password": MessageLookupByLibrary.simpleMessage("忘记密码?"),
+        "forgot_text": MessageLookupByLibrary.simpleMessage("请输入您的邮箱和手机号码"),
         "form": MessageLookupByLibrary.simpleMessage("表單"),
         "form": MessageLookupByLibrary.simpleMessage("表單"),
+        "get_code": MessageLookupByLibrary.simpleMessage("获取验证码"),
         "login": MessageLookupByLibrary.simpleMessage("登录"),
         "login": MessageLookupByLibrary.simpleMessage("登录"),
+        "mobile_phone": MessageLookupByLibrary.simpleMessage("手机号码"),
+        "next": MessageLookupByLibrary.simpleMessage("下一步"),
         "notice_board": MessageLookupByLibrary.simpleMessage("通知板"),
         "notice_board": MessageLookupByLibrary.simpleMessage("通知板"),
         "notification": MessageLookupByLibrary.simpleMessage("通知"),
         "notification": MessageLookupByLibrary.simpleMessage("通知"),
         "other": MessageLookupByLibrary.simpleMessage("其他"),
         "other": MessageLookupByLibrary.simpleMessage("其他"),
         "password": MessageLookupByLibrary.simpleMessage("密码"),
         "password": MessageLookupByLibrary.simpleMessage("密码"),
+        "password_format": MessageLookupByLibrary.simpleMessage("8位数字或字母"),
         "payment": MessageLookupByLibrary.simpleMessage("支付"),
         "payment": MessageLookupByLibrary.simpleMessage("支付"),
         "phone_email": MessageLookupByLibrary.simpleMessage("电话或邮箱"),
         "phone_email": MessageLookupByLibrary.simpleMessage("电话或邮箱"),
+        "reset_password": MessageLookupByLibrary.simpleMessage("重置密码"),
         "rewards": MessageLookupByLibrary.simpleMessage("獎勵"),
         "rewards": MessageLookupByLibrary.simpleMessage("獎勵"),
-        "terms_of_service": MessageLookupByLibrary.simpleMessage("服务条款")
+        "terms_of_service": MessageLookupByLibrary.simpleMessage("服务条款"),
+        "verification_code": MessageLookupByLibrary.simpleMessage("验证码")
       };
       };
 }
 }

+ 90 - 0
packages/cs_resources/lib/generated/l10n.dart

@@ -180,6 +180,96 @@ class S {
     );
     );
   }
   }
 
 
+  /// `Enter your email and mobile phone number`
+  String get forgot_text {
+    return Intl.message(
+      'Enter your email and mobile phone number',
+      name: 'forgot_text',
+      desc: '',
+      args: [],
+    );
+  }
+
+  /// `Email`
+  String get email {
+    return Intl.message(
+      'Email',
+      name: 'email',
+      desc: '',
+      args: [],
+    );
+  }
+
+  /// `Mobile Phone`
+  String get mobile_phone {
+    return Intl.message(
+      'Mobile Phone',
+      name: 'mobile_phone',
+      desc: '',
+      args: [],
+    );
+  }
+
+  /// `Next`
+  String get next {
+    return Intl.message(
+      'Next',
+      name: 'next',
+      desc: '',
+      args: [],
+    );
+  }
+
+  /// `Verification Code`
+  String get verification_code {
+    return Intl.message(
+      'Verification Code',
+      name: 'verification_code',
+      desc: '',
+      args: [],
+    );
+  }
+
+  /// `Reset Password`
+  String get reset_password {
+    return Intl.message(
+      'Reset Password',
+      name: 'reset_password',
+      desc: '',
+      args: [],
+    );
+  }
+
+  /// `Confirm Password`
+  String get confirm_password {
+    return Intl.message(
+      'Confirm Password',
+      name: 'confirm_password',
+      desc: '',
+      args: [],
+    );
+  }
+
+  /// `8 Digits Alphanumeric`
+  String get password_format {
+    return Intl.message(
+      '8 Digits Alphanumeric',
+      name: 'password_format',
+      desc: '',
+      args: [],
+    );
+  }
+
+  /// `Get Code`
+  String get get_code {
+    return Intl.message(
+      'Get Code',
+      name: 'get_code',
+      desc: '',
+      args: [],
+    );
+  }
+
   /// `Other`
   /// `Other`
   String get other {
   String get other {
     return Intl.message(
     return Intl.message(

+ 9 - 0
packages/cs_resources/lib/l10n/intl_en.arb

@@ -12,5 +12,14 @@
   "create_new_yy_home_account": "Create New YY Home Account",
   "create_new_yy_home_account": "Create New YY Home Account",
   "agree_to": "Agree to",
   "agree_to": "Agree to",
   "terms_of_service": "Terms of Service",
   "terms_of_service": "Terms of Service",
+  "forgot_text": "Enter your email and mobile phone number",
+  "email": "Email",
+  "mobile_phone": "Mobile Phone",
+  "next": "Next",
+  "verification_code": "Verification Code",
+  "reset_password": "Reset Password",
+  "confirm_password": "Confirm Password",
+  "password_format": "8 Digits Alphanumeric",
+  "get_code": "Get Code",
   "other": "Other"
   "other": "Other"
 }
 }

+ 9 - 0
packages/cs_resources/lib/l10n/intl_zh_CN.arb

@@ -12,5 +12,14 @@
   "create_new_yy_home_account": "创建新的 YY Home 账户",
   "create_new_yy_home_account": "创建新的 YY Home 账户",
   "agree_to": "同意",
   "agree_to": "同意",
   "terms_of_service": "服务条款",
   "terms_of_service": "服务条款",
+  "forgot_text": "请输入您的邮箱和手机号码",
+  "email": "邮箱",
+  "mobile_phone": "手机号码",
+  "next": "下一步",
+  "verification_code": "验证码",
+  "reset_password": "重置密码",
+  "confirm_password": "确认密码",
+  "password_format": "8位数字或字母",
+  "get_code": "获取验证码",
   "other": "其他"
   "other": "其他"
 }
 }

+ 9 - 0
packages/cs_resources/lib/l10n/intl_zh_HK.arb

@@ -12,5 +12,14 @@
   "create_new_yy_home_account": "创建新的 YY Home 账户",
   "create_new_yy_home_account": "创建新的 YY Home 账户",
   "agree_to": "同意",
   "agree_to": "同意",
   "terms_of_service": "服务条款",
   "terms_of_service": "服务条款",
+  "forgot_text": "请输入您的邮箱和手机号码",
+  "email": "邮箱",
+  "mobile_phone": "手机号码",
+  "next": "下一步",
+  "verification_code": "验证码",
+  "reset_password": "重置密码",
+  "confirm_password": "确认密码",
+  "password_format": "8位数字或字母",
+  "get_code": "获取验证码",
   "other": "其他"
   "other": "其他"
 }
 }

+ 2 - 2
packages/cs_resources/lib/theme/app_colors_theme.dart

@@ -12,7 +12,7 @@ extension AppColorsThemeExtensions on BuildContext {
 class AppColorsTheme extends ThemeExtension<AppColorsTheme> {
 class AppColorsTheme extends ThemeExtension<AppColorsTheme> {
   //亮色主题的自定义颜色值
   //亮色主题的自定义颜色值
   static const _colorPrimary = Color(0xFF4161D0); //主题色
   static const _colorPrimary = Color(0xFF4161D0); //主题色
-  static const _colorB0B0B0 = Color(0xFFB0B0B0);
+  static const _colorFCFCFC = Color(0xFFFCFCFC);
   static const _color6C6C6C = Color(0xFF6C6C6C);
   static const _color6C6C6C = Color(0xFF6C6C6C);
   static const _color666666 = Color(0xFF666666);
   static const _color666666 = Color(0xFF666666);
   static const _colorD7DBE7 = Color(0xffD7DBE7);
   static const _colorD7DBE7 = Color(0xffD7DBE7);
@@ -53,7 +53,7 @@ class AppColorsTheme extends ThemeExtension<AppColorsTheme> {
   // 浅色主题工厂方法
   // 浅色主题工厂方法
   factory AppColorsTheme.light() {
   factory AppColorsTheme.light() {
     return const AppColorsTheme._internal(
     return const AppColorsTheme._internal(
-      backgroundDefault: Colors.white,
+      backgroundDefault: _colorFCFCFC,
       btnBgDefault: _colorPrimary,
       btnBgDefault: _colorPrimary,
       searchFiledBorder: _colorD7DBE7,
       searchFiledBorder: _colorD7DBE7,
       authFiledHint: _colorBDBDBD,
       authFiledHint: _colorBDBDBD,

+ 2 - 0
packages/cs_router/lib/path/router_path.dart

@@ -6,6 +6,8 @@ class RouterPath {
 
 
   //用户
   //用户
   static const authLogin = '/auth/login'; //用户登录注册
   static const authLogin = '/auth/login'; //用户登录注册
+  static const authForgotInput = '/auth/forgot/input'; //忘记密码
+  static const authForgotVerify = '/auth/forgot/verify'; //忘记密码校验
   static const authSignUp = '/auth/signup'; //注册
   static const authSignUp = '/auth/signup'; //注册
   static const authResetPassword = '/auth/rest_psd'; //重置密码
   static const authResetPassword = '/auth/rest_psd'; //重置密码
 
 

+ 4 - 0
packages/cs_widgets/lib/my_text_field.dart

@@ -24,6 +24,8 @@ class MyTextField extends StatelessWidget {
   String? hintText;
   String? hintText;
   TextStyle? hintStyle;
   TextStyle? hintStyle;
   TextStyle? style;
   TextStyle? style;
+  final String? subHintText; //提示附文本
+  final TextStyle? subHintStyle;
   bool? autofocus;
   bool? autofocus;
   int? maxLines = 1;
   int? maxLines = 1;
   InputBorder? border;
   InputBorder? border;
@@ -65,6 +67,8 @@ class MyTextField extends StatelessWidget {
     this.cursorColor, // 光标颜色
     this.cursorColor, // 光标颜色
     this.hintText, //提示文本
     this.hintText, //提示文本
     this.hintStyle, //提示文本样式
     this.hintStyle, //提示文本样式
+    this.subHintText, // 新的子提示文本
+    this.subHintStyle, // 新的子提示文本样式
     this.style, //默认的文本样式
     this.style, //默认的文本样式
     this.autofocus = false, // 自动聚焦
     this.autofocus = false, // 自动聚焦
     this.maxLines = 1, //最多行数,高度与行数同步
     this.maxLines = 1, //最多行数,高度与行数同步