Browse Source

更改用户信息

liukai 3 months ago
parent
commit
8bc0ed140f

+ 3 - 3
packages/cpt_profile/lib/modules/profile_edit/Profile_edit_page.dart

@@ -56,7 +56,7 @@ class ProfileEditPage extends HookConsumerWidget {
                     children: [
                       //默认的占位图
                       Visibility(
-                        visible: true,
+                        visible: state.avatarPath == null,
                         child: const Align(
                           alignment: Alignment.bottomCenter,
                           child: MyAssetImage(
@@ -69,9 +69,9 @@ class ProfileEditPage extends HookConsumerWidget {
 
                       //用户的头像
                       Visibility(
-                        visible: false,
+                        visible: state.avatarPath != null,
                         child: MyLoadImage(
-                          "https://img1.baidu.com/it/u=1656098746,3560654086&fm=253&fmt=auto&app=120&f=JPEG?w=800&h=800",
+                          state.avatarPath,
                           width: 80,
                           height: 80,
                           isCircle: true,

+ 67 - 6
packages/cpt_profile/lib/modules/profile_edit/profile_edit_view_model.dart

@@ -1,10 +1,15 @@
 import 'package:cpt_profile/modules/profile_edit/dialog/avatar_edit_dialog.dart';
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:domain/repository/profile_repository.dart';
 import 'package:flutter/material.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/ext/auto_router_extensions.dart';
 import 'package:shared/utils/log_utils.dart';
+import 'package:shared/utils/util.dart';
 import 'profile_edit_state.dart';
 import 'package:plugin_platform/platform_export.dart';
 
@@ -12,13 +17,19 @@ part 'profile_edit_view_model.g.dart';
 
 @riverpod
 class ProfileEditViewModel extends _$ProfileEditViewModel {
+  late final ProfileRepository profileRepository;
+
   @override
   ProfileEditState build() {
-    return ProfileEditState();
+    profileRepository = ref.read(profileRepositoryProvider);
+
+    final state = initState();
+
+    return state;
   }
 
   /// 提交编辑用户信息
-  void submitEdit() {
+  void submitEdit() async {
     final FocusNode firstNameFocusNode = state.formData['first_name']!['focusNode'];
     final FocusNode lastNameFocusNode = state.formData['last_name']!['focusNode'];
     final FocusNode emailFocusNode = state.formData['email']!['focusNode'];
@@ -37,10 +48,39 @@ class ProfileEditViewModel extends _$ProfileEditViewModel {
 
     Log.d('当前待提交的 firstName:$firstName lastName:$lastName email:$email');
 
+    if (Utils.isEmpty(firstName)) {
+      ToastEngine.show('First Name cannot be empty!');
+      return;
+    }
+
+    if (Utils.isEmpty(lastName)) {
+      ToastEngine.show('Last Name cannot be empty!');
+      return;
+    }
+
+    if (Utils.isEmpty(email)) {
+      ToastEngine.show('Email cannot be empty!');
+      return;
+    }
+
+    if (Utils.isEmpty(state.avatarPath)) {
+      ToastEngine.show('Please select an avatar as your profile picture');
+      return;
+    }
+
     //执行密码登录
-    ToastEngine.show('准备执行请求发送验证码 firstName:$firstName lastName:$lastName email:$email ');
+    final result = await profileRepository.updateProfile(firstName: firstName, lastName: lastName, email: email, avatarPath: state.avatarPath);
 
-    appRouter.maybePop();
+    if (result.isSuccess) {
+      //提示成功
+      NotifyEngine.showSuccess(S.current.successful);
+      //刷新用户信息
+      UserConfigService.getInstance().refreshUserInfo();
+      //返回
+      appRouter.maybePop();
+    } else {
+      ToastEngine.show(result.errorMsg ?? "UnKnow Error");
+    }
   }
 
   //去编辑头像页面
@@ -48,7 +88,7 @@ class ProfileEditViewModel extends _$ProfileEditViewModel {
     DialogEngine.show(
         widget: AvatarEditDialog(
       otherAction: (path) {
-        ToastEngine.show("点击了图片:$path");
+        state = state.copyWith(avatarPath: path);
       },
       photoAction: () {
         //选择相机相册
@@ -60,7 +100,28 @@ class ProfileEditViewModel extends _$ProfileEditViewModel {
   //相机相册选择
   void _pickPhoto(BuildContext context) {
     ImagePickerUtils().show(context, (path) {
-      ToastEngine.show("选中了图片:$path");
+      state = state.copyWith(avatarPath: path);
     });
   }
+
+  // 初始化
+  ProfileEditState initState() {
+    final String? avatarPath = UserConfigService.getState().user?.avatar;
+    final initState = ProfileEditState(avatarPath: Utils.isEmpty(avatarPath) ? null : avatarPath);
+
+    final String? firstName = UserConfigService.getState().user?.information?.firstName;
+    final String? lastName = UserConfigService.getState().user?.information?.lastName;
+    final String? email = UserConfigService.getState().user?.email;
+
+    final TextEditingController firstNameController = initState.formData['first_name']!['controller'];
+    firstNameController.text = firstName ?? "";
+
+    final TextEditingController lastNameController = initState.formData['last_name']!['controller'];
+    lastNameController.text = lastName ?? "";
+
+    final TextEditingController emailController = initState.formData['email']!['controller'];
+    emailController.text = email ?? "";
+
+    return initState;
+  }
 }

+ 15 - 9
packages/cs_domain/lib/constants/api_constants.dart

@@ -12,27 +12,27 @@ class ApiConstants {
   // 登录
   static const apiUserLogin = "/api/v1/user/auth/login";
 
-  // 登出系统
-  static const apiUserLogout = "/index.php/api/v1/hotel/logout";
-
-  // 用户修改密码
-  static const apiResetPassword = "/index.php/api/v1/hotel/reset";
+  // 用户重置密码
+  static const apiResetPassword = "/api/v1/user/me/profile/update";
 
   // 用户忘记密码
-  static const apiForgotPassword = "/index.php/api/v1/hotel/reset";
+  static const apiForgotPassword = "/api/v1/user/auth/forget-password";
 
   //用户注册
   static const apiAuthRegister = "/api/v1/user/auth/register";
 
-  //用户注销
-  static const apiAuthDeactivate = "/index.php/api/v1/hotel/deactivate";
-
   //验证码图片
   static const apiCaptchaImage = "/api/v1/user/captcha/index";
 
   //发送短信
   static const apiSendSMS = "/api/v1/user/sms/send";
 
+  // 登出系统
+  static const apiUserLogout = "/index.php/api/v1/hotel/logout";
+
+  //用户注销
+  static const apiAuthDeactivate = "/index.php/api/v1/hotel/deactivate";
+
   // =========================== 首页 ↓=========================================
 
   // =========================== Profile ↓=========================================
@@ -40,6 +40,12 @@ class ApiConstants {
   //用户Me页面详情
   static const apiProfileInfo = "/api/v1/user/me/index";
 
+  //更新用户信息
+  static const apiUpdateProfile = "/api/v1/user/me/profile/update";
+
+  //修改手机号码
+  static const apiChangeMobile = "/api/v1/user/me/setting/change-phone";
+
   // =========================== 其他 ↓=========================================
 
   //服务器时间

+ 24 - 0
packages/cs_domain/lib/entity/user_me_entity.dart

@@ -9,6 +9,7 @@ class UserMeEntity {
 	String? name;
 	String? avatar;
 	String? phone;
+	String? email;
 	@JSONField(name: "follows_count")
 	String? followsCount;
 	@JSONField(name: "flowers_count")
@@ -19,6 +20,7 @@ class UserMeEntity {
 	List<UserMeEstates>? estates = [];
 	@JSONField(name: "default_unit")
 	UserMeDefaultUnit? defaultUnit;
+	UserMeInformation? information;
 
 	UserMeEntity();
 
@@ -132,4 +134,26 @@ class UserMeDefaultUnit {
 	String toString() {
 		return jsonEncode(this);
 	}
+}
+
+@JsonSerializable()
+class UserMeInformation {
+	@JSONField(name: "first_name")
+	String? firstName;
+	@JSONField(name: "last_name")
+	String? lastName;
+	@JSONField(name: "country_code")
+	String? countryCode;
+	String? phone;
+
+	UserMeInformation();
+
+	factory UserMeInformation.fromJson(Map<String, dynamic> json) => $UserMeInformationFromJson(json);
+
+	Map<String, dynamic> toJson() => $UserMeInformationToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
 }

+ 4 - 0
packages/cs_domain/lib/generated/json/base/json_convert_content.dart

@@ -167,6 +167,9 @@ class JsonConvert {
     if (<UserMeDefaultUnit>[] is M) {
       return data.map<UserMeDefaultUnit>((Map<String, dynamic> e) => UserMeDefaultUnit.fromJson(e)).toList() as M;
     }
+    if (<UserMeInformation>[] is M) {
+      return data.map<UserMeInformation>((Map<String, dynamic> e) => UserMeInformation.fromJson(e)).toList() as M;
+    }
 
     debugPrint("$M not found");
 
@@ -196,6 +199,7 @@ class JsonConvertClassCollection {
     (UserMeEstatesAccounts).toString(): UserMeEstatesAccounts.fromJson,
     (UserMeEstatesAccountsUnit).toString(): UserMeEstatesAccountsUnit.fromJson,
     (UserMeDefaultUnit).toString(): UserMeDefaultUnit.fromJson,
+    (UserMeInformation).toString(): UserMeInformation.fromJson,
   };
 
   bool containsKey(String type) {

+ 60 - 1
packages/cs_domain/lib/generated/json/user_me_entity.g.dart

@@ -19,6 +19,10 @@ UserMeEntity $UserMeEntityFromJson(Map<String, dynamic> json) {
   if (phone != null) {
     userMeEntity.phone = phone;
   }
+  final String? email = jsonConvert.convert<String>(json['email']);
+  if (email != null) {
+    userMeEntity.email = email;
+  }
   final String? followsCount = jsonConvert.convert<String>(json['follows_count']);
   if (followsCount != null) {
     userMeEntity.followsCount = followsCount;
@@ -45,6 +49,10 @@ UserMeEntity $UserMeEntityFromJson(Map<String, dynamic> json) {
   if (defaultUnit != null) {
     userMeEntity.defaultUnit = defaultUnit;
   }
+  final UserMeInformation? information = jsonConvert.convert<UserMeInformation>(json['information']);
+  if (information != null) {
+    userMeEntity.information = information;
+  }
   return userMeEntity;
 }
 
@@ -54,12 +62,14 @@ Map<String, dynamic> $UserMeEntityToJson(UserMeEntity entity) {
   data['name'] = entity.name;
   data['avatar'] = entity.avatar;
   data['phone'] = entity.phone;
+  data['email'] = entity.email;
   data['follows_count'] = entity.followsCount;
   data['flowers_count'] = entity.flowersCount;
   data['posts_count'] = entity.postsCount;
   data['households'] = entity.households?.map((v) => v.toJson()).toList();
   data['estates'] = entity.estates?.map((v) => v.toJson()).toList();
   data['default_unit'] = entity.defaultUnit?.toJson();
+  data['information'] = entity.information?.toJson();
   return data;
 }
 
@@ -69,24 +79,28 @@ extension UserMeEntityExtension on UserMeEntity {
     String? name,
     String? avatar,
     String? phone,
+    String? email,
     String? followsCount,
     String? flowersCount,
     String? postsCount,
     List<UserMeHouseholds>? households,
     List<UserMeEstates>? estates,
     UserMeDefaultUnit? defaultUnit,
+    UserMeInformation? information,
   }) {
     return UserMeEntity()
       ..id = id ?? this.id
       ..name = name ?? this.name
       ..avatar = avatar ?? this.avatar
       ..phone = phone ?? this.phone
+      ..email = email ?? this.email
       ..followsCount = followsCount ?? this.followsCount
       ..flowersCount = flowersCount ?? this.flowersCount
       ..postsCount = postsCount ?? this.postsCount
       ..households = households ?? this.households
       ..estates = estates ?? this.estates
-      ..defaultUnit = defaultUnit ?? this.defaultUnit;
+      ..defaultUnit = defaultUnit ?? this.defaultUnit
+      ..information = information ?? this.information;
   }
 }
 
@@ -349,4 +363,49 @@ extension UserMeDefaultUnitExtension on UserMeDefaultUnit {
       ..address = address ?? this.address
       ..type = type ?? this.type;
   }
+}
+
+UserMeInformation $UserMeInformationFromJson(Map<String, dynamic> json) {
+  final UserMeInformation userMeInformation = UserMeInformation();
+  final String? firstName = jsonConvert.convert<String>(json['first_name']);
+  if (firstName != null) {
+    userMeInformation.firstName = firstName;
+  }
+  final String? lastName = jsonConvert.convert<String>(json['last_name']);
+  if (lastName != null) {
+    userMeInformation.lastName = lastName;
+  }
+  final String? countryCode = jsonConvert.convert<String>(json['country_code']);
+  if (countryCode != null) {
+    userMeInformation.countryCode = countryCode;
+  }
+  final String? phone = jsonConvert.convert<String>(json['phone']);
+  if (phone != null) {
+    userMeInformation.phone = phone;
+  }
+  return userMeInformation;
+}
+
+Map<String, dynamic> $UserMeInformationToJson(UserMeInformation entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['first_name'] = entity.firstName;
+  data['last_name'] = entity.lastName;
+  data['country_code'] = entity.countryCode;
+  data['phone'] = entity.phone;
+  return data;
+}
+
+extension UserMeInformationExtension on UserMeInformation {
+  UserMeInformation copyWith({
+    String? firstName,
+    String? lastName,
+    String? countryCode,
+    String? phone,
+  }) {
+    return UserMeInformation()
+      ..firstName = firstName ?? this.firstName
+      ..lastName = lastName ?? this.lastName
+      ..countryCode = countryCode ?? this.countryCode
+      ..phone = phone ?? this.phone;
+  }
 }

+ 39 - 1
packages/cs_domain/lib/repository/profile_repository.dart

@@ -28,7 +28,6 @@ class ProfileRepository {
   Future<HttpResult<UserMeEntity>> fetchUserInfo({
     CancelToken? cancelToken,
   }) async {
-
     final result = await dioEngine.requestNetResult(
       ApiConstants.apiProfileInfo,
       method: HttpMethod.GET,
@@ -42,4 +41,43 @@ class ProfileRepository {
     }
     return result.convert();
   }
+
+  /// 更新用户信息
+  Future<HttpResult> updateProfile({
+    required String? firstName,
+    required String? lastName,
+    required String? email,
+    required String? avatarPath,
+    CancelToken? cancelToken,
+  }) async {
+    Map<String, String> params = {};
+    params['first_name'] = firstName!;
+    params['last_name'] = lastName!;
+    params['email'] = email!;
+
+    Map<String, String> paths = {};
+
+    //如果是链接通过params传参
+    if (avatarPath != null && avatarPath.startsWith("http")) {
+      params['avatar'] = avatarPath;
+    } else {
+      //如果是文件通过Path传参
+      paths['avatar'] = avatarPath ?? "";
+    }
+
+    final result = await dioEngine.requestNetResult(
+      ApiConstants.apiUpdateProfile,
+      params: params,
+      paths: paths,
+      method: HttpMethod.POST,
+      isShowLoadingDialog: true,
+      networkDebounce: true,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      return result.convert();
+    }
+    return result.convert();
+  }
 }