deleteUser

This commit is contained in:
秦秋旭 2023-02-24 21:39:36 +08:00
parent 40e0e2dd77
commit 31fc03a654
5 changed files with 164 additions and 6 deletions

View File

@ -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<Token>('/api/users/password', data)
}
export async function deleteUser(data: DeleteUser) {
return axios.delete('/api/users/me', { data })
}
let refreshing: Promise<AxiosResponse<Token>> | null
export async function refreshToken(data: TokenRefreshPayload) {
if (!refreshing) {

View File

@ -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

View File

@ -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<DeleteUser>({
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 (
<>
<Button color="error" onClick={() => setOpen(true)}>
</Button>
<Dialog
open={open}
fullWidth
maxWidth="xs"
onClose={() => setOpen(false)}
>
<DialogTitle></DialogTitle>
<DialogContent dividers>
<TextField
{...formik.getFieldProps('email')}
disabled
helperText={' '}
fullWidth
label="邮箱"
sx={{ mt: 1 }}
/>
<Grid container spacing={2}>
<Grid>
<TextField
{...formik.getFieldProps('verifyCode')}
required
error={formik.touched.verifyCode && !!formik.errors.verifyCode}
helperText={
(formik.touched.verifyCode && formik.errors.verifyCode) || ' '
}
fullWidth
label="验证码"
autoComplete="verifyCode"
autoFocus
sx={{ mt: 1 }}
/>
</Grid>
<Grid mt={2} sx={{ flexGrow: 1 }}>
<Button
size="large"
fullWidth
variant="contained"
disabled={countdown > 0}
onClick={sendVerifyCode}
>
{countdown > 0 ? countdown : '发送验证码'}
</Button>
</Grid>
</Grid>
<TextField
{...formik.getFieldProps('password')}
required
error={formik.touched.password && !!formik.errors.password}
helperText={
(formik.touched.password && formik.errors.password) || ' '
}
fullWidth
label="密码"
type="password"
autoComplete="current-password"
sx={{ mt: 1 }}
/>
</DialogContent>
<DialogActions>
<Button onClick={() => setOpen(false)}></Button>
<Button color="error" onClick={() => setConfrim(true)}>
</Button>
</DialogActions>
</Dialog>
<Dialog maxWidth="xs" open={confirm}>
<DialogTitle></DialogTitle>
<DialogContent dividers>
<DialogContentText>
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={() => setConfrim(false)}></Button>
<Button color="error" type="submit" onClick={formik.submitForm}>
</Button>
</DialogActions>
</Dialog>
</>
)
}

View File

@ -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 (
<>
<Alert severity="success">hello {user!.email}</Alert>
<Button onClick={logout}></Button>
<Button onClick={logout}>退</Button>
<DeleteUser />
</>
)
}

View File

@ -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<UserEntity>,
AxiosError
>(`user`, api.user.getUserInfo)
const { data, error, isLoading } = useSWR<AxiosResponse<User>, AxiosError>(
`user`,
api.user.getUserInfo,
)
const user = data?.data ?? null
const errMsg = error?.message ?? ''