mirror of
https://github.com/labring/FastGPT.git
synced 2026-05-08 01:08:43 +08:00
bd966d479f
* fix: login secret * lock * env template * fix: ts * fix: ts * fix: ts
199 lines
5.7 KiB
TypeScript
199 lines
5.7 KiB
TypeScript
import React, { useEffect, type Dispatch } from 'react';
|
|
import { FormControl, Flex, Input, Button, Box } from '@chakra-ui/react';
|
|
import { useForm } from 'react-hook-form';
|
|
import { LoginPageTypeEnum } from '@/web/support/user/login/constants';
|
|
import { postLogin, getPreLogin } from '@/web/support/user/api';
|
|
import { useToast } from '@fastgpt/web/hooks/useToast';
|
|
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
|
import { useTranslation } from 'next-i18next';
|
|
import FormLayout from './FormLayout';
|
|
import { useRequest } from '@fastgpt/web/hooks/useRequest';
|
|
import PolicyTip from './PolicyTip';
|
|
import { useSearchParams } from 'next/navigation';
|
|
import { UserErrEnum } from '@fastgpt/global/common/error/code/user';
|
|
import { useRouter } from 'next/router';
|
|
import { useMount } from 'ahooks';
|
|
import type { LangEnum } from '@fastgpt/global/common/i18n/type';
|
|
import type { LoginSuccessResponseType } from '@fastgpt/global/openapi/support/user/account/login/api';
|
|
|
|
interface Props {
|
|
setPageType: Dispatch<`${LoginPageTypeEnum}`>;
|
|
loginSuccess: (e: LoginSuccessResponseType) => void;
|
|
}
|
|
|
|
interface LoginFormType {
|
|
username: string;
|
|
password: string;
|
|
}
|
|
|
|
const LoginForm = ({ setPageType, loginSuccess }: Props) => {
|
|
const { t, i18n } = useTranslation();
|
|
const { feConfigs } = useSystemStore();
|
|
const query = useSearchParams();
|
|
const router = useRouter();
|
|
|
|
const {
|
|
register,
|
|
handleSubmit,
|
|
formState: { errors }
|
|
} = useForm<LoginFormType>();
|
|
|
|
const { runAsync: onclickLogin, loading: requesting } = useRequest(
|
|
async ({ username, password }: LoginFormType) => {
|
|
const { code } = await getPreLogin(username);
|
|
loginSuccess(
|
|
await postLogin({
|
|
username,
|
|
password,
|
|
code,
|
|
language: i18n.language as LangEnum
|
|
})
|
|
);
|
|
},
|
|
{
|
|
refreshDeps: [loginSuccess],
|
|
successToast: t('login:login_success'),
|
|
onError: (error: any) => {
|
|
// 密码错误,需要清空 query 参数
|
|
if (error.statusText === UserErrEnum.account_psw_error) {
|
|
router.replace(
|
|
router.pathname,
|
|
{
|
|
query: {
|
|
...router.query,
|
|
u: '',
|
|
p: ''
|
|
}
|
|
},
|
|
{
|
|
shallow: false
|
|
}
|
|
);
|
|
}
|
|
}
|
|
}
|
|
);
|
|
|
|
const isCommunityVersion = !!(feConfigs?.register_method && !feConfigs?.isPlus);
|
|
|
|
const placeholder = (() => {
|
|
if (isCommunityVersion) {
|
|
return t('login:use_root_login');
|
|
}
|
|
return [t('common:support.user.login.Username')]
|
|
.concat(
|
|
feConfigs?.login_method?.map((item) => {
|
|
switch (item) {
|
|
case 'email':
|
|
return t('common:support.user.login.Email');
|
|
case 'phone':
|
|
return t('common:support.user.login.Phone number');
|
|
}
|
|
}) ?? []
|
|
)
|
|
.join('/');
|
|
})();
|
|
|
|
useMount(() => {
|
|
const username = query.get('u');
|
|
const password = query.get('p');
|
|
if (username && password) {
|
|
onclickLogin({
|
|
username,
|
|
password
|
|
});
|
|
}
|
|
});
|
|
|
|
return (
|
|
<FormLayout setPageType={setPageType} pageType={LoginPageTypeEnum.passwordLogin}>
|
|
<Box
|
|
mt={8}
|
|
onKeyDown={(e) => {
|
|
if (e.key === 'Enter' && !e.shiftKey && !requesting) {
|
|
handleSubmit(onclickLogin)();
|
|
}
|
|
}}
|
|
>
|
|
<FormControl isInvalid={!!errors.username}>
|
|
<Input
|
|
bg={'myGray.50'}
|
|
size={'lg'}
|
|
placeholder={placeholder}
|
|
{...register('username', {
|
|
required: true
|
|
})}
|
|
></Input>
|
|
</FormControl>
|
|
<FormControl mt={7} isInvalid={!!errors.password}>
|
|
<Input
|
|
bg={'myGray.50'}
|
|
size={'lg'}
|
|
type={'password'}
|
|
placeholder={
|
|
isCommunityVersion
|
|
? t('login:root_password_placeholder')
|
|
: t('common:support.user.login.Password')
|
|
}
|
|
{...register('password', {
|
|
required: true,
|
|
maxLength: {
|
|
value: 60,
|
|
message: t('login:password_condition')
|
|
}
|
|
})}
|
|
></Input>
|
|
</FormControl>
|
|
<PolicyTip isCenter={false} />
|
|
|
|
<Button
|
|
type="submit"
|
|
my={[5, 7]}
|
|
w={'100%'}
|
|
size={['md', 'md']}
|
|
h={[10, 10]}
|
|
fontWeight={['medium', 'medium']}
|
|
colorScheme="blue"
|
|
isLoading={requesting}
|
|
onClick={handleSubmit(onclickLogin)}
|
|
>
|
|
{t('login:Login')}
|
|
</Button>
|
|
|
|
<Flex
|
|
align={'center'}
|
|
justifyContent={['flex-end', 'center']}
|
|
color={'primary.700'}
|
|
fontWeight={'medium'}
|
|
>
|
|
{feConfigs?.find_password_method && feConfigs.find_password_method.length > 0 && (
|
|
<Box
|
|
cursor={'pointer'}
|
|
_hover={{ textDecoration: 'underline' }}
|
|
onClick={() => setPageType('forgetPassword')}
|
|
fontSize="mini"
|
|
>
|
|
{t('login:forget_password')}
|
|
</Box>
|
|
)}
|
|
{feConfigs?.register_method && feConfigs.register_method.length > 0 && (
|
|
<Flex alignItems={'center'}>
|
|
<Box mx={3} h={'12px'} w={'1px'} bg={'myGray.250'}></Box>
|
|
<Box
|
|
cursor={'pointer'}
|
|
_hover={{ textDecoration: 'underline' }}
|
|
onClick={() => setPageType('register')}
|
|
fontSize="mini"
|
|
>
|
|
{t('login:register')}
|
|
</Box>
|
|
</Flex>
|
|
)}
|
|
</Flex>
|
|
</Box>
|
|
</FormLayout>
|
|
);
|
|
};
|
|
|
|
export default LoginForm;
|