committed by
GitHub
9 changed files with 273 additions and 12 deletions
@ -0,0 +1,110 @@ |
|||
<script setup lang="ts"> |
|||
import { useVbenForm, useVbenModal, z } from '@vben/common-ui'; |
|||
import { $t } from '@vben/locales'; |
|||
|
|||
import { usePasswordValidator } from '@abp/identity'; |
|||
import { message } from 'ant-design-vue'; |
|||
|
|||
import { useProfileApi } from '../../api'; |
|||
|
|||
const { validate } = usePasswordValidator(); |
|||
const { changePasswordApi } = useProfileApi(); |
|||
|
|||
interface FormModel { |
|||
currentPassword: string; |
|||
newPassword: string; |
|||
newPasswordConfirm: string; |
|||
} |
|||
|
|||
const [Form, formApi] = useVbenForm({ |
|||
handleSubmit: onSubmit, |
|||
schema: [ |
|||
{ |
|||
component: 'InputPassword', |
|||
fieldName: 'currentPassword', |
|||
label: $t('AbpAccount.DisplayName:CurrentPassword'), |
|||
rules: 'required', |
|||
}, |
|||
{ |
|||
component: 'InputPassword', |
|||
fieldName: 'newPassword', |
|||
label: $t('AbpAccount.DisplayName:NewPassword'), |
|||
rules: z |
|||
.string() |
|||
.superRefine(async (newPassword, ctx) => { |
|||
try { |
|||
await validate(newPassword); |
|||
} catch (error) { |
|||
ctx.addIssue({ |
|||
code: z.ZodIssueCode.custom, |
|||
message: String(error), |
|||
}); |
|||
} |
|||
}) |
|||
.refine( |
|||
async (newPassword) => { |
|||
const input = (await formApi.getValues()) as FormModel; |
|||
return input.currentPassword !== newPassword; |
|||
}, |
|||
{ |
|||
message: $t('AbpAccount.NewPasswordSameAsOld'), |
|||
}, |
|||
) |
|||
.refine( |
|||
async (newPassword) => { |
|||
const input = (await formApi.getValues()) as FormModel; |
|||
return input.newPasswordConfirm === newPassword; |
|||
}, |
|||
{ |
|||
message: $t( |
|||
'AbpIdentity.Volo_Abp_Identity:PasswordConfirmationFailed', |
|||
), |
|||
}, |
|||
), |
|||
}, |
|||
{ |
|||
component: 'InputPassword', |
|||
fieldName: 'newPasswordConfirm', |
|||
label: $t('AbpAccount.DisplayName:NewPasswordConfirm'), |
|||
rules: z.string().refine( |
|||
async (newPasswordConfirm) => { |
|||
const input = (await formApi.getValues()) as FormModel; |
|||
return input.newPassword === newPasswordConfirm; |
|||
}, |
|||
{ |
|||
message: $t( |
|||
'AbpIdentity.Volo_Abp_Identity:PasswordConfirmationFailed', |
|||
), |
|||
}, |
|||
), |
|||
}, |
|||
], |
|||
showDefaultActions: false, |
|||
}); |
|||
const [Modal, modalApi] = useVbenModal({ |
|||
async onConfirm() { |
|||
await formApi.validateAndSubmitForm(); |
|||
}, |
|||
}); |
|||
async function onSubmit(values: Record<string, any>) { |
|||
try { |
|||
modalApi.setState({ submitting: true }); |
|||
await changePasswordApi({ |
|||
currentPassword: values.currentPassword, |
|||
newPassword: values.newPassword, |
|||
}); |
|||
message.success($t('AbpIdentity.PasswordChangedMessage')); |
|||
modalApi.close(); |
|||
} finally { |
|||
modalApi.setState({ submitting: false }); |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<template> |
|||
<Modal :title="$t('AbpAccount.ResetMyPassword')"> |
|||
<Form /> |
|||
</Modal> |
|||
</template> |
|||
|
|||
<style scoped></style> |
|||
@ -0,0 +1,82 @@ |
|||
<script setup lang="ts"> |
|||
import { useVbenForm, useVbenModal } from '@vben/common-ui'; |
|||
import { $t } from '@vben/locales'; |
|||
|
|||
import { message } from 'ant-design-vue'; |
|||
|
|||
import { useProfileApi } from '../../api'; |
|||
|
|||
const emits = defineEmits<{ |
|||
(event: 'change', data: string): void; |
|||
}>(); |
|||
|
|||
const { changePhoneNumberApi, sendChangePhoneNumberCodeApi } = useProfileApi(); |
|||
|
|||
const [Form, formApi] = useVbenForm({ |
|||
handleSubmit: onSubmit, |
|||
schema: [ |
|||
{ |
|||
component: 'Input', |
|||
fieldName: 'newPhoneNumber', |
|||
label: $t('AbpIdentity.DisplayName:NewPhoneNumber'), |
|||
rules: 'required', |
|||
}, |
|||
{ |
|||
component: 'VbenPinInput', |
|||
componentProps: { |
|||
createText: (countdown: number) => { |
|||
const text = |
|||
countdown > 0 |
|||
? $t('authentication.sendText', [countdown]) |
|||
: $t('authentication.sendCode'); |
|||
return text; |
|||
}, |
|||
handleSendCode: onSendCode, |
|||
}, |
|||
fieldName: 'code', |
|||
label: $t('AbpIdentity.DisplayName:SmsVerifyCode'), |
|||
rules: 'required', |
|||
}, |
|||
], |
|||
showDefaultActions: false, |
|||
}); |
|||
const [Modal, modalApi] = useVbenModal({ |
|||
async onConfirm() { |
|||
await formApi.validateAndSubmitForm(); |
|||
}, |
|||
}); |
|||
|
|||
async function onSendCode() { |
|||
const result = await formApi.validateField('newPhoneNumber'); |
|||
if (!result.valid) { |
|||
throw new Error(result.errors.join('\n')); |
|||
} |
|||
const input = await formApi.getValues(); |
|||
await sendChangePhoneNumberCodeApi({ |
|||
newPhoneNumber: input.newPhoneNumber, |
|||
}); |
|||
} |
|||
|
|||
async function onSubmit(values: Record<string, any>) { |
|||
try { |
|||
modalApi.setState({ submitting: true }); |
|||
await changePhoneNumberApi({ |
|||
code: values.code, |
|||
newPhoneNumber: values.newPhoneNumber, |
|||
}); |
|||
message.success($t('AbpAccount.PhoneNumberChangedMessage')); |
|||
emits('change', values.newPhoneNumber); |
|||
modalApi.close(); |
|||
} finally { |
|||
modalApi.setState({ submitting: false }); |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<template> |
|||
<Modal :title="$t('AbpIdentity.PhoneNumber')"> |
|||
<Form /> |
|||
</Modal> |
|||
</template> |
|||
|
|||
<style scoped></style> |
|||
@ -1,4 +1,5 @@ |
|||
export * from './api'; |
|||
export * from './components'; |
|||
export { UserLookupPermissions } from './constants/permissions'; |
|||
export * from './hooks'; |
|||
export * from './types'; |
|||
|
|||
Loading…
Reference in new issue