Commit 21621828e9bcdef1ed6534e3613f3ca1d4537f7a

Authored by 常守达
1 parent 32082e02

feat(email): 邮箱新绑定/换绑

... ... @@ -116,5 +116,10 @@ class MyController extends GetxController {
}
}
void refreshEmail() {}
Future<void> refreshEmail() async {
final result = await _userApi.getUserInfo();
if (result case AppSuccess<UserInfoResponse>(data: final user)) {
await Get.find<UserPreferencesStorage>().updateMeUserInfo(user);
}
}
}
... ...
... ... @@ -43,6 +43,8 @@ class AddSecurityEmailController extends GetxController {
final confirmPasswordInput = ''.obs;
final isConfirmPasswordObscured = true.obs;
final isEmailExist = false.obs;
@override
void onInit() {
super.onInit();
... ... @@ -98,12 +100,18 @@ class AddSecurityEmailController extends GetxController {
if (!isEmailValid) return;
try {
await LoadingService.instance.run(() async {
final result = await _userApi.requestEmailVerifyCode(emailInput.value);
// if (result is AppSuccess<void>) {
startResendCountdown();
Get.to(
() => SecurityEmailVerificationView(isChangeEmail: isChangeEmail));
// }
final checkRsult = await _userApi.requestEmailCheck(emailInput.value);
if (checkRsult is AppSuccess<void>) {
final result =
await _userApi.requestEmailVerifyCode(emailInput.value);
if (result is AppSuccess<void>) {
startResendCountdown();
Get.to(() =>
SecurityEmailVerificationView(isChangeEmail: isChangeEmail));
}
} else {
isEmailExist.value = true;
}
});
} catch (_) {}
}
... ... @@ -133,15 +141,18 @@ class AddSecurityEmailController extends GetxController {
codeController.text,
);
if (result is AppSuccess<void>) {
AppToast.show(context.l10n.successChanged);
Get.back();
Get.back();
Get.back();
final changeEmailResult = await _userApi.changeEmail(
emailInput.value,
codeController.text,
);
if (changeEmailResult is AppSuccess<void>) {
AppToast.show(context.l10n.successChanged);
Get.back();
Get.back();
Get.back();
}
} else {
AppToast.show(context.l10n.verifyEmailFailed);
Get.back();
Get.back();
Get.back();
}
});
} catch (_) {}
... ... @@ -152,11 +163,12 @@ class AddSecurityEmailController extends GetxController {
emailInput.value,
codeController.text,
);
// if (result is AppSuccess<void>) {
Get.to(() => const SetSecurityEmailPasswordView());
// }
if (result is AppSuccess<void>) {
AppToast.show(l10n.successChanged);
Get.to(() => const SetSecurityEmailPasswordView());
} else {
AppToast.show(l10n.verifyEmailFailed);
}
});
} catch (_) {}
}
... ... @@ -174,16 +186,30 @@ class AddSecurityEmailController extends GetxController {
codeController.text,
md5Password,
);
// if (result is AppSuccess<void>) {
FocusScope.of(context).unfocus();
AppToast.show(context.l10n.settingsSaved);
TextInput.finishAutofillContext();
Get.back();
Get.back();
Get.back();
if (result is AppSuccess<void>) {
AppToast.show(context.l10n.settingsSaved);
FocusScope.of(context).unfocus();
AppToast.show(context.l10n.settingsSaved);
TextInput.finishAutofillContext();
Get.back();
Get.back();
Get.back();
} else {}
});
} catch (_) {}
}
// }
Future<void> verifyPassword() async {
try {
final md5Password =
md5.convert(utf8.encode(passwordInput.value)).toString();
await LoadingService.instance.run(() async {
final result = await _userApi.verifySefetyEmailPassword(
md5Password,
);
if (result is AppSuccess<void>) {
Get.to(() => AddSecurityEmailView(isChangeEmail: true));
} else {}
});
} catch (_) {}
}
... ...
... ... @@ -153,7 +153,24 @@ class AddSecurityEmailView extends GetView<AddSecurityEmailController> {
),
);
}),
const SizedBox(height: 32),
SizedBox(
height: 88,
child: Padding(
padding:
const EdgeInsets.only(top: 8.0, left: 20, right: 20),
child: Obx(() => controller.isEmailExist.value
? Text(
'This email is already linked to another account. Please use a different email.',
textAlign: TextAlign.center,
style: TextStyle(
color: context.colors.warning,
fontSize: 14,
fontWeight: FontWeight.w400,
),
)
: SizedBox.shrink()),
),
),
SizedBox(
width: double.infinity,
height: 48,
... ... @@ -814,7 +831,7 @@ class VerifyEmailPwdView extends GetView<AddSecurityEmailController> {
Obx(() {
final isObscured = c.isPasswordObscured.value;
return TextField(
textInputAction: TextInputAction.next,
// textInputAction: TextInputAction.next,
controller: c.passwordController,
// keyboardType: TextInputType.visiblePassword,
obscureText: isObscured,
... ... @@ -889,8 +906,7 @@ class VerifyEmailPwdView extends GetView<AddSecurityEmailController> {
),
),
),
onSubmitted: (_) =>
Get.to(() => AddSecurityEmailView(isChangeEmail: true)),
onSubmitted: (_) => c.verifyPassword(),
);
}),
const SizedBox(height: 8),
... ... @@ -913,10 +929,8 @@ class VerifyEmailPwdView extends GetView<AddSecurityEmailController> {
height: 48,
child: Obx(
() => ElevatedButton(
onPressed: c.isPasswordValid
? () => Get.to(
() => AddSecurityEmailView(isChangeEmail: true))
: null,
onPressed:
c.isPasswordValid ? () => c.verifyPassword() : null,
style: ElevatedButton.styleFrom(
backgroundColor: colors.primary,
disabledBackgroundColor:
... ...
... ... @@ -289,7 +289,20 @@ class UserApi {
await _dioClient.dio.post(
ApiPaths.emailSendCode,
data: {
'safety_email': email,
'email': email,
},
);
},
);
}
Future<AppResult<void>> requestEmailCheck(String email) {
return safeCall(
call: () async {
await _dioClient.dio.post(
ApiPaths.emailCheck,
data: {
'email': email,
},
);
},
... ... @@ -302,8 +315,22 @@ class UserApi {
await _dioClient.dio.post(
ApiPaths.emailVerifyCode,
data: {
'safety_email': email,
'safety_email_code': code,
'email': email,
'code': code,
},
);
},
);
}
Future<AppResult<void>> changeEmail(String email, String code) {
return safeCall(
call: () async {
await _dioClient.dio.post(
ApiPaths.changeEmail,
data: {
'email': email,
'code': code,
},
);
},
... ... @@ -317,8 +344,22 @@ class UserApi {
await _dioClient.dio.post(
ApiPaths.addSafetyEmail,
data: {
'safety_email': email,
'safety_email_code': code,
'email': email,
'code': code,
'password': pwd,
},
);
},
);
}
Future<AppResult<void>> verifySefetyEmailPassword(String pwd) {
return safeCall(
call: () async {
await _dioClient.dio.post(
ApiPaths.changeEmailVerifyPassword,
data: {
'current_password': pwd,
},
);
},
... ...
... ... @@ -4,11 +4,13 @@ abstract final class ApiPaths {
static const userRegister = '/client/doublefeel/user/register/';
static const userLogin = '/client/doublefeel/user/login/';
static const smsSendCode = '/client/doublefeel/sms/send_code/';
static const emailSendCode =
'/client/doublefeel/safety_email/send_verify_code/';
static const emailVerifyCode = '/client/doublefeel/safety_email/verify_code/';
static const addSafetyEmail =
'/client/doublefeel/safety_email/add_safety_email/';
static const emailCheck = '/client/doublefeel/user/email/check/';
static const emailSendCode = '/client/doublefeel/user/email/send_email/';
static const emailVerifyCode = '/client/doublefeel/user/email/check_code/';
static const changeEmail = '/client/doublefeel/user/email/change/';
static const addSafetyEmail = '/client/doublefeel/user/email/submit/';
static const changeEmailVerifyPassword =
'/client/doublefeel/user/email/change/verify_password/';
static const userPair = '/client/doublefeel/user/pair/';
static const userLogout = '/client/doublefeel/user/logout/';
static const userDeleteAccount = '/client/doublefeel/user/account/delete/';
... ...