管理端个人中心

pull/65/head
awenes 2023-10-06 17:47:56 +08:00
parent 9fce81d45d
commit 4fa0746bfb
7 changed files with 76 additions and 174 deletions

View File

@ -33,11 +33,13 @@ export default (props: {
const [loading, setLoading] = useState<boolean>(false);
const formRef = useRef<ProFormInstance>();
const intl = useIntl();
useEffect(() => {
setLoading(true);
formRef.current?.setFieldsValue({ id });
setLoading(false);
}, [visible, id]);
return (
<ModalForm
title={intl.formatMessage({ id: 'pages.setting.administrator.reset_password_modal' })}
@ -52,7 +54,7 @@ export default (props: {
destroyOnClose: true,
onCancel: onCancel,
}}
onFinish={(formData: { password: string }) => {
onFinish={async (formData: { password: string }) => {
setLoading(true);
const password = Base64.encode(formData.password, true);
onFinish({ id, password }).finally(() => {

View File

@ -22,7 +22,6 @@ import { ModalForm, ProFormCaptcha, ProFormText } from '@ant-design/pro-componen
import { App, Spin } from 'antd';
import { omit } from 'lodash';
import { useEffect, useRef, useState } from 'react';
import { FormLayout } from './constant';
import { useIntl } from '@@/exports';
export default (props: {
@ -39,10 +38,12 @@ export default (props: {
const [hasSendCaptcha, setHasSendCaptcha] = useState<boolean>(false);
const captchaRef = useRef<CaptFieldRef>();
const formRef = useRef<ProFormInstance>();
useEffect(() => {
setLoading(true);
setLoading(false);
}, [visible]);
return (
<>
<ModalForm
@ -52,7 +53,12 @@ export default (props: {
labelAlign={'right'}
preserve={false}
layout={'horizontal'}
{...FormLayout}
labelCol={{
span: 4,
}}
wrapperCol={{
span: 20,
}}
autoFocusFirstInput
open={visible}
modalProps={{

View File

@ -16,21 +16,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { FieldNames } from '../constant';
import { changePassword, prepareChangePassword } from '../service';
import { aesEcbEncrypt } from '@/utils/aes';
import { onGetEncryptSecret } from '@/utils/utils';
import {
ModalForm,
ProFormCaptcha,
ProFormDependency,
ProFormInstance,
ProFormRadio,
ProFormText,
} from '@ant-design/pro-components';
import { changePassword } from '../service';
import { ModalForm, ProFormInstance, ProFormText } from '@ant-design/pro-components';
import { App, Spin } from 'antd';
import { useEffect, useRef, useState } from 'react';
import { FormLayout } from './constant';
import { FormattedMessage, useIntl, useModel } from '@@/exports';
import * as React from 'react';
import { useIntl } from '@umijs/max';
/**
*
@ -43,12 +34,12 @@ const ModifyPassword = (props: {
setRefresh: (visible: boolean) => void;
setVisible: (visible: boolean) => void;
}) => {
const { initialState } = useModel('@@initialState');
const intl = useIntl();
const { message } = App.useApp();
const { visible, setVisible, setRefresh } = props;
const [loading, setLoading] = useState<boolean>(false);
const formRef = useRef<ProFormInstance>();
useEffect(() => {
setLoading(true);
setLoading(false);
@ -63,7 +54,12 @@ const ModifyPassword = (props: {
labelAlign={'right'}
preserve={false}
layout={'horizontal'}
{...FormLayout}
labelCol={{
span: 5,
}}
wrapperCol={{
span: 19,
}}
autoFocusFirstInput
open={visible}
modalProps={{
@ -74,31 +70,36 @@ const ModifyPassword = (props: {
},
}}
onFinish={async (formData: Record<string, any>) => {
const publicSecret = await onGetEncryptSecret();
if (publicSecret) {
//加密传输
const { success, result } = await changePassword(
aesEcbEncrypt(
JSON.stringify({
...formData,
newPassword: formData[FieldNames.NEW_PASSWORD] as string,
verifyCode: formData[FieldNames.VERIFY_CODE] as string,
channel: formData[FieldNames.CHANNEL] as string,
}),
publicSecret,
),
);
if (success && result) {
setVisible(false);
message.success(intl.formatMessage({ id: 'page.user.profile.modify_password.success' }));
setRefresh(true);
return Promise.resolve();
}
const { success, result } = await changePassword({
oldPassword: formData[FieldNames.NEW_PASSWORD] as string,
newPassword: formData[FieldNames.OLD_PASSWORD] as string,
});
if (success && result) {
setVisible(false);
message.success(intl.formatMessage({ id: 'page.user.profile.modify_password.success' }));
setRefresh(true);
return Promise.resolve();
}
return Promise.reject();
}}
>
<Spin spinning={loading}>
<ProFormText.Password
placeholder={intl.formatMessage({
id: 'page.user.profile.modify_password.form.old_password.placeholder',
})}
label={intl.formatMessage({ id: 'page.user.profile.modify_password.form.old_password' })}
name={FieldNames.OLD_PASSWORD}
fieldProps={{ autoComplete: 'off' }}
rules={[
{
required: true,
message: intl.formatMessage({
id: 'page.user.profile.modify_password.form.old_password.rule.0',
}),
},
]}
/>
<ProFormText.Password
placeholder={intl.formatMessage({
id: 'page.user.profile.modify_password.form.new_password.placeholder',
@ -115,114 +116,33 @@ const ModifyPassword = (props: {
},
]}
/>
<ProFormRadio.Group
name={FieldNames.CHANNEL}
<ProFormText.Password
label={intl.formatMessage({
id: 'page.user.profile.modify_password.form.verify-code-type.label',
id: 'pages.setting.administrator.reset_password_modal.from.confirm_password',
})}
options={[
{
label: intl.formatMessage({
id: 'page.user.profile.modify_password.form.phone.label',
}),
value: 'sms',
},
{
label: intl.formatMessage({
id: 'page.user.profile.modify_password.form.mail.label',
}),
value: 'mail',
},
]}
placeholder={intl.formatMessage({
id: 'pages.setting.administrator.reset_password_modal.from.confirm_password.placeholder',
})}
name={'confirmPassword'}
fieldProps={{ autoComplete: 'off' }}
rules={[
{
required: true,
message: intl.formatMessage({
id: 'page.user.profile.modify_password.form.verify-code-type.rule.0',
id: 'pages.setting.administrator.reset_password_modal.from.confirm_password.rule.0.message',
}),
},
]}
/>
<ProFormDependency name={[FieldNames.CHANNEL]}>
{({ channel }) => {
if (channel === 'sms') {
return (
<ProFormText
key={'sms'}
label={intl.formatMessage({
id: 'page.user.profile.modify_password.form.phone',
})}
name={'show'}
initialValue={initialState?.currentUser?.phone}
readonly
/>
);
}
return (
<ProFormText
key={'mail'}
label={intl.formatMessage({
id: 'page.user.profile.modify_password.form.mail',
})}
name={'show'}
initialValue={initialState?.currentUser?.email}
readonly
/>
);
}}
</ProFormDependency>
<ProFormCaptcha
label={intl.formatMessage({ id: 'page.user.profile.modify_password.form.verify-code' })}
fieldProps={{
maxLength: 6,
}}
captchaProps={{}}
phoneName={'show'}
placeholder={intl.formatMessage({
id: 'pages.login.captcha.placeholder',
})}
captchaTextRender={(timing, count) => {
if (timing) {
return `${count} ${intl.formatMessage({
id: 'pages.login.phone.captcha-second-text',
})}`;
}
return intl.formatMessage({
id: 'pages.login.phone.get-opt-code',
});
}}
name={FieldNames.VERIFY_CODE}
rules={[
{
required: true,
message: <FormattedMessage id="pages.login.captcha.required" />,
},
]}
onGetCaptcha={async () => {
const validate = await formRef.current?.validateFields([FieldNames.CHANNEL]);
if (!validate) {
return;
}
let channel = formRef.current?.getFieldValue(FieldNames.CHANNEL);
const publicSecret = await onGetEncryptSecret();
if (publicSecret) {
const { success } = await prepareChangePassword(
aesEcbEncrypt(
JSON.stringify({
channel: channel as string,
}),
publicSecret,
),
);
if (success) {
message.success(
intl.formatMessage({
id: 'pages.login.phone.get-opt-code.success',
}),
({ getFieldValue }) => ({
validator(_, value) {
if (!value || getFieldValue(FieldNames.NEW_PASSWORD) === value) {
return Promise.resolve();
}
return Promise.reject(
new Error(intl.formatMessage({ id: 'app.password.not_match' })),
);
}
}
}}
},
}),
]}
/>
</Spin>
</ModalForm>

View File

@ -29,7 +29,6 @@ import {
import { App, ConfigProvider, Spin } from 'antd';
import { omit } from 'lodash';
import { useContext, useEffect, useRef, useState } from 'react';
import { FormLayout } from './constant';
import classnames from 'classnames';
import { ConfigContext } from 'antd/es/config-provider';
import { useIntl } from '@@/exports';
@ -84,7 +83,12 @@ export default (props: {
labelAlign={'right'}
preserve={false}
layout={'horizontal'}
{...FormLayout}
labelCol={{
span: 4,
}}
wrapperCol={{
span: 20,
}}
autoFocusFirstInput
open={visible}
modalProps={{

View File

@ -1,21 +0,0 @@
/*
* eiam-console - Employee Identity and Access Management
* Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
export const FormLayout = {
labelCol: { span: 4 },
wrapperCol: { span: 20 },
};

View File

@ -62,6 +62,11 @@ export default {
'page.user.profile.modify_email.form.email.rule.1': '邮箱格式不正确',
'page.user.profile.modify_password.form': '修改密码',
'page.user.profile.modify_password.success': '修改成功,请重新登录',
'page.user.profile.modify_password.form.old_password': '旧密码',
'page.user.profile.modify_password.form.old_password.placeholder': '请输入旧密码',
'page.user.profile.modify_password.form.old_password.rule.0': '请输入请输入旧密码',
'page.user.profile.modify_password.form.new_password': '新密码',
'page.user.profile.modify_password.form.new_password.placeholder': '请输入新密码',
'page.user.profile.modify_password.form.new_password.rule.0': '请输入请输入新密码',

View File

@ -109,17 +109,3 @@ export async function changeBaseInfo(
method: 'PUT',
});
}
/**
*
*/
export async function prepareChangePassword(encrypt: string): Promise<API.ApiResult<boolean>> {
return request('/api/v1/user/profile/prepare_change_password', {
method: 'POST',
data: { encrypt: encrypt },
skipErrorHandler: true,
}).catch(({ response: { data } }) => {
return data;
});
}