diff --git a/apps/vben5/apps/app-antd/src/layouts/basic.vue b/apps/vben5/apps/app-antd/src/layouts/basic.vue index 5367f444e..99d4b38f8 100644 --- a/apps/vben5/apps/app-antd/src/layouts/basic.vue +++ b/apps/vben5/apps/app-antd/src/layouts/basic.vue @@ -23,6 +23,8 @@ import { preferences } from '@vben/preferences'; import { useAccessStore, useUserStore } from '@vben/stores'; import { openWindow } from '@vben/utils'; +import { useAbpStore } from '@abp/core'; + import { useSessions } from '#/hooks/useSessions'; import { $t } from '#/locales'; import { useAuthStore } from '#/store'; @@ -64,6 +66,7 @@ const notifications = ref([ useSessions(); const { replace } = useRouter(); +const abpStore = useAbpStore(); const userStore = useUserStore(); const authStore = useAuthStore(); const accessStore = useAccessStore(); @@ -109,8 +112,19 @@ const menus = computed(() => [ }, ]); +const userInfo = computed(() => { + return userStore.userInfo; +}); + +const description = computed(() => { + if (abpStore.application?.currentTenant.name && userInfo.value?.username) { + return `${abpStore.application.currentTenant.name}/${userInfo.value.username}`; + } + return userInfo.value?.username; +}); + const avatar = computed(() => { - return userStore.userInfo?.avatar ?? preferences.app.defaultAvatar; + return userInfo.value?.avatar ?? preferences.app.defaultAvatar; }); async function handleLogout() { @@ -129,7 +143,7 @@ watch( async (enable) => { if (enable) { await updateWatermark({ - content: `${userStore.userInfo?.username}`, + content: `${userInfo.value?.username}`, }); } else { destroyWatermark(); @@ -146,10 +160,10 @@ watch( diff --git a/apps/vben5/packages/@abp/account/src/api/useProfileApi.ts b/apps/vben5/packages/@abp/account/src/api/useProfileApi.ts index 9a13b0242..63c77d849 100644 --- a/apps/vben5/packages/@abp/account/src/api/useProfileApi.ts +++ b/apps/vben5/packages/@abp/account/src/api/useProfileApi.ts @@ -2,9 +2,11 @@ import type { AuthenticatorDto, AuthenticatorRecoveryCodeDto, ChangePasswordInput, + ChangePhoneNumberInput, ChangePictureInput, ConfirmEmailInput, ProfileDto, + SendChangePhoneNumberCodeInput, SendEmailConfirmCodeDto, TwoFactorEnabledDto, UpdateProfileDto, @@ -49,6 +51,30 @@ export function useProfileApi() { }); } + /** + * 发送修改手机号验证码 + * @param input 参数 + */ + function sendChangePhoneNumberCodeApi( + input: SendChangePhoneNumberCodeInput, + ): Promise { + return request('/api/account/my-profile/send-phone-number-change-code', { + data: input, + method: 'POST', + }); + } + + /** + * 修改手机号 + * @param input 参数 + */ + function changePhoneNumberApi(input: ChangePhoneNumberInput): Promise { + return request('/api/account/my-profile/change-phone-number', { + data: input, + method: 'PUT', + }); + } + /** * 修改头像 * @param input 参数 @@ -158,6 +184,7 @@ export function useProfileApi() { return { cancel, changePasswordApi, + changePhoneNumberApi, changePictureApi, changeTwoFactorEnabledApi, confirmEmailApi, @@ -166,6 +193,7 @@ export function useProfileApi() { getPictureApi, getTwoFactorEnabledApi, resetAuthenticatorApi, + sendChangePhoneNumberCodeApi, sendEmailConfirmLinkApi, updateApi, verifyAuthenticatorCodeApi, diff --git a/apps/vben5/packages/@abp/account/src/components/MySetting.vue b/apps/vben5/packages/@abp/account/src/components/MySetting.vue index 78f72706a..20c07367f 100644 --- a/apps/vben5/packages/@abp/account/src/components/MySetting.vue +++ b/apps/vben5/packages/@abp/account/src/components/MySetting.vue @@ -91,6 +91,16 @@ const [EmailConfirmModal, emailConfirmModalApi] = useVbenModal({ () => import('./components/EmailConfirmModal.vue'), ), }); +const [ChangePasswordModal, changePasswordModalApi] = useVbenModal({ + connectedComponent: defineAsyncComponent( + () => import('./components/ChangePasswordModal.vue'), + ), +}); +const [ChangePhoneNumberModal, changePhoneNumberModalApi] = useVbenModal({ + connectedComponent: defineAsyncComponent( + () => import('./components/ChangePhoneNumberModal.vue'), + ), +}); function onEmailConfirm() { if (query?.confirmToken) { emailConfirmModalApi.setData({ @@ -104,6 +114,11 @@ async function onGetProfile() { const profile = await getApi(); myProfile.value = profile; } +async function onPhoneNumberChange(phoneNumber: string) { + userStore.$patch((state) => { + state.userInfo && (state.userInfo.phoneNumber = phoneNumber); + }); +} async function onUpdateProfile(input: UpdateProfileDto) { Modal.confirm({ centered: true, @@ -120,12 +135,10 @@ async function onUpdateProfile(input: UpdateProfileDto) { }); } function onChangePassword() { - // TODO: onChangePassword 暂时未实现! - console.warn('onChangePassword 暂时未实现!'); + changePasswordModalApi.open(); } function onChangePhoneNumber() { - // TODO: onChangePhoneNumber 暂时未实现! - console.warn('onChangePhoneNumber 暂时未实现!'); + changePhoneNumberModalApi.open(); } onMounted(async () => { await onGetProfile(); @@ -169,6 +182,8 @@ onMounted(async () => { + + diff --git a/apps/vben5/packages/@abp/account/src/components/components/ChangePasswordModal.vue b/apps/vben5/packages/@abp/account/src/components/components/ChangePasswordModal.vue new file mode 100644 index 000000000..0c0f1bb7c --- /dev/null +++ b/apps/vben5/packages/@abp/account/src/components/components/ChangePasswordModal.vue @@ -0,0 +1,110 @@ + + + + + diff --git a/apps/vben5/packages/@abp/account/src/components/components/ChangePhoneNumberModal.vue b/apps/vben5/packages/@abp/account/src/components/components/ChangePhoneNumberModal.vue new file mode 100644 index 000000000..e7e063004 --- /dev/null +++ b/apps/vben5/packages/@abp/account/src/components/components/ChangePhoneNumberModal.vue @@ -0,0 +1,82 @@ + + + + + diff --git a/apps/vben5/packages/@abp/account/src/types/profile.ts b/apps/vben5/packages/@abp/account/src/types/profile.ts index f5a4d57ab..d9f0bd050 100644 --- a/apps/vben5/packages/@abp/account/src/types/profile.ts +++ b/apps/vben5/packages/@abp/account/src/types/profile.ts @@ -36,6 +36,15 @@ interface ChangePasswordInput { newPassword: string; } +interface ChangePhoneNumberInput { + code: string; + newPhoneNumber: string; +} + +interface SendChangePhoneNumberCodeInput { + newPhoneNumber: string; +} + interface ChangePictureInput { file: File; } @@ -73,9 +82,11 @@ export type { AuthenticatorDto, AuthenticatorRecoveryCodeDto, ChangePasswordInput, + ChangePhoneNumberInput, ChangePictureInput, ConfirmEmailInput, ProfileDto, + SendChangePhoneNumberCodeInput, SendEmailConfirmCodeDto, TwoFactorEnabledDto, UpdateProfileDto, diff --git a/apps/vben5/packages/@abp/identity/src/hooks/usePasswordValidator.ts b/apps/vben5/packages/@abp/identity/src/hooks/usePasswordValidator.ts index 0e64dbd55..620d6874e 100644 --- a/apps/vben5/packages/@abp/identity/src/hooks/usePasswordValidator.ts +++ b/apps/vben5/packages/@abp/identity/src/hooks/usePasswordValidator.ts @@ -14,7 +14,7 @@ import { export function usePasswordValidator() { const { getNumber, isTrue } = useSettings(); - const { L } = useLocalization(['AbpIdentity', 'AbpUi']); + const { L } = useLocalization(['AbpIdentity', 'AbpValidation', 'AbpUi']); const passwordSetting = computed(() => { return { diff --git a/apps/vben5/packages/@abp/identity/src/index.ts b/apps/vben5/packages/@abp/identity/src/index.ts index e8affa2fe..88795a62d 100644 --- a/apps/vben5/packages/@abp/identity/src/index.ts +++ b/apps/vben5/packages/@abp/identity/src/index.ts @@ -1,4 +1,5 @@ export * from './api'; export * from './components'; export { UserLookupPermissions } from './constants/permissions'; +export * from './hooks'; export * from './types'; diff --git a/apps/vben5/packages/@abp/settings/src/components/settings/SettingForm.vue b/apps/vben5/packages/@abp/settings/src/components/settings/SettingForm.vue index e7b0a6104..4849331c9 100644 --- a/apps/vben5/packages/@abp/settings/src/components/settings/SettingForm.vue +++ b/apps/vben5/packages/@abp/settings/src/components/settings/SettingForm.vue @@ -78,7 +78,7 @@ async function onSubmit() { } function onCheckChange(setting: SettingDetail) { - setting.value = setting.value === 'true' ? 'false' : 'true'; + setting.value = setting.value?.toLowerCase() === 'true' ? 'false' : 'true'; onValueChange(setting); } @@ -202,7 +202,7 @@ onMounted(onGet); {{ detail.displayName }}