mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-23 05:12:39 +00:00
@@ -647,7 +647,8 @@
|
|||||||
"success": "Start syncing"
|
"success": "Start syncing"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"training": {}
|
"training": {
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"data": {
|
"data": {
|
||||||
"Auxiliary Data": "Auxiliary data",
|
"Auxiliary Data": "Auxiliary data",
|
||||||
@@ -1084,13 +1085,15 @@
|
|||||||
"default_reply": "Default reply",
|
"default_reply": "Default reply",
|
||||||
"error": {
|
"error": {
|
||||||
"Create failed": "Create failed",
|
"Create failed": "Create failed",
|
||||||
|
"code_error": "Code error",
|
||||||
"fileNotFound": "File not found~",
|
"fileNotFound": "File not found~",
|
||||||
"inheritPermissionError": "Inherit permission Error",
|
"inheritPermissionError": "Inherit permission Error",
|
||||||
"missingParams": "Insufficient parameters",
|
"missingParams": "Insufficient parameters",
|
||||||
"team": {
|
"team": {
|
||||||
"overSize": "Team members exceed the limit"
|
"overSize": "Team members exceed the limit"
|
||||||
},
|
},
|
||||||
"upload_file_error_filename": "{{name}} upload failed"
|
"upload_file_error_filename": "{{name}} upload failed",
|
||||||
|
"username_empty": "Account cannot be empty"
|
||||||
},
|
},
|
||||||
"extraction_results": "Extract results",
|
"extraction_results": "Extract results",
|
||||||
"field_name": "Name",
|
"field_name": "Name",
|
||||||
|
@@ -647,7 +647,8 @@
|
|||||||
"success": "开始同步"
|
"success": "开始同步"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"training": {}
|
"training": {
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"data": {
|
"data": {
|
||||||
"Auxiliary Data": "辅助数据",
|
"Auxiliary Data": "辅助数据",
|
||||||
@@ -1084,13 +1085,15 @@
|
|||||||
"default_reply": "默认回复",
|
"default_reply": "默认回复",
|
||||||
"error": {
|
"error": {
|
||||||
"Create failed": "创建失败",
|
"Create failed": "创建失败",
|
||||||
|
"code_error": "验证码错误",
|
||||||
"fileNotFound": "文件找不到了~",
|
"fileNotFound": "文件找不到了~",
|
||||||
"inheritPermissionError": "权限继承错误",
|
"inheritPermissionError": "权限继承错误",
|
||||||
"missingParams": "参数缺失",
|
"missingParams": "参数缺失",
|
||||||
"team": {
|
"team": {
|
||||||
"overSize": "团队成员超出上限"
|
"overSize": "团队成员超出上限"
|
||||||
},
|
},
|
||||||
"upload_file_error_filename": "{{name}} 上传失败"
|
"upload_file_error_filename": "{{name}} 上传失败",
|
||||||
|
"username_empty": "账号不能为空"
|
||||||
},
|
},
|
||||||
"extraction_results": "提取结果",
|
"extraction_results": "提取结果",
|
||||||
"field_name": "字段名",
|
"field_name": "字段名",
|
||||||
@@ -1247,7 +1250,6 @@
|
|||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"Avatar": "头像",
|
"Avatar": "头像",
|
||||||
"captcha_placeholder": "请输入验证码",
|
|
||||||
"Go laf env": "点击前往 {{env}} 获取 PAT 凭证。",
|
"Go laf env": "点击前往 {{env}} 获取 PAT 凭证。",
|
||||||
"Laf account course": "查看绑定 laf 账号教程。",
|
"Laf account course": "查看绑定 laf 账号教程。",
|
||||||
"Laf account intro": "绑定你的 laf 账号后,你将可以在工作流中使用 laf 模块,实现在线编写代码。",
|
"Laf account intro": "绑定你的 laf 账号后,你将可以在工作流中使用 laf 模块,实现在线编写代码。",
|
||||||
@@ -1257,6 +1259,7 @@
|
|||||||
"auth": {
|
"auth": {
|
||||||
"Sending Code": "正在发送"
|
"Sending Code": "正在发送"
|
||||||
},
|
},
|
||||||
|
"captcha_placeholder": "请输入验证码",
|
||||||
"inform": {
|
"inform": {
|
||||||
"System message": "系统消息"
|
"System message": "系统消息"
|
||||||
},
|
},
|
||||||
|
@@ -75,8 +75,8 @@ COPY ./projects/app/data /app/data
|
|||||||
|
|
||||||
RUN chown -R nextjs:nodejs /app/data
|
RUN chown -R nextjs:nodejs /app/data
|
||||||
|
|
||||||
ENV NODE_ENV production
|
ENV NODE_ENV=production
|
||||||
ENV NEXT_TELEMETRY_DISABLED 1
|
ENV NEXT_TELEMETRY_DISABLED=1
|
||||||
ENV PORT=3000
|
ENV PORT=3000
|
||||||
|
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
|
@@ -1,58 +1,72 @@
|
|||||||
import { getCaptchaPic } from '@/web/support/user/api';
|
import { getCaptchaPic } from '@/web/support/user/api';
|
||||||
import { useSendCode } from '@/web/support/user/hooks/useSendCode';
|
import { Button, Input, Image, ModalBody, ModalFooter, Skeleton } from '@chakra-ui/react';
|
||||||
import { Box, Button, Input, Image, ModalBody, ModalFooter } from '@chakra-ui/react';
|
|
||||||
import { UserAuthTypeEnum } from '@fastgpt/global/support/user/auth/constants';
|
|
||||||
import MyModal from '@fastgpt/web/components/common/MyModal';
|
import MyModal from '@fastgpt/web/components/common/MyModal';
|
||||||
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { useState } from 'react';
|
import { useForm } from 'react-hook-form';
|
||||||
|
|
||||||
const SendCodeAuthModal = ({
|
const SendCodeAuthModal = ({
|
||||||
username,
|
username,
|
||||||
type,
|
onClose,
|
||||||
onClose
|
onSending,
|
||||||
|
onSendCode
|
||||||
}: {
|
}: {
|
||||||
username: string;
|
username: string;
|
||||||
type: UserAuthTypeEnum;
|
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
|
|
||||||
|
onSending: boolean;
|
||||||
|
onSendCode: (params_0: { username: string; captcha: string }) => Promise<void>;
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [captchaInput, setCaptchaInput] = useState('');
|
|
||||||
const { codeSending, sendCode } = useSendCode();
|
const { register, handleSubmit } = useForm({
|
||||||
|
defaultValues: {
|
||||||
|
code: ''
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data,
|
data,
|
||||||
loading,
|
loading,
|
||||||
runAsync: getCaptcha
|
runAsync: getCaptcha
|
||||||
} = useRequest2(() => getCaptchaPic(username), { manual: false });
|
} = useRequest2(() => getCaptchaPic(username), { manual: false });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MyModal isOpen={true} isLoading={loading}>
|
<MyModal isOpen={true}>
|
||||||
<ModalBody pt={8}>
|
<ModalBody pt={8}>
|
||||||
<Image
|
<Skeleton
|
||||||
borderRadius={'md'}
|
minH="200px"
|
||||||
w={'100%'}
|
isLoaded={!loading}
|
||||||
h={'200px'}
|
fadeDuration={2}
|
||||||
_hover={{ cursor: 'pointer' }}
|
display={'flex'}
|
||||||
mb={8}
|
justifyContent={'center'}
|
||||||
onClick={getCaptcha}
|
my={1}
|
||||||
src={data?.captchaImage}
|
>
|
||||||
alt="captcha"
|
<Image
|
||||||
/>
|
borderRadius={'md'}
|
||||||
<Input
|
w={'100%'}
|
||||||
placeholder={t('common:support.user.captcha_placeholder')}
|
h={'200px'}
|
||||||
value={captchaInput}
|
_hover={{ cursor: 'pointer' }}
|
||||||
onChange={(e) => setCaptchaInput(e.target.value)}
|
mb={8}
|
||||||
/>
|
onClick={getCaptcha}
|
||||||
|
src={data?.captchaImage}
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
</Skeleton>
|
||||||
|
|
||||||
|
<Input placeholder={t('common:support.user.captcha_placeholder')} {...register('code')} />
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
<ModalFooter gap={2}>
|
<ModalFooter gap={2}>
|
||||||
<Button isLoading={codeSending} variant={'whiteBase'} onClick={onClose}>
|
<Button isLoading={onSending} variant={'whiteBase'} onClick={onClose}>
|
||||||
{t('common:common.Cancel')}
|
{t('common:common.Cancel')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
isLoading={codeSending}
|
isLoading={onSending}
|
||||||
onClick={async () => {
|
onClick={handleSubmit(({ code }) => {
|
||||||
await sendCode({ username, type, captcha: captchaInput });
|
return onSendCode({ username, captcha: code }).then(() => {
|
||||||
onClose();
|
onClose();
|
||||||
}}
|
});
|
||||||
|
})}
|
||||||
>
|
>
|
||||||
{t('common:common.Confirm')}
|
{t('common:common.Confirm')}
|
||||||
</Button>
|
</Button>
|
||||||
|
@@ -18,8 +18,6 @@ import Icon from '@fastgpt/web/components/common/Icon';
|
|||||||
import { useSendCode } from '@/web/support/user/hooks/useSendCode';
|
import { useSendCode } from '@/web/support/user/hooks/useSendCode';
|
||||||
import { useUserStore } from '@/web/support/user/useUserStore';
|
import { useUserStore } from '@/web/support/user/useUserStore';
|
||||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||||
import SendCodeAuthModal from '@/components/support/user/safe/SendCodeAuthModal';
|
|
||||||
import { UserAuthTypeEnum } from '@fastgpt/global/support/user/auth/constants';
|
|
||||||
|
|
||||||
type FormType = {
|
type FormType = {
|
||||||
account: string;
|
account: string;
|
||||||
@@ -30,7 +28,8 @@ const UpdateNotificationModal = ({ onClose }: { onClose: () => void }) => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { initUserInfo } = useUserStore();
|
const { initUserInfo } = useUserStore();
|
||||||
const { feConfigs } = useSystemStore();
|
const { feConfigs } = useSystemStore();
|
||||||
const { register, handleSubmit, trigger, getValues, watch } = useForm<FormType>({
|
|
||||||
|
const { register, handleSubmit, watch } = useForm<FormType>({
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
account: '',
|
account: '',
|
||||||
verifyCode: ''
|
verifyCode: ''
|
||||||
@@ -38,11 +37,7 @@ const UpdateNotificationModal = ({ onClose }: { onClose: () => void }) => {
|
|||||||
});
|
});
|
||||||
const account = watch('account');
|
const account = watch('account');
|
||||||
const verifyCode = watch('verifyCode');
|
const verifyCode = watch('verifyCode');
|
||||||
const {
|
|
||||||
isOpen: openCodeAuthModal,
|
|
||||||
onOpen: onOpenCodeAuthModal,
|
|
||||||
onClose: onCloseCodeAuthModal
|
|
||||||
} = useDisclosure();
|
|
||||||
const { runAsync: onSubmit, loading: isLoading } = useRequest2(
|
const { runAsync: onSubmit, loading: isLoading } = useRequest2(
|
||||||
(data: FormType) => {
|
(data: FormType) => {
|
||||||
return updateNotificationAccount(data);
|
return updateNotificationAccount(data);
|
||||||
@@ -57,13 +52,7 @@ const UpdateNotificationModal = ({ onClose }: { onClose: () => void }) => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const { sendCodeText, codeCountDown } = useSendCode();
|
const { SendCodeBox } = useSendCode({ type: 'bindNotification' });
|
||||||
|
|
||||||
const onclickSendCode = useCallback(async () => {
|
|
||||||
const check = await trigger('account');
|
|
||||||
if (!check) return;
|
|
||||||
onOpenCodeAuthModal();
|
|
||||||
}, [onOpenCodeAuthModal, trigger]);
|
|
||||||
|
|
||||||
const placeholder = feConfigs?.bind_notification_method
|
const placeholder = feConfigs?.bind_notification_method
|
||||||
?.map((item) => {
|
?.map((item) => {
|
||||||
@@ -107,23 +96,7 @@ const UpdateNotificationModal = ({ onClose }: { onClose: () => void }) => {
|
|||||||
{...register('verifyCode', { required: true })}
|
{...register('verifyCode', { required: true })}
|
||||||
placeholder={t('user:password.code_required')}
|
placeholder={t('user:password.code_required')}
|
||||||
></Input>
|
></Input>
|
||||||
<Box
|
<SendCodeBox username={account} />
|
||||||
position={'absolute'}
|
|
||||||
right={2}
|
|
||||||
zIndex={1}
|
|
||||||
fontSize={'sm'}
|
|
||||||
{...(codeCountDown > 0
|
|
||||||
? {
|
|
||||||
color: 'myGray.500'
|
|
||||||
}
|
|
||||||
: {
|
|
||||||
color: 'primary.700',
|
|
||||||
cursor: 'pointer',
|
|
||||||
onClick: onclickSendCode
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
{sendCodeText}
|
|
||||||
</Box>
|
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
@@ -140,13 +113,6 @@ const UpdateNotificationModal = ({ onClose }: { onClose: () => void }) => {
|
|||||||
</Button>
|
</Button>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
</MyModal>
|
</MyModal>
|
||||||
{openCodeAuthModal && (
|
|
||||||
<SendCodeAuthModal
|
|
||||||
onClose={onCloseCodeAuthModal}
|
|
||||||
username={getValues('account')}
|
|
||||||
type={UserAuthTypeEnum.bindNotification}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@@ -8,8 +8,8 @@ import type { ResLogin } from '@/global/support/api/userRes.d';
|
|||||||
import { useToast } from '@fastgpt/web/hooks/useToast';
|
import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { UserAuthTypeEnum } from '@fastgpt/global/support/user/auth/constants';
|
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||||
import SendCodeAuthModal from '@/components/support/user/safe/SendCodeAuthModal';
|
|
||||||
interface Props {
|
interface Props {
|
||||||
setPageType: Dispatch<`${LoginPageTypeEnum}`>;
|
setPageType: Dispatch<`${LoginPageTypeEnum}`>;
|
||||||
loginSuccess: (e: ResLogin) => void;
|
loginSuccess: (e: ResLogin) => void;
|
||||||
@@ -30,25 +30,15 @@ const RegisterForm = ({ setPageType, loginSuccess }: Props) => {
|
|||||||
register,
|
register,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
getValues,
|
getValues,
|
||||||
trigger,
|
watch,
|
||||||
formState: { errors }
|
formState: { errors }
|
||||||
} = useForm<RegisterType>({
|
} = useForm<RegisterType>({
|
||||||
mode: 'onBlur'
|
mode: 'onBlur'
|
||||||
});
|
});
|
||||||
|
const username = watch('username');
|
||||||
|
|
||||||
const { sendCodeText, codeCountDown } = useSendCode();
|
const { SendCodeBox } = useSendCode({ type: 'findPassword' });
|
||||||
const {
|
|
||||||
isOpen: openCodeAuthModal,
|
|
||||||
onOpen: onOpenCodeAuthModal,
|
|
||||||
onClose: onCloseCodeAuthModal
|
|
||||||
} = useDisclosure();
|
|
||||||
const onclickSendCode = useCallback(async () => {
|
|
||||||
const check = await trigger('username');
|
|
||||||
if (!check) return;
|
|
||||||
onOpenCodeAuthModal();
|
|
||||||
}, [onOpenCodeAuthModal, trigger]);
|
|
||||||
|
|
||||||
const [requesting, setRequesting] = useState(false);
|
|
||||||
const placeholder = feConfigs?.find_password_method
|
const placeholder = feConfigs?.find_password_method
|
||||||
?.map((item) => {
|
?.map((item) => {
|
||||||
switch (item) {
|
switch (item) {
|
||||||
@@ -62,30 +52,23 @@ const RegisterForm = ({ setPageType, loginSuccess }: Props) => {
|
|||||||
})
|
})
|
||||||
.join('/');
|
.join('/');
|
||||||
|
|
||||||
const onclickFindPassword = useCallback(
|
const { runAsync: onclickFindPassword, loading: requesting } = useRequest2(
|
||||||
async ({ username, code, password }: RegisterType) => {
|
async ({ username, code, password }: RegisterType) => {
|
||||||
setRequesting(true);
|
loginSuccess(
|
||||||
try {
|
await postFindPassword({
|
||||||
loginSuccess(
|
username,
|
||||||
await postFindPassword({
|
code,
|
||||||
username,
|
password
|
||||||
code,
|
})
|
||||||
password
|
);
|
||||||
})
|
toast({
|
||||||
);
|
status: 'success',
|
||||||
toast({
|
title: t('user:password.retrieved')
|
||||||
title: t('user:password.retrieved'),
|
});
|
||||||
status: 'success'
|
|
||||||
});
|
|
||||||
} catch (error: any) {
|
|
||||||
toast({
|
|
||||||
title: error.message || t('user:password.change_error'),
|
|
||||||
status: 'error'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
setRequesting(false);
|
|
||||||
},
|
},
|
||||||
[loginSuccess, toast]
|
{
|
||||||
|
refreshDeps: [loginSuccess, t, toast]
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -131,23 +114,7 @@ const RegisterForm = ({ setPageType, loginSuccess }: Props) => {
|
|||||||
required: t('user:password.code_required')
|
required: t('user:password.code_required')
|
||||||
})}
|
})}
|
||||||
></Input>
|
></Input>
|
||||||
<Box
|
<SendCodeBox username={username} />
|
||||||
position={'absolute'}
|
|
||||||
right={3}
|
|
||||||
zIndex={1}
|
|
||||||
fontSize={'sm'}
|
|
||||||
{...(codeCountDown > 0
|
|
||||||
? {
|
|
||||||
color: 'myGray.500'
|
|
||||||
}
|
|
||||||
: {
|
|
||||||
color: 'primary.700',
|
|
||||||
cursor: 'pointer',
|
|
||||||
onClick: onclickSendCode
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
{sendCodeText}
|
|
||||||
</Box>
|
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormControl mt={6} isInvalid={!!errors.password}>
|
<FormControl mt={6} isInvalid={!!errors.password}>
|
||||||
<Input
|
<Input
|
||||||
@@ -203,13 +170,6 @@ const RegisterForm = ({ setPageType, loginSuccess }: Props) => {
|
|||||||
{t('user:password.to_login')}
|
{t('user:password.to_login')}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
{openCodeAuthModal && (
|
|
||||||
<SendCodeAuthModal
|
|
||||||
onClose={onCloseCodeAuthModal}
|
|
||||||
username={getValues('username')}
|
|
||||||
type={UserAuthTypeEnum.findPassword}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import React, { useState, Dispatch, useCallback } from 'react';
|
import React, { Dispatch } from 'react';
|
||||||
import { FormControl, Box, Input, Button, useDisclosure } from '@chakra-ui/react';
|
import { FormControl, Box, Input, Button } from '@chakra-ui/react';
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import { LoginPageTypeEnum } from '@/web/support/user/login/constants';
|
import { LoginPageTypeEnum } from '@/web/support/user/login/constants';
|
||||||
import { postRegister } from '@/web/support/user/api';
|
import { postRegister } from '@/web/support/user/api';
|
||||||
@@ -12,8 +12,7 @@ import { useSystemStore } from '@/web/common/system/useSystemStore';
|
|||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
|
import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
|
||||||
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||||
import SendCodeAuthModal from '@/components/support/user/safe/SendCodeAuthModal';
|
|
||||||
import { UserAuthTypeEnum } from '@fastgpt/global/support/user/auth/constants';
|
|
||||||
interface Props {
|
interface Props {
|
||||||
loginSuccess: (e: ResLogin) => void;
|
loginSuccess: (e: ResLogin) => void;
|
||||||
setPageType: Dispatch<`${LoginPageTypeEnum}`>;
|
setPageType: Dispatch<`${LoginPageTypeEnum}`>;
|
||||||
@@ -35,63 +34,47 @@ const RegisterForm = ({ setPageType, loginSuccess }: Props) => {
|
|||||||
register,
|
register,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
getValues,
|
getValues,
|
||||||
trigger,
|
watch,
|
||||||
formState: { errors }
|
formState: { errors }
|
||||||
} = useForm<RegisterType>({
|
} = useForm<RegisterType>({
|
||||||
mode: 'onBlur'
|
mode: 'onBlur'
|
||||||
});
|
});
|
||||||
const {
|
const username = watch('username');
|
||||||
isOpen: openCodeAuthModal,
|
|
||||||
onOpen: onOpenCodeAuthModal,
|
|
||||||
onClose: onCloseCodeAuthModal
|
|
||||||
} = useDisclosure();
|
|
||||||
const { sendCodeText, codeCountDown } = useSendCode();
|
|
||||||
|
|
||||||
const onclickSendCode = useCallback(async () => {
|
const { SendCodeBox } = useSendCode({ type: 'register' });
|
||||||
const check = await trigger('username');
|
|
||||||
if (!check) return;
|
|
||||||
onOpenCodeAuthModal();
|
|
||||||
}, [onOpenCodeAuthModal, trigger]);
|
|
||||||
|
|
||||||
const [requesting, setRequesting] = useState(false);
|
const { runAsync: onclickRegister, loading: requesting } = useRequest2(
|
||||||
|
|
||||||
const onclickRegister = useCallback(
|
|
||||||
async ({ username, password, code }: RegisterType) => {
|
async ({ username, password, code }: RegisterType) => {
|
||||||
setRequesting(true);
|
loginSuccess(
|
||||||
try {
|
await postRegister({
|
||||||
loginSuccess(
|
username,
|
||||||
await postRegister({
|
code,
|
||||||
username,
|
password,
|
||||||
code,
|
inviterId: localStorage.getItem('inviterId') || undefined
|
||||||
password,
|
})
|
||||||
inviterId: localStorage.getItem('inviterId') || undefined
|
);
|
||||||
})
|
|
||||||
);
|
toast({
|
||||||
toast({
|
status: 'success',
|
||||||
title: t('user:register.success'),
|
title: t('user:register.success')
|
||||||
status: 'success'
|
});
|
||||||
});
|
|
||||||
// auto register template app
|
// auto register template app
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
Object.entries(emptyTemplates).map(([type, emptyTemplate]) => {
|
Object.entries(emptyTemplates).map(([type, emptyTemplate]) => {
|
||||||
postCreateApp({
|
postCreateApp({
|
||||||
avatar: emptyTemplate.avatar,
|
avatar: emptyTemplate.avatar,
|
||||||
name: t(emptyTemplate.name as any),
|
name: t(emptyTemplate.name as any),
|
||||||
modules: emptyTemplate.nodes,
|
modules: emptyTemplate.nodes,
|
||||||
edges: emptyTemplate.edges,
|
edges: emptyTemplate.edges,
|
||||||
type: type as AppTypeEnum
|
type: type as AppTypeEnum
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}, 100);
|
|
||||||
} catch (error: any) {
|
|
||||||
toast({
|
|
||||||
title: error.message || t('user:register.error'),
|
|
||||||
status: 'error'
|
|
||||||
});
|
});
|
||||||
}
|
}, 100);
|
||||||
setRequesting(false);
|
|
||||||
},
|
},
|
||||||
[loginSuccess, t, toast]
|
{
|
||||||
|
refreshDeps: [loginSuccess, t, toast]
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const placeholder = feConfigs?.register_method
|
const placeholder = feConfigs?.register_method
|
||||||
@@ -148,23 +131,7 @@ const RegisterForm = ({ setPageType, loginSuccess }: Props) => {
|
|||||||
required: t('user:password.code_required')
|
required: t('user:password.code_required')
|
||||||
})}
|
})}
|
||||||
></Input>
|
></Input>
|
||||||
<Box
|
<SendCodeBox username={username} />
|
||||||
position={'absolute'}
|
|
||||||
right={3}
|
|
||||||
zIndex={1}
|
|
||||||
fontSize={'sm'}
|
|
||||||
{...(codeCountDown > 0
|
|
||||||
? {
|
|
||||||
color: 'myGray.500'
|
|
||||||
}
|
|
||||||
: {
|
|
||||||
color: 'primary.700',
|
|
||||||
cursor: 'pointer',
|
|
||||||
onClick: onclickSendCode
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
{sendCodeText}
|
|
||||||
</Box>
|
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormControl mt={6} isInvalid={!!errors.password}>
|
<FormControl mt={6} isInvalid={!!errors.password}>
|
||||||
<Input
|
<Input
|
||||||
@@ -219,13 +186,6 @@ const RegisterForm = ({ setPageType, loginSuccess }: Props) => {
|
|||||||
{t('user:register.to_login')}
|
{t('user:register.to_login')}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
{openCodeAuthModal && (
|
|
||||||
<SendCodeAuthModal
|
|
||||||
onClose={onCloseCodeAuthModal}
|
|
||||||
username={getValues('username')}
|
|
||||||
type={UserAuthTypeEnum.register}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@@ -87,4 +87,4 @@ export const getWXLoginResult = (code: string) =>
|
|||||||
export const getCaptchaPic = (username: string) =>
|
export const getCaptchaPic = (username: string) =>
|
||||||
GET<{
|
GET<{
|
||||||
captchaImage: string;
|
captchaImage: string;
|
||||||
}>('/proApi/support/user/account/captcha', { username });
|
}>('/proApi/support/user/account/captcha/getImgCaptcha', { username });
|
||||||
|
@@ -4,26 +4,24 @@ import { UserAuthTypeEnum } from '@fastgpt/global/support/user/auth/constants';
|
|||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||||
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||||
|
import { Box, BoxProps, useDisclosure } from '@chakra-ui/react';
|
||||||
|
import SendCodeAuthModal from '@/components/support/user/safe/SendCodeAuthModal';
|
||||||
|
import { useMemoizedFn } from 'ahooks';
|
||||||
|
import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||||
let timer: NodeJS.Timeout;
|
let timer: NodeJS.Timeout;
|
||||||
|
|
||||||
export const useSendCode = () => {
|
export const useSendCode = ({ type }: { type: `${UserAuthTypeEnum}` }) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { feConfigs } = useSystemStore();
|
const { feConfigs } = useSystemStore();
|
||||||
|
const { toast } = useToast();
|
||||||
const [codeCountDown, setCodeCountDown] = useState(0);
|
const [codeCountDown, setCodeCountDown] = useState(0);
|
||||||
|
|
||||||
const { runAsync: sendCode, loading: codeSending } = useRequest2(
|
const { runAsync: sendCode, loading: codeSending } = useRequest2(
|
||||||
async ({
|
async ({ username, captcha }: { username: string; captcha: string }) => {
|
||||||
username,
|
|
||||||
type,
|
|
||||||
captcha
|
|
||||||
}: {
|
|
||||||
username: string;
|
|
||||||
type: `${UserAuthTypeEnum}`;
|
|
||||||
captcha: string;
|
|
||||||
}) => {
|
|
||||||
if (codeCountDown > 0) return;
|
if (codeCountDown > 0) return;
|
||||||
const googleToken = await getClientToken(feConfigs.googleClientVerKey);
|
const googleToken = await getClientToken(feConfigs.googleClientVerKey);
|
||||||
await sendAuthCode({ username, type, googleToken, captcha });
|
await sendAuthCode({ username, type, googleToken, captcha });
|
||||||
|
|
||||||
setCodeCountDown(60);
|
setCodeCountDown(60);
|
||||||
|
|
||||||
timer = setInterval(() => {
|
timer = setInterval(() => {
|
||||||
@@ -38,7 +36,7 @@ export const useSendCode = () => {
|
|||||||
{
|
{
|
||||||
successToast: t('user:password.code_sended'),
|
successToast: t('user:password.code_sended'),
|
||||||
errorToast: t('user:password.code_send_error'),
|
errorToast: t('user:password.code_send_error'),
|
||||||
refreshDeps: [codeCountDown, feConfigs?.googleClientVerKey]
|
refreshDeps: [codeCountDown, type, feConfigs?.googleClientVerKey]
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -53,11 +51,60 @@ export const useSendCode = () => {
|
|||||||
return t('user:password.get_code');
|
return t('user:password.get_code');
|
||||||
}, [codeCountDown, codeSending, t]);
|
}, [codeCountDown, codeSending, t]);
|
||||||
|
|
||||||
|
const {
|
||||||
|
isOpen: openCodeAuthModal,
|
||||||
|
onOpen: onOpenCodeAuthModal,
|
||||||
|
onClose: onCloseCodeAuthModal
|
||||||
|
} = useDisclosure();
|
||||||
|
|
||||||
|
const SendCodeBox = useMemoizedFn(({ username, ...styles }: BoxProps & { username: string }) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Box
|
||||||
|
position={'absolute'}
|
||||||
|
right={3}
|
||||||
|
zIndex={1}
|
||||||
|
fontSize={'sm'}
|
||||||
|
{...styles}
|
||||||
|
{...(codeCountDown > 0
|
||||||
|
? {
|
||||||
|
color: 'myGray.500'
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
color: 'primary.700',
|
||||||
|
cursor: 'pointer',
|
||||||
|
onClick: () => {
|
||||||
|
if (!username) {
|
||||||
|
toast({
|
||||||
|
status: 'warning',
|
||||||
|
title: t('common:error.username_empty')
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
onOpenCodeAuthModal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
{sendCodeText}
|
||||||
|
</Box>
|
||||||
|
{openCodeAuthModal && (
|
||||||
|
<SendCodeAuthModal
|
||||||
|
onClose={onCloseCodeAuthModal}
|
||||||
|
username={username}
|
||||||
|
onSending={codeSending}
|
||||||
|
onSendCode={sendCode}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
codeSending,
|
codeSending,
|
||||||
sendCode,
|
sendCode,
|
||||||
sendCodeText,
|
sendCodeText,
|
||||||
codeCountDown
|
codeCountDown,
|
||||||
|
SendCodeBox
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
Reference in New Issue
Block a user