lk
2 months ago
4 changed files with 270 additions and 190 deletions
-
307src/components/captcha/SlideCapt.tsx
-
49src/pages/use/login/index.tsx
-
70src/pages/use/password/retrieve.tsx
-
34src/pages/use/register/index.tsx
@ -1,160 +1,163 @@ |
|||
import React, { forwardRef, memo, useCallback, useEffect, useState, useImperativeHandle } from "react"; |
|||
import { Popover, message } from "antd"; |
|||
import GoCaptcha from "go-captcha-react"; |
|||
import { SlideCaptchaCheckData } from "./types.ts"; |
|||
import { SlideData, SlidePoint } from "go-captcha-react/dist/components/Slide/meta/data"; |
|||
import { SlideConfig } from "go-captcha-react/dist/components/Slide/meta/config"; |
|||
import { Props } from "go-captcha-react/dist/components/Button"; |
|||
import { useStyle } from "./style.ts"; |
|||
import React, { forwardRef, memo, useCallback, useEffect, useState, useImperativeHandle } from 'react' |
|||
import { Popover, message } from 'antd' |
|||
import GoCaptcha from 'go-captcha-react' |
|||
import { SlideCaptchaCheckData } from './types.ts' |
|||
import { SlideData, SlidePoint } from 'go-captcha-react/dist/components/Slide/meta/data' |
|||
import { SlideConfig } from 'go-captcha-react/dist/components/Slide/meta/config' |
|||
import { useStyle } from './style.ts' |
|||
import {Props} from "@/global"; |
|||
|
|||
export interface SlideCaptProps { |
|||
api: { |
|||
getCaptcha: () => Promise<any>; |
|||
checkCaptcha: (params: SlideCaptchaCheckData) => Promise<any>; |
|||
}; |
|||
config?: SlideConfig; |
|||
value?: string; |
|||
onChange?: (value?: string) => void; |
|||
getCaptcha: () => Promise<any>, |
|||
checkCaptcha: (params: SlideCaptchaCheckData) => Promise<any>, |
|||
}, |
|||
config?: SlideConfig |
|||
value?: string |
|||
onChange?: (value?: string) => void |
|||
} |
|||
|
|||
export type SlideCaptRef = { |
|||
reset: () => void; |
|||
}; |
|||
|
|||
const SlideCapt = forwardRef<SlideCaptRef | undefined, SlideCaptProps>( |
|||
({ config, api, value, onChange }: SlideCaptProps, ref) => { |
|||
const { styles } = useStyle(); |
|||
const [open, setOpen] = useState(false); |
|||
const [state, setState] = useState<Props>({}); |
|||
const [data, setData] = useState<SlideData>(); |
|||
const [innerKey, setKey] = useState(value); |
|||
|
|||
const fetchCaptcha = useCallback(() => { |
|||
return api.getCaptcha().then((res) => { |
|||
if (res.code === 0) { |
|||
const data = res.data; |
|||
setKey(data["captcha_key"] || ""); |
|||
setData({ |
|||
image: data["image_base64"] || "", |
|||
thumb: data["tile_base64"] || "", |
|||
thumbX: data["tile_x"] || 0, |
|||
thumbY: data["tile_y"] || 0, |
|||
thumbWidth: data["tile_width"] || 0, |
|||
thumbHeight: data["tile_height"] || 0, |
|||
}); |
|||
} |
|||
}); |
|||
}, [api.getCaptcha, setData]); |
|||
|
|||
const refresh = useCallback(() => { |
|||
fetchCaptcha(); |
|||
}, [fetchCaptcha]); |
|||
|
|||
const confirm = useCallback( |
|||
(point: SlidePoint, clear: (fn?: any) => void) => { |
|||
api |
|||
.checkCaptcha({ |
|||
point: [point.x, point.y].join(","), |
|||
key: innerKey!, |
|||
}) |
|||
.then((res) => { |
|||
// console.log(res)
|
|||
if (res.code === 0 && res.data.is_ok) { |
|||
message.success(`验证成功`); |
|||
|
|||
//验证成功,onChange通知出去,外部需要key做为校验
|
|||
onChange?.(innerKey); |
|||
|
|||
setState((prevState) => ({ |
|||
...prevState, |
|||
type: "success", |
|||
title: "校验成功", |
|||
})); |
|||
setOpen(false); |
|||
} else { |
|||
message.error("验证失败"); |
|||
setState((prevState) => ({ |
|||
...prevState, |
|||
type: "error", |
|||
title: "点击进行校验", |
|||
})); |
|||
} |
|||
setTimeout(() => { |
|||
clear(); |
|||
fetchCaptcha(); |
|||
}, 1000); |
|||
}) |
|||
.catch(() => { |
|||
setTimeout(() => { |
|||
clear(); |
|||
fetchCaptcha(); |
|||
}, 1000); |
|||
}); |
|||
}, |
|||
[api.checkCaptcha, setData, state, setState, setOpen, innerKey, onChange, fetchCaptcha], |
|||
); |
|||
|
|||
useImperativeHandle(ref, () => { |
|||
return { |
|||
reset() { |
|||
setState((prevState) => ({ |
|||
...prevState, |
|||
type: "default", |
|||
title: "点击进行校验", |
|||
})); |
|||
setKey(undefined); |
|||
onChange?.(undefined); |
|||
refresh(); |
|||
}, |
|||
}; |
|||
}, [fetchCaptcha, setState, setKey]); |
|||
|
|||
useEffect(() => { |
|||
if (open) { |
|||
fetchCaptcha(); |
|||
reset: () => void |
|||
} |
|||
|
|||
|
|||
const SlideCapt = forwardRef<SlideCaptRef | undefined, SlideCaptProps>(( |
|||
{ |
|||
config, |
|||
api, |
|||
value, |
|||
onChange, |
|||
}: SlideCaptProps, ref) => { |
|||
|
|||
const { styles } = useStyle() |
|||
const [ open, setOpen ] = useState(false) |
|||
const [ state, setState ] = useState<Props>({}) |
|||
const [ data, setData ] = useState<SlideData>() |
|||
const [ innerKey, setKey ] = useState(value) |
|||
|
|||
const fetchCaptcha = useCallback(() => { |
|||
|
|||
return api.getCaptcha().then(res => { |
|||
if (res.code === 0) { |
|||
const data = res.data |
|||
setKey(data['captcha_key'] || '') |
|||
setData({ |
|||
image: data['image_base64'] || '', |
|||
thumb: data['tile_base64'] || '', |
|||
thumbX: data['tile_x'] || 0, |
|||
thumbY: data['tile_y'] || 0, |
|||
thumbWidth: data['tile_width'] || 0, |
|||
thumbHeight: data['tile_height'] || 0, |
|||
}) |
|||
} |
|||
}, [open]); |
|||
|
|||
return ( |
|||
<div className={styles.container}> |
|||
<Popover |
|||
content={ |
|||
<GoCaptcha.Slide |
|||
config={{ |
|||
width: 300, |
|||
height: 217, |
|||
showTheme: false, |
|||
verticalPadding: 5, |
|||
horizontalPadding: 5, |
|||
...config, |
|||
}} |
|||
style={{ color: "red" }} |
|||
data={data!} |
|||
events={{ |
|||
refresh, |
|||
confirm, |
|||
close: () => { |
|||
setOpen(false); |
|||
}, |
|||
}} |
|||
/> |
|||
} |
|||
open={open} |
|||
onOpenChange={setOpen} |
|||
forceRender={true} |
|||
trigger="click" |
|||
> |
|||
<GoCaptcha.Button |
|||
title={"点击进行校验"} |
|||
{...state} |
|||
clickEvent={() => { |
|||
setOpen(true); |
|||
}} |
|||
/> |
|||
</Popover> |
|||
</div> |
|||
); |
|||
}, |
|||
); |
|||
|
|||
export default memo(SlideCapt); |
|||
}) |
|||
|
|||
|
|||
}, [ api.getCaptcha, setData ]) |
|||
|
|||
const refresh = useCallback(() => { |
|||
fetchCaptcha() |
|||
}, [ fetchCaptcha ]) |
|||
|
|||
const confirm = useCallback((point: SlidePoint, clear: (fn?: any) => void) => { |
|||
|
|||
api.checkCaptcha({ |
|||
point: [ point.x, point.y ].join(','), |
|||
key: innerKey! |
|||
}).then(res => { |
|||
// console.log(res)
|
|||
if (res.code === 0 && res.data.is_ok) { |
|||
message.success(`验证成功`) |
|||
|
|||
//验证成功,onChange通知出去,外部需要key做为校验
|
|||
onChange?.(innerKey) |
|||
|
|||
setState(prevState => ({ |
|||
...prevState, type: 'success', title: '校验成功', |
|||
})) |
|||
setOpen(false) |
|||
} else { |
|||
message.error('验证失败') |
|||
setState(prevState => ({ |
|||
...prevState, type: 'error', title: '点击进行校验', |
|||
})) |
|||
} |
|||
setTimeout(() => { |
|||
clear() |
|||
fetchCaptcha() |
|||
}, 1000) |
|||
|
|||
}).catch(() => { |
|||
setTimeout(() => { |
|||
clear() |
|||
fetchCaptcha() |
|||
}, 1000) |
|||
}) |
|||
|
|||
}, [ api.checkCaptcha, setData, state, setState, setOpen, innerKey, onChange, fetchCaptcha ]) |
|||
|
|||
useImperativeHandle(ref, () => { |
|||
return { |
|||
reset() { |
|||
setState(prevState => ({ |
|||
...prevState, type: 'default', title: '点击进行校验', |
|||
})) |
|||
setKey(undefined) |
|||
onChange?.(undefined) |
|||
refresh() |
|||
} |
|||
} |
|||
}, [ fetchCaptcha, setState, setKey ]) |
|||
|
|||
useEffect(() => { |
|||
|
|||
if (open) { |
|||
fetchCaptcha() |
|||
} |
|||
|
|||
}, [ open ]) |
|||
|
|||
return ( |
|||
<div className={styles.container}> |
|||
<Popover |
|||
content={ |
|||
<GoCaptcha.Slide |
|||
config={{ |
|||
width: 300, |
|||
height: 217, |
|||
showTheme: false, |
|||
verticalPadding: 5, |
|||
horizontalPadding: 5, |
|||
...config, |
|||
}} |
|||
style={{ color: 'red' }} |
|||
data={data!} |
|||
events={{ |
|||
refresh, |
|||
confirm, |
|||
close: () => { |
|||
setOpen(false) |
|||
} |
|||
}} |
|||
/> |
|||
} |
|||
open={open} |
|||
onOpenChange={setOpen} |
|||
forceRender={true} |
|||
trigger="click"> |
|||
<GoCaptcha.Button |
|||
title={'点击进行校验'} |
|||
{...state} |
|||
clickEvent={ |
|||
() => { |
|||
setOpen(true) |
|||
} |
|||
}/> |
|||
</Popover> |
|||
</div> |
|||
) |
|||
}) |
|||
|
|||
export default memo(SlideCapt) |
Write
Preview
Loading…
Cancel
Save
Reference in new issue