浏览代码

忘记密码。修改密码,修改手机号码

liukai 4 月之前
父节点
当前提交
a67407fefe
共有 23 个文件被更改,包括 458 次插入112 次删除
  1. 1 1
      app/lib/modules/splash/vm/splash_view_model.dart
  2. 1 1
      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. 5 18
      packages/cpt_auth/lib/modules/forgot_input/forgot_input_view_model.dart
  5. 14 9
      packages/cpt_auth/lib/modules/forgot_verify/forgot_verify_page.dart
  6. 69 8
      packages/cpt_auth/lib/modules/forgot_verify/forgot_verify_view_model.dart
  7. 8 8
      packages/cpt_auth/lib/modules/sing_up_success/sign_up_success_page.dart
  8. 1 1
      packages/cpt_auth/lib/modules/sing_up_verify/sign_up_verify_view_model.dart
  9. 1 1
      packages/cpt_auth/lib/modules/sing_up_verify/sign_up_verify_view_model.g.dart
  10. 33 5
      packages/cpt_auth/lib/router/page/auth_page_router.gr.dart
  11. 69 22
      packages/cpt_profile/lib/modules/change_mobile/change_mobile_view_model.dart
  12. 8 0
      packages/cpt_profile/lib/modules/profile_edit/Profile_edit_page.dart
  13. 10 17
      packages/cpt_profile/lib/modules/profile_edit/dialog/avatar_edit_dialog.dart
  14. 4 0
      packages/cpt_profile/lib/modules/profile_edit/profile_edit_state.dart
  15. 21 2
      packages/cpt_profile/lib/modules/profile_edit/profile_edit_view_model.dart
  16. 3 0
      packages/cpt_profile/lib/modules/reset_password/reset_password_page.dart
  17. 64 7
      packages/cpt_profile/lib/modules/reset_password/reset_password_view_model.dart
  18. 4 1
      packages/cs_domain/lib/constants/api_constants.dart
  19. 61 0
      packages/cs_domain/lib/repository/auth_repository.dart
  20. 63 0
      packages/cs_domain/lib/repository/profile_repository.dart
  21. 1 0
      packages/cs_plugin_basic/lib/dio_interceptors/interceptor_auth_dio.dart
  22. 10 4
      packages/cs_plugin_basic/lib/provider/user_config/user_config.dart
  23. 6 6
      packages/cs_plugin_basic/lib/provider/user_config/user_config_service.dart

+ 1 - 1
app/lib/modules/splash/vm/splash_view_model.dart

@@ -49,7 +49,7 @@ class SplashViewModel extends _$SplashViewModel {
 
     UserConfigService.getInstance();
 
-    if (UserConfigService.getState().haslogin == true) {
+    if (UserConfigService.getState().hasLogin == true) {
       Log.d("已经登录,去首页页面");
       ComponentServiceManager().mainService.startMainPage();
     } else {

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

@@ -67,7 +67,7 @@ class AuthLoginViewModel extends _$AuthLoginViewModel {
 
     //请求成功去首页
     if (result.isSuccess) {
-      UserConfigService.getInstance().setToken(result.data?.token);
+      UserConfigService.getInstance().setToken(token: result.data?.token, userName: result.data?.name);
       ComponentServiceManager().mainService.startMainPage();
     } else {
       ToastEngine.show(result.errorMsg ?? "UnKnow Error");

+ 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() =>
-    r'afff62eb84d983159db7ca8c4d7b1a9dde73ce08';
+    r'a3e88f9aa351b658190e033c598003af7c274212';
 
 /// See also [AuthLoginViewModel].
 @ProviderFor(AuthLoginViewModel)

+ 5 - 18
packages/cpt_auth/lib/modules/forgot_input/forgot_input_view_model.dart

@@ -38,25 +38,12 @@ class ForgotInputViewModel extends _$ForgotInputViewModel {
 
     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;
-    // }
+    if (Utils.isEmpty(phone)) {
+      state = state.copyWith(phoneErrorText: "Phone cannot be empty!");
+      return;
+    }
 
-    //执行密码登录
-    ToastEngine.show('准备执行请求发送验证码 邮箱:${email} 电话:${phone}');
-
-    gotoForgotVerifyPage();
-  }
-
-  //去忘记密码验证页面
-  void gotoForgotVerifyPage() {
-    ForgotVerifyPage.startInstance();
+    ForgotVerifyPage.startInstance(phone: phone);
   }
 
   //初始化监听

+ 14 - 9
packages/cpt_auth/lib/modules/forgot_verify/forgot_verify_page.dart

@@ -5,6 +5,7 @@ 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:plugin_basic/constants/app_constant.dart';
 import 'package:router/ext/auto_router_extensions.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_appbar.dart';
@@ -19,14 +20,16 @@ import 'forgot_verify_view_model.dart';
 
 @RoutePage()
 class ForgotVerifyPage extends HookConsumerWidget {
-  const ForgotVerifyPage({Key? key}) : super(key: key);
+  final String? phone;
+
+  const ForgotVerifyPage({Key? key, required this.phone}) : super(key: key);
 
   //启动当前页面
-  static void startInstance({BuildContext? context}) {
+  static void startInstance({BuildContext? context, required String? phone}) {
     if (context != null) {
-      context.router.push(const ForgotVerifyPageRoute());
+      context.router.push(ForgotVerifyPageRoute(phone: phone));
     } else {
-      appRouter.push(const ForgotVerifyPageRoute());
+      appRouter.push(ForgotVerifyPageRoute(phone: phone));
     }
   }
 
@@ -65,7 +68,7 @@ class ForgotVerifyPage extends HookConsumerWidget {
               ),
 
               MyTextView(
-                "+65 88249621",
+                "+${AppConstant.countryCode} ${phone ?? "-"}",
                 fontSize: 23,
                 marginBottom: 23,
                 isFontMedium: true,
@@ -82,13 +85,13 @@ class ForgotVerifyPage extends HookConsumerWidget {
                 errorText: state.codeErrorText,
                 showRightIcon: true,
                 rightWidget: MyTextView(
-                  state.isCounting? "${state.countdownTime} s": S.current.get_code,
+                  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(),
+                  onClick: state.isCounting ? null : () => viewModel.showVerifyCodedDialog(phone),
                 ).paddingOnly(top: 15, bottom: 15),
                 onSubmit: (formKey, value) {
                   state.formData[formKey]!['focusNode'].unfocus();
@@ -159,12 +162,14 @@ class ForgotVerifyPage extends HookConsumerWidget {
                 ),
                 onSubmit: (formKey, value) {
                   state.formData[formKey]!['focusNode'].unfocus();
-                  viewModel.submitVerify();
+                  viewModel.submitVerify(phone);
                 },
               ),
 
               MyButton(
-                onPressed: viewModel.submitVerify,
+                onPressed: (){
+                  viewModel.submitVerify(phone);
+                },
                 text: S.current.next,
                 textColor: Colors.white,
                 backgroundColor: context.appColors.btnBgDefault,

+ 69 - 8
packages/cpt_auth/lib/modules/forgot_verify/forgot_verify_view_model.dart

@@ -1,7 +1,14 @@
 import 'dart:async';
 
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:domain/repository/auth_repository.dart';
 import 'package:flutter/material.dart';
+import 'package:plugin_basic/constants/app_constant.dart';
+import 'package:plugin_basic/dialog/verify_code_dialog.dart';
+import 'package:plugin_platform/engine/dialog/dialog_engine.dart';
+import 'package:plugin_platform/engine/notify/notify_engine.dart';
 import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 import 'package:shared/utils/log_utils.dart';
 import 'package:shared/utils/util.dart';
@@ -12,21 +19,32 @@ import 'forgot_verify_state.dart';
 part 'forgot_verify_view_model.g.dart';
 
 @riverpod
-class ForgotVerifyViewModel extends _$ForgotVerifyViewModel {
+class ForgotVerifyViewModel extends _$ForgotVerifyViewModel with DioCancelableMixin {
+  late final AuthRepository _authRepository;
+
   @override
   ForgotVerifyState build() {
+    _authRepository = ref.read(authRepositoryProvider);
+
     final state = ForgotVerifyState();
     initListener(state);
-    ref.onDispose(() {
+
+    registerCancellation(callback: () {
       onDispose(state);
     });
+
     return state;
   }
 
   //提交重置密码的校验
-  void submitVerify() {
+  void submitVerify(String? phone) async {
     state = state.copyWith(codeErrorText: null, passwordErrorText: null, confirmPasswordErrorText: null);
 
+    if (Utils.isEmpty(phone)) {
+      ToastEngine.show("Mobile Phone Error");
+      return;
+    }
+
     final FocusNode codeFocusNode = state.formData['code']!['focusNode'];
     final FocusNode passwordFocusNode = state.formData['password']!['focusNode'];
     final FocusNode confirmPasswordFocusNode = state.formData['confirm_password']!['focusNode'];
@@ -66,9 +84,21 @@ class ForgotVerifyViewModel extends _$ForgotVerifyViewModel {
     }
 
     //执行密码登录
-    ToastEngine.show('准备执行请求发送验证码 code:$code password:$password confirmPassword:$confirmPassword');
-
-    gotoLoginPage();
+    final result = await _authRepository.forgotPassword(
+      smsCode: code,
+      countryCode: AppConstant.countryCode,
+      phone: phone,
+      password: password,
+      confirmPassword: confirmPassword,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      NotifyEngine.showSuccess(S.current.successful);
+      gotoLoginPage();
+    } else {
+      ToastEngine.show(result.errorMsg ?? "UnKnow Error");
+    }
   }
 
   //去登录页面
@@ -86,8 +116,39 @@ class ForgotVerifyViewModel extends _$ForgotVerifyViewModel {
   }
 
   // 验证弹窗
-  void showVerifyCodedDialog() {
-    _startCountDown();
+  showVerifyCodedDialog(String? phone) {
+    if (Utils.isEmpty(phone)) {
+      ToastEngine.show("Mobile Phone Error");
+      return;
+    }
+
+    DialogEngine.show(
+      onDismiss: () {},
+      widget: VerifyCodeDialog(
+        confirmAction: (key, code) {
+          //发送短信验证码
+          sendSMS(phone!, key, code);
+        },
+      ),
+    );
+  }
+
+  /// 调用接口发送短信验证码
+  void sendSMS(String phone, String? key, String? code) async {
+    final result = await _authRepository.sendSMS(
+      countryCode: AppConstant.countryCode,
+      phone: phone,
+      captchaKey: key,
+      captchaValue: code,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      NotifyEngine.showSuccess(S.current.send_sms_successful);
+      _startCountDown();
+    } else {
+      ToastEngine.show(result.errorMsg ?? "UnKnow Error");
+    }
   }
 
   Timer? countdownTimer;

+ 8 - 8
packages/cpt_auth/lib/modules/sing_up_success/sign_up_success_page.dart

@@ -5,6 +5,7 @@ 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:plugin_basic/provider/user_config/user_config_service.dart';
 import 'package:router/ext/auto_router_extensions.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_appbar.dart';
@@ -19,17 +20,17 @@ class SignUpSuccessPage extends HookConsumerWidget {
 
   //启动当前页面
   static void startInstance({BuildContext? context}) {
-    appRouter.pushAndPopUntil(
-      const SignUpSuccessPageRoute(),
-      predicate: (route) {
-        return route.settings.name == 'AuthLoginPageRoute';
-      },
-    );
+    if (context != null) {
+      context.router.popAndPush(const SignUpSuccessPageRoute());
+    } else {
+      appRouter.popAndPush(const SignUpSuccessPageRoute());
+    }
   }
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
     final viewModel = ref.watch(signUpSuccessViewModelProvider.notifier);
+    final userConfig = UserConfigService.getState(ref: ref);
 
     return Scaffold(
       appBar: MyAppBar.appBar(context, ""),
@@ -54,7 +55,7 @@ class SignUpSuccessPage extends HookConsumerWidget {
                     ).alignCenter().marginOnly(top: 12),
 
                     MyTextView(
-                      S.current.welcome_name("Huyu"),
+                      S.current.welcome_name(userConfig.userName ?? ""),
                       fontSize: 23,
                       marginTop: 30,
                       isFontMedium: true,
@@ -86,7 +87,6 @@ class SignUpSuccessPage extends HookConsumerWidget {
                     ),
                   ],
                 )).expanded(),
-
             MyButton(
               onPressed: viewModel.gotoSelectEstatePage,
               text: S.current.get_started,

+ 1 - 1
packages/cpt_auth/lib/modules/sing_up_verify/sign_up_verify_view_model.dart

@@ -61,7 +61,7 @@ class SignUpVerifyViewModel extends _$SignUpVerifyViewModel {
     if (result.isSuccess) {
       NotifyEngine.showSuccess(S.current.successful);
       //存入Token
-      UserConfigService.getInstance().setToken(result.data?.token);
+      UserConfigService.getInstance().setToken(token: result.data?.token, userName: result.data?.name);
       //去成功页面
       SignUpSuccessPage.startInstance();
     } else {

+ 1 - 1
packages/cpt_auth/lib/modules/sing_up_verify/sign_up_verify_view_model.g.dart

@@ -7,7 +7,7 @@ part of 'sign_up_verify_view_model.dart';
 // **************************************************************************
 
 String _$signUpVerifyViewModelHash() =>
-    r'853c61774b0353652744df67e42d7fefe16f41e7';
+    r'ad1cb9a410068dac7bf1311d777f3fe0baa1a938';
 
 /// See also [SignUpVerifyViewModel].
 @ProviderFor(SignUpVerifyViewModel)

+ 33 - 5
packages/cpt_auth/lib/router/page/auth_page_router.gr.dart

@@ -28,9 +28,13 @@ abstract class _$AuthPageRouter extends RootStackRouter {
       );
     },
     ForgotVerifyPageRoute.name: (routeData) {
+      final args = routeData.argsAs<ForgotVerifyPageRouteArgs>();
       return AutoRoutePage<dynamic>(
         routeData: routeData,
-        child: const ForgotVerifyPage(),
+        child: ForgotVerifyPage(
+          key: args.key,
+          phone: args.phone,
+        ),
       );
     },
     SelectEstatePageRoute.name: (routeData) {
@@ -125,16 +129,40 @@ class ForgotInputPageRoute extends PageRouteInfo<void> {
 
 /// generated route for
 /// [ForgotVerifyPage]
-class ForgotVerifyPageRoute extends PageRouteInfo<void> {
-  const ForgotVerifyPageRoute({List<PageRouteInfo>? children})
-      : super(
+class ForgotVerifyPageRoute extends PageRouteInfo<ForgotVerifyPageRouteArgs> {
+  ForgotVerifyPageRoute({
+    Key? key,
+    required String? phone,
+    List<PageRouteInfo>? children,
+  }) : super(
           ForgotVerifyPageRoute.name,
+          args: ForgotVerifyPageRouteArgs(
+            key: key,
+            phone: phone,
+          ),
           initialChildren: children,
         );
 
   static const String name = 'ForgotVerifyPageRoute';
 
-  static const PageInfo<void> page = PageInfo<void>(name);
+  static const PageInfo<ForgotVerifyPageRouteArgs> page =
+      PageInfo<ForgotVerifyPageRouteArgs>(name);
+}
+
+class ForgotVerifyPageRouteArgs {
+  const ForgotVerifyPageRouteArgs({
+    this.key,
+    required this.phone,
+  });
+
+  final Key? key;
+
+  final String? phone;
+
+  @override
+  String toString() {
+    return 'ForgotVerifyPageRouteArgs{key: $key, phone: $phone}';
+  }
 }
 
 /// generated route for

+ 69 - 22
packages/cpt_profile/lib/modules/change_mobile/change_mobile_view_model.dart

@@ -1,11 +1,19 @@
 import 'dart:async';
 
 import 'package:cpt_profile/modules/setting/setting_page.dart';
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:domain/repository/auth_repository.dart';
+import 'package:domain/repository/profile_repository.dart';
 import 'package:flutter/material.dart';
+import 'package:plugin_basic/constants/app_constant.dart';
 import 'package:plugin_basic/dialog/verify_code_dialog.dart';
+import 'package:plugin_basic/provider/user_config/user_config_service.dart';
 import 'package:plugin_platform/engine/dialog/dialog_engine.dart';
+import 'package:plugin_platform/engine/notify/notify_engine.dart';
 import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:router/componentRouter/component_service_manager.dart';
 import 'package:shared/utils/log_utils.dart';
 import 'package:shared/utils/util.dart';
 import 'package:widgets/widget_export.dart';
@@ -15,34 +23,38 @@ import 'change_mobile_state.dart';
 part 'change_mobile_view_model.g.dart';
 
 @riverpod
-class ChangeMobileViewModel extends _$ChangeMobileViewModel {
+class ChangeMobileViewModel extends _$ChangeMobileViewModel with DioCancelableMixin {
+  late final ProfileRepository _profileRepository;
+  late final AuthRepository _authRepository;
+
   @override
   ChangeMobileState build() {
+    _profileRepository = ref.read(profileRepositoryProvider);
+    _authRepository = ref.read(authRepositoryProvider);
+
     final state = ChangeMobileState();
     initListener(state);
-    ref.onDispose(() {
+
+    registerCancellation(callback: () {
       onDispose(state);
     });
+
     return state;
   }
 
   /// 提交表单修改电话号码
-  void submitChangeMobile() {
+  void submitChangeMobile() async {
     state = state.copyWith(oldCodeErrorText: null, newCodeErrorText: null);
 
-    final FocusNode oldMobileFocusNode = state.formData['old']!['focusNode'];
     final FocusNode newMobileFocusNode = state.formData['new']!['focusNode'];
     final FocusNode newCodeFocusNode = state.formData['new_code']!['focusNode'];
 
-    final TextEditingController oldMobileController = state.formData['old']!['controller'];
     final TextEditingController newMobileController = state.formData['new']!['controller'];
     final TextEditingController newCodeController = state.formData['new_code']!['controller'];
 
-    oldMobileFocusNode.unfocus();
     newMobileFocusNode.unfocus();
     newCodeFocusNode.unfocus();
 
-    final oldMobile = oldMobileController.text;
     final newMobile = newMobileController.text;
     final newCode = newCodeController.text;
 
@@ -59,36 +71,68 @@ class ChangeMobileViewModel extends _$ChangeMobileViewModel {
     }
 
     //执行密码登录
-    ToastEngine.show('准备执行请求发送验证码 newMobile:$newMobile newCode:$newCode');
+    final result = await _profileRepository.changeMobilePhone(
+      smsCode: newCode,
+      countryCode: AppConstant.countryCode,
+      phone: newMobile,
+      cancelToken: cancelToken,
+    );
 
-    //返回设置页面
-    SettingPage.startInstance();
+    if (result.isSuccess) {
+      //提示成功
+      NotifyEngine.showSuccess(S.current.successful);
+      //清除用户登录信息
+      UserConfigService.getInstance().handleLogoutParams();
+      //去登录页面
+      ComponentServiceManager().authService.startAndPopAllLoginPage();
+    } else {
+      ToastEngine.show(result.errorMsg ?? "UnKnow Error");
+    }
   }
 
   //展示发送验证码弹窗
-  showVerifyCodedDialog() {
-
-    //展示对应的验证码弹窗
-    _showCAPTCHADialog();
-  }
+  void showVerifyCodedDialog() {
+    final TextEditingController phoneController = state.formData['new']!['controller'];
+    final phone = phoneController.text;
+    if (Utils.isEmpty(phone)) {
+      ToastEngine.show("Mobile Phone Error");
+      return;
+    }
 
-  void _showCAPTCHADialog() {
+    //短信验证码之前的图片验证码弹窗
     DialogEngine.show(
-      onDismiss: () {
-      },
+      onDismiss: () {},
       widget: VerifyCodeDialog(
         confirmAction: (key, code) {
-          //发送验证码
-          _startNewCountDown();
+          //发送短信验证码
+          _sendSMS(phone, key, code);
         },
       ),
     );
   }
 
+  /// 调用接口发送短信验证码
+  void _sendSMS(String phone, String? key, String? code) async {
+    final result = await _authRepository.sendSMS(
+      countryCode: AppConstant.countryCode,
+      phone: phone,
+      captchaKey: key,
+      captchaValue: code,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      NotifyEngine.showSuccess(S.current.send_sms_successful);
+      _startCountDown();
+    } else {
+      ToastEngine.show(result.errorMsg ?? "UnKnow Error");
+    }
+  }
+
   Timer? newCountdownTimer;
 
   /// 开启倒计时 - New
-  void _startNewCountDown() {
+  void _startCountDown() {
     //60秒倒计时
     state = state.copyWith(isNewCounting: true, newCountdownTime: 60);
 
@@ -108,6 +152,10 @@ class ChangeMobileViewModel extends _$ChangeMobileViewModel {
 
   //初始化监听
   void initListener(ChangeMobileState initState) {
+    final String? phone = UserConfigService.getState().user?.information?.phone;
+    final TextEditingController phoneController = initState.formData['old']!['controller'];
+    phoneController.text = phone ?? "-";
+
     final FocusNode newCodeFocusNode = initState.formData['new_code']!['focusNode'];
 
     newCodeFocusNode.addListener(() {
@@ -127,5 +175,4 @@ class ChangeMobileViewModel extends _$ChangeMobileViewModel {
 
     Log.d("ChangeMobileViewModel 销毁 onDispose");
   }
-
 }

+ 8 - 0
packages/cpt_profile/lib/modules/profile_edit/Profile_edit_page.dart

@@ -6,6 +6,7 @@ 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:flutter_hooks/flutter_hooks.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:router/ext/auto_router_extensions.dart';
 import 'package:widgets/ext/ex_widget.dart';
@@ -34,6 +35,13 @@ class ProfileEditPage extends HookConsumerWidget {
     final viewModel = ref.watch(profileEditViewModelProvider.notifier);
     final state = ref.watch(profileEditViewModelProvider);
 
+    useEffect(() {
+      // 执行接口请求
+      Future.microtask(() => viewModel.fetchDefaultAvatar());
+      return () {
+      };
+    }, []);
+
     return Scaffold(
       appBar: MyAppBar.appBar(context, S.current.edit_profile,backgroundColor: context.appColors.backgroundWhite),
       backgroundColor: context.appColors.backgroundDefault,

+ 10 - 17
packages/cpt_profile/lib/modules/profile_edit/dialog/avatar_edit_dialog.dart

@@ -2,34 +2,27 @@ 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:hooks_riverpod/hooks_riverpod.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_load_image.dart';
 import 'package:widgets/my_text_view.dart';
 import 'package:widgets/widget_export.dart';
 
-class AvatarEditDialog extends StatelessWidget {
+import '../profile_edit_view_model.dart';
+
+class AvatarEditDialog extends HookConsumerWidget {
   void Function(String path) otherAction;
   void Function() photoAction;
 
-  final List<String> otherImages = [
-    "https://pic.rmb.bdstatic.com/bjh/bc3fcc5fadee3ab70dc6f941ae3eb4a21534.jpeg@h_1280",
-    "https://img0.baidu.com/it/u=3885044482,1194334042&fm=253&fmt=auto&app=120&f=JPEG?w=800&h=800",
-    "https://q0.itc.cn/q_70/images03/20240508/64f00aea4daa4b808e59fdadb939ff41.jpeg",
-    "https://ww3.sinaimg.cn/mw690/d315af46ly1h7wfnspdomj20u00u0tef.jpg",
-    "https://ww2.sinaimg.cn/mw690/006A8Z5cly1hrhndmtmuaj30he0htq55.jpg",
-    "https://ww1.sinaimg.cn/mw690/d315af46ly1h7wfnuxn91j20j60j60uk.jpg",
-    "https://img0.baidu.com/it/u=80291486,3068765574&fm=253&fmt=auto&app=138&f=JPEG?w=380&h=380",
-    "https://img0.baidu.com/it/u=528233043,1559727912&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500",
-    "https://img0.baidu.com/it/u=691481429,1364097496&fm=253&fmt=auto?w=500&h=500"
-  ];
-
   AvatarEditDialog({
     required this.photoAction,
     required this.otherAction,
   });
 
   @override
-  Widget build(BuildContext context) {
+  Widget build(BuildContext context,WidgetRef ref) {
+    final state = ref.watch(profileEditViewModelProvider);
+
     return Column(
       crossAxisAlignment: CrossAxisAlignment.center,
       mainAxisAlignment: MainAxisAlignment.center,
@@ -101,12 +94,12 @@ class AvatarEditDialog extends StatelessWidget {
                   crossAxisSpacing: 15.0, // 交叉轴(左右)的间距
                   childAspectRatio: 1, // 宽高比例
                 ),
-                itemCount: otherImages.length,
+                itemCount: state.defaultAvatars?.length ?? 0,
                 itemBuilder: (context, index) {
                   return Center(
-                    child: MyLoadImage(otherImages[index]).onTap((){
+                    child: MyLoadImage(state.defaultAvatars?[index]).onTap((){
                       onCancel();
-                      otherAction.call(otherImages[index]);
+                      otherAction.call(state.defaultAvatars?[index]??"");
                     }),
                   );
                 },

+ 4 - 0
packages/cpt_profile/lib/modules/profile_edit/profile_edit_state.dart

@@ -5,6 +5,7 @@ class ProfileEditState{
   //表单的校验与数据
   final Map<String, Map<String, dynamic>> formData;
 
+  List<String>? defaultAvatars;  //默认头像
   String? avatarPath;  //头像的路径或Uri
 
   // ===================================  Begin  ↓  ===================================
@@ -12,6 +13,7 @@ class ProfileEditState{
   ProfileEditState({
     Map<String, Map<String, dynamic>>? formData,
     this.avatarPath,
+    this.defaultAvatars,
   }) : formData = formData ??
       {
         'first_name': {
@@ -39,10 +41,12 @@ class ProfileEditState{
 
   ProfileEditState copyWith({
     String? avatarPath,
+    List<String>? defaultAvatars,
   }) {
     return ProfileEditState(
       formData: this.formData,
       avatarPath: avatarPath ?? this.avatarPath,
+      defaultAvatars: defaultAvatars ?? this.defaultAvatars,
     );
   }
 

+ 21 - 2
packages/cpt_profile/lib/modules/profile_edit/profile_edit_view_model.dart

@@ -6,6 +6,7 @@ import 'package:plugin_basic/provider/user_config/user_config_service.dart';
 import 'package:plugin_platform/engine/dialog/dialog_engine.dart';
 import 'package:plugin_platform/engine/notify/notify_engine.dart';
 import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 import 'package:router/ext/auto_router_extensions.dart';
 import 'package:shared/utils/log_utils.dart';
@@ -16,7 +17,7 @@ import 'package:plugin_platform/platform_export.dart';
 part 'profile_edit_view_model.g.dart';
 
 @riverpod
-class ProfileEditViewModel extends _$ProfileEditViewModel {
+class ProfileEditViewModel extends _$ProfileEditViewModel with DioCancelableMixin {
   late final ProfileRepository profileRepository;
 
   @override
@@ -25,9 +26,21 @@ class ProfileEditViewModel extends _$ProfileEditViewModel {
 
     final state = initState();
 
+    registerCancellation();
+
     return state;
   }
 
+  // 获取默认的头像
+  void fetchDefaultAvatar() async {
+    final result = await profileRepository.fetchDefaultAvatar(cancelToken: cancelToken);
+    if (result.isSuccess) {
+      state = state.copyWith(defaultAvatars: result.list);
+    } else {
+      Log.e(result.errorMsg ?? "UnKnow Error");
+    }
+  }
+
   /// 提交编辑用户信息
   void submitEdit() async {
     final FocusNode firstNameFocusNode = state.formData['first_name']!['focusNode'];
@@ -69,7 +82,13 @@ class ProfileEditViewModel extends _$ProfileEditViewModel {
     }
 
     //执行密码登录
-    final result = await profileRepository.updateProfile(firstName: firstName, lastName: lastName, email: email, avatarPath: state.avatarPath);
+    final result = await profileRepository.updateProfile(
+      firstName: firstName,
+      lastName: lastName,
+      email: email,
+      avatarPath: state.avatarPath,
+      cancelToken: cancelToken,
+    );
 
     if (result.isSuccess) {
       //提示成功

+ 3 - 0
packages/cpt_profile/lib/modules/reset_password/reset_password_page.dart

@@ -82,6 +82,7 @@ class ResetPasswordPage extends HookConsumerWidget {
                     context,
                     state,
                     "phone",
+                    enable: false,
                     textInputType: TextInputType.number,
                     textInputAction: TextInputAction.next,
                     onSubmit: (formKey, value) {
@@ -241,6 +242,7 @@ class ResetPasswordPage extends HookConsumerWidget {
         TextInputType textInputType = TextInputType.text,
         String? errorText,
         bool obscureText = false,
+        bool enable = true,
         TextInputAction textInputAction = TextInputAction.done,
         Function? onSubmit,
       }) {
@@ -260,6 +262,7 @@ class ResetPasswordPage extends HookConsumerWidget {
         margin: EdgeInsets.only(top: marginTop),
         padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 3),
         showDivider: false,
+        enabled: enable,
         height: 44,
         style: TextStyle(
           color: context.appColors.authFiledText,

+ 64 - 7
packages/cpt_profile/lib/modules/reset_password/reset_password_view_model.dart

@@ -1,9 +1,17 @@
 import 'dart:async';
 
 import 'package:cpt_profile/modules/reset_password/reset_password_state.dart';
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:domain/repository/auth_repository.dart';
 import 'package:flutter/material.dart';
+import 'package:plugin_basic/constants/app_constant.dart';
+import 'package:plugin_basic/dialog/verify_code_dialog.dart';
+import 'package:plugin_basic/provider/user_config/user_config_service.dart';
+import 'package:plugin_platform/engine/dialog/dialog_engine.dart';
+import 'package:plugin_platform/engine/notify/notify_engine.dart';
 import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:router/componentRouter/component_service_manager.dart';
 import 'package:router/ext/auto_router_extensions.dart';
 import 'package:shared/utils/log_utils.dart';
 import 'package:shared/utils/util.dart';
@@ -12,8 +20,12 @@ part 'reset_password_view_model.g.dart';
 
 @riverpod
 class ResetPasswordViewModel extends _$ResetPasswordViewModel {
+  late final AuthRepository authRepository;
+
   @override
   ResetPasswordState build() {
+    authRepository = ref.read(authRepositoryProvider);
+
     final state = ResetPasswordState();
     initListener(state);
     ref.onDispose(() {
@@ -23,7 +35,7 @@ class ResetPasswordViewModel extends _$ResetPasswordViewModel {
   }
 
   /// 提交重置密码请求
-  void submitResetPassword() {
+  void submitResetPassword() async {
     state = state.copyWith(codeErrorText: null, passwordErrorText: null, confirmPasswordErrorText: null);
 
     final FocusNode phoneFocusNode = state.formData['phone']!['focusNode'];
@@ -49,7 +61,7 @@ class ResetPasswordViewModel extends _$ResetPasswordViewModel {
     Log.d('当前待提交的 phone:$phone code:$code password:$password confirmPassword:$confirmPassword');
 
     if (Utils.isEmpty(phone)) {
-      ToastEngine.show("Enter Mobile Phone");
+      ToastEngine.show("Mobile Phone Error");
       return;
     }
 
@@ -74,10 +86,18 @@ class ResetPasswordViewModel extends _$ResetPasswordViewModel {
     }
 
     //执行密码登录
-    ToastEngine.show('准备执行请求发送验证码 phone:$phone code:$code password:$password confirmPassword:$confirmPassword');
-
-    //页面返回
-    appRouter.maybePop();
+    final result = await authRepository.resetPassword(smsCode: code, password: password, confirmPassword: confirmPassword);
+
+    if (result.isSuccess) {
+      //提示成功
+      NotifyEngine.showSuccess(S.current.successful);
+      //清除用户登录信息
+      UserConfigService.getInstance().handleLogoutParams();
+      //去登录页面
+      ComponentServiceManager().authService.startAndPopAllLoginPage();
+    } else {
+      ToastEngine.show(result.errorMsg ?? "UnKnow Error");
+    }
   }
 
   //切换隐藏显示密码
@@ -90,7 +110,40 @@ class ResetPasswordViewModel extends _$ResetPasswordViewModel {
   }
 
   void showVerifyCodedDialog() {
-    _startCountDown();
+    final TextEditingController phoneController = state.formData['phone']!['controller'];
+    final phone = phoneController.text;
+    if (Utils.isEmpty(phone)) {
+      ToastEngine.show("Mobile Phone Error");
+      return;
+    }
+
+    //短信验证码之前的图片验证码弹窗
+    DialogEngine.show(
+      onDismiss: () {},
+      widget: VerifyCodeDialog(
+        confirmAction: (key, code) {
+          //发送短信验证码
+          _sendSMS(phone, key, code);
+        },
+      ),
+    );
+  }
+
+  /// 调用接口发送短信验证码
+  void _sendSMS(String phone, String? key, String? code) async {
+    final result = await authRepository.sendSMS(
+      countryCode: AppConstant.countryCode,
+      phone: phone,
+      captchaKey: key,
+      captchaValue: code,
+    );
+
+    if (result.isSuccess) {
+      NotifyEngine.showSuccess(S.current.send_sms_successful);
+      _startCountDown();
+    } else {
+      ToastEngine.show(result.errorMsg ?? "UnKnow Error");
+    }
   }
 
   Timer? countdownTimer;
@@ -116,6 +169,10 @@ class ResetPasswordViewModel extends _$ResetPasswordViewModel {
 
   //初始化监听
   void initListener(ResetPasswordState initState) {
+    final String? phone = UserConfigService.getState().user?.information?.phone;
+    final TextEditingController phoneController = initState.formData['phone']!['controller'];
+    phoneController.text = phone ?? "-";
+
     final FocusNode codeFocusNode = initState.formData['code']!['focusNode'];
     final FocusNode passwordFocusNode = initState.formData['password']!['focusNode'];
     final FocusNode confirmPasswordFocusNode = initState.formData['confirm_password']!['focusNode'];

+ 4 - 1
packages/cs_domain/lib/constants/api_constants.dart

@@ -13,7 +13,7 @@ class ApiConstants {
   static const apiUserLogin = "/api/v1/user/auth/login";
 
   // 用户重置密码
-  static const apiResetPassword = "/api/v1/user/me/profile/update";
+  static const apiResetPassword = "/api/v1/user/me/setting/reset-password";
 
   // 用户忘记密码
   static const apiForgotPassword = "/api/v1/user/auth/forget-password";
@@ -43,6 +43,9 @@ class ApiConstants {
   //更新用户信息
   static const apiUpdateProfile = "/api/v1/user/me/profile/update";
 
+  //用户的默认头像列表
+  static const apiDefaultAvatar = "/api/v1/user/me/profile/default-avatar";
+
   //修改手机号码
   static const apiChangeMobile = "/api/v1/user/me/setting/change-phone";
 

+ 61 - 0
packages/cs_domain/lib/repository/auth_repository.dart

@@ -144,4 +144,65 @@ class AuthRepository {
     }
     return result.convert();
   }
+
+  /// 修改密码
+  Future<HttpResult> resetPassword({
+    required String? smsCode,
+    required String? password,
+    required String? confirmPassword,
+    CancelToken? cancelToken,
+  }) async {
+    Map<String, String> params = {};
+
+    params['sms_code'] = smsCode!;
+    params['password'] = password!;
+    params['password_confirmation'] = confirmPassword!;
+
+    final result = await dioEngine.requestNetResult(
+      ApiConstants.apiResetPassword,
+      params: params,
+      method: HttpMethod.POST,
+      isShowLoadingDialog: true,
+      networkDebounce: true,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      return result.convert();
+    }
+    return result.convert();
+  }
+
+  /// 忘记密码
+  Future<HttpResult> forgotPassword({
+    required String? smsCode,
+    required String? countryCode,
+    required String? phone,
+    required String? password,
+    required String? confirmPassword,
+    CancelToken? cancelToken,
+  }) async {
+    Map<String, String> params = {};
+
+    params['sms_code'] = smsCode!;
+    params['country_code'] = countryCode!;
+    params['phone'] = phone!;
+    params['password'] = password!;
+    params['password_confirmation'] = confirmPassword!;
+
+    final result = await dioEngine.requestNetResult(
+      ApiConstants.apiForgotPassword,
+      params: params,
+      method: HttpMethod.POST,
+      isShowLoadingDialog: true,
+      networkDebounce: true,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      return result.convert();
+    }
+    return result.convert();
+  }
+
 }

+ 63 - 0
packages/cs_domain/lib/repository/profile_repository.dart

@@ -80,4 +80,67 @@ class ProfileRepository {
     }
     return result.convert();
   }
+
+  /// 获取用户的默认头像列表
+  Future<HttpResult<String>> fetchDefaultAvatar({
+    CancelToken? cancelToken,
+  }) async {
+    final result = await dioEngine.requestNetResult(
+      ApiConstants.apiDefaultAvatar,
+      method: HttpMethod.GET,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      final jsonList = result.getListJson();
+
+      List<String> stringList = [];
+      if (jsonList != null) {
+        stringList = jsonList
+            .map((value) {
+              // 假设 value 是字符串类型,直接返回
+              if (value is String) {
+                return value;
+              }
+              return null;
+            })
+            .where((item) => item != null)
+            .cast<String>()
+            .toList();
+      }
+
+      return result.convert<String>(list: stringList);
+    }
+
+    return result.convert<String>();
+  }
+
+  /// 修改手机号码
+  Future<HttpResult> changeMobilePhone({
+    required String? smsCode,
+    required String? countryCode,
+    required String? phone,
+    CancelToken? cancelToken,
+  }) async {
+    Map<String, String> params = {};
+
+    params['sms_code'] = smsCode!;
+    params['country_code'] = countryCode!;
+    params['phone'] = phone!;
+
+    final result = await dioEngine.requestNetResult(
+      ApiConstants.apiChangeMobile,
+      params: params,
+      method: HttpMethod.POST,
+      isShowLoadingDialog: true,
+      networkDebounce: true,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      return result.convert();
+    }
+    return result.convert();
+  }
+
 }

+ 1 - 0
packages/cs_plugin_basic/lib/dio_interceptors/interceptor_auth_dio.dart

@@ -51,6 +51,7 @@ class AuthDioInterceptors extends Interceptor {
 
     //如果有通行令牌,都带上通行令牌
     String? token = UserConfigService.getState().token;
+    Log.d("请求拦截加上Token:$token");
     if (!Utils.isEmpty(token)) {
       headers['Authorization'] = 'Bearer $token';
     }

+ 10 - 4
packages/cs_plugin_basic/lib/provider/user_config/user_config.dart

@@ -8,8 +8,10 @@ class UserConfig {
   //用户的登录Token
   String? token;
 
+  String? userName;
+
   //用户是否已经登录
-  bool haslogin = false;
+  bool hasLogin = false;
 
   //用户的 registrationId 推送标识
   String? registrationId;
@@ -23,7 +25,9 @@ class UserConfig {
   UserConfig({
     this.user,
     this.token,
-    required this.haslogin,
+
+    this.userName,
+    required this.hasLogin,
     this.registrationId,
     required this.unreadNotificationsCount,
   });
@@ -31,14 +35,16 @@ class UserConfig {
   UserConfig copyWith({
     UserMeEntity? user,
     String? token,
-    bool? haslogin,
+    String? userName,
+    bool? hasLogin,
     String? registrationId,
     int? unreadNotificationsCount,
   }) {
     return UserConfig(
       user: user ?? this.user,
       token: token ?? this.token,
-      haslogin: haslogin ?? this.haslogin,
+      userName: userName ?? this.userName,
+      hasLogin: hasLogin ?? this.hasLogin,
       registrationId: registrationId ?? this.registrationId,
       unreadNotificationsCount: unreadNotificationsCount ?? this.unreadNotificationsCount,
     );

+ 6 - 6
packages/cs_plugin_basic/lib/provider/user_config/user_config_service.dart

@@ -44,7 +44,7 @@ class UserConfigService extends _$UserConfigService {
 
     String? token = SPUtil.getString(AppConstant.storageToken);
     Log.d('UserService - 查询SP token:$token 并赋值');
-    return UserConfig(token: token, haslogin: Utils.isNotEmpty(token), registrationId: null, unreadNotificationsCount: 0);
+    return UserConfig(token: token, hasLogin: Utils.isNotEmpty(token), registrationId: null, unreadNotificationsCount: 0);
   }
 
   /// 静默请求用户的详情数据
@@ -59,18 +59,18 @@ class UserConfigService extends _$UserConfigService {
 
   /// 设置用户信息
   void setUserInfo(UserMeEntity? user) {
-    state = state.copyWith(user: user);
+    state = state.copyWith(user: user, userName: user?.name);
   }
 
   /// 设置全局的Token,同时更新 hasLogin 的值,赋值时机如下
-  void setToken(String? token) {
+  void setToken({String? token, String? userName}) {
     UserConfig configState = state.copyWith(token: token);
 
     if (Utils.isEmpty(token)) {
-      configState.copyWith(haslogin: false);
+      configState.copyWith(hasLogin: false, userName: userName);
       SPUtil.remove(AppConstant.storageToken);
     } else {
-      configState.copyWith(haslogin: true);
+      configState.copyWith(hasLogin: true, userName: userName);
       SPUtil.putString(AppConstant.storageToken, token!);
     }
 
@@ -82,6 +82,6 @@ class UserConfigService extends _$UserConfigService {
   /// 处理退出登录之后的数据清除
   void handleLogoutParams() {
     SPUtil.remove(AppConstant.storageToken);
-    state = state.copyWith(token: null, haslogin: false, registrationId: null, unreadNotificationsCount: 0, user: null);
+    state = state.copyWith(token: null, hasLogin: false, registrationId: null, unreadNotificationsCount: 0, user: null, userName: null);
   }
 }