diff --git a/src/api/user.api.ts b/src/api/user.api.ts index da5c92b..3c4e620 100644 --- a/src/api/user.api.ts +++ b/src/api/user.api.ts @@ -4,6 +4,7 @@ import { LoginInputDto, RegisterInputDto, ForgetPasswordInputDto, + DeleteUser, Token, TokenRefreshPayload, User, @@ -21,6 +22,10 @@ export async function forgetPassword(data: ForgetPasswordInputDto) { return axios.patch('/api/users/password', data) } +export async function deleteUser(data: DeleteUser) { + return axios.delete('/api/users/me', { data }) +} + let refreshing: Promise> | null export async function refreshToken(data: TokenRefreshPayload) { if (!refreshing) { diff --git a/src/api/user.interface.ts b/src/api/user.interface.ts index 4a4ed43..a84504e 100644 --- a/src/api/user.interface.ts +++ b/src/api/user.interface.ts @@ -18,6 +18,11 @@ export interface ForgetPasswordInputDto extends EmailVerifyDto { password: string } +/** 删除账户入参 */ +export interface DeleteUser extends EmailVerifyDto { + password: string +} + export interface Token { accessToken: string refreshToken: string diff --git a/src/pages/components/DeleteUser.tsx b/src/pages/components/DeleteUser.tsx new file mode 100644 index 0000000..65bf4b8 --- /dev/null +++ b/src/pages/components/DeleteUser.tsx @@ -0,0 +1,146 @@ +import * as React from 'react' +import { useUser } from '@/utils/useUser' +import { useFormik } from 'formik' +import { useRouter } from 'next/router' +import Button from '@mui/material/Button' +import TextField from '@mui/material/TextField' +import Dialog from '@mui/material/Dialog' +import DialogActions from '@mui/material/DialogActions' +import DialogContent from '@mui/material/DialogContent' +import DialogContentText from '@mui/material/DialogContentText' +import DialogTitle from '@mui/material/DialogTitle' +import Grid from '@mui/material/Unstable_Grid2' +import { DeleteUser } from '@/api/user.interface' +import { EmailVerifyCodeScene } from '@/api/email.interface' +import * as yup from '@/utils/validation' +import * as api from '@/api' +import { useCountdown, COUNTDOWN_SECONDS } from '@/utils/useCountdown' +import { toast } from 'react-toastify' + +export function DeleteUser() { + const { user } = useUser() + const router = useRouter() + const [open, setOpen] = React.useState(false) + const [confirm, setConfrim] = React.useState(false) + const { countdown, setCountdown } = useCountdown() + + const formik = useFormik({ + initialValues: { + email: user!.email, + password: '', + verifyCode: '', + token: '', + }, + validateOnChange: false, + validationSchema: yup.object({ + verifyCode: yup.verifyCodeSchema, + }), + onSubmit: async (values) => { + await api.user.deleteUser(values) + localStorage.removeItem('accessToken') + localStorage.removeItem('refreshToken') + toast.success('用户删除成功') + router.push('/login') + }, + }) + + async function sendVerifyCode() { + setCountdown(COUNTDOWN_SECONDS) + try { + const res = await api.email.sendEmailVerifyCode({ + email: formik.values.email, + scene: EmailVerifyCodeScene.deleteUser, + }) + formik.setFieldValue('token', res.data.token) + } catch (err) { + setCountdown(0) + } + } + + return ( + <> + + setOpen(false)} + > + 删除用户 + + + + + + + + + + + + + + + + + + + 确定删除? + + + 该用户的所有数据将被不可逆地抹除! + + + + + + + + + ) +} diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 0bef993..01e7b97 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -3,6 +3,7 @@ import { useUser } from '@/utils/useUser' import Alert from '@mui/material/Alert' import Button from '@mui/material/Button' import { useRouter } from 'next/router' +import { DeleteUser } from './components/DeleteUser' export default function Home() { const { user, isLoading, errMsg } = useUser() @@ -34,7 +35,8 @@ export default function Home() { return ( <> hello {user!.email} - + + ) } diff --git a/src/utils/useUser.ts b/src/utils/useUser.ts index f4c8b74..1038279 100644 --- a/src/utils/useUser.ts +++ b/src/utils/useUser.ts @@ -1,13 +1,13 @@ import useSWR from 'swr' import * as api from '@/api' import type { AxiosError, AxiosResponse } from 'axios' -import { UserEntity } from '@/api/user' +import { User } from '@/api/user.interface' export function useUser() { - const { data, error, isLoading } = useSWR< - AxiosResponse, - AxiosError - >(`user`, api.user.getUserInfo) + const { data, error, isLoading } = useSWR, AxiosError>( + `user`, + api.user.getUserInfo, + ) const user = data?.data ?? null const errMsg = error?.message ?? ''