|
|
@ -1,119 +1,123 @@ |
|
|
|
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; |
|
|
|
}; |
|
|
|
reset: () => void |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const SlideCapt = forwardRef<SlideCaptRef | undefined, SlideCaptProps>(( |
|
|
|
{ |
|
|
|
config, |
|
|
|
api, |
|
|
|
value, |
|
|
|
onChange, |
|
|
|
}: SlideCaptProps, ref) => { |
|
|
|
|
|
|
|
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 { 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) => { |
|
|
|
|
|
|
|
return api.getCaptcha().then(res => { |
|
|
|
if (res.code === 0) { |
|
|
|
const data = res.data; |
|
|
|
setKey(data["captcha_key"] || ""); |
|
|
|
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, |
|
|
|
}); |
|
|
|
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) => { |
|
|
|
|
|
|
|
|
|
|
|
}, [ 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(`验证成功`); |
|
|
|
message.success(`验证成功`) |
|
|
|
|
|
|
|
//验证成功,onChange通知出去,外部需要key做为校验
|
|
|
|
onChange?.(innerKey); |
|
|
|
|
|
|
|
setState((prevState) => ({ |
|
|
|
...prevState, |
|
|
|
type: "success", |
|
|
|
title: "校验成功", |
|
|
|
})); |
|
|
|
setOpen(false); |
|
|
|
onChange?.(innerKey) |
|
|
|
|
|
|
|
setState(prevState => ({ |
|
|
|
...prevState, type: 'success', title: '校验成功', |
|
|
|
})) |
|
|
|
setOpen(false) |
|
|
|
} else { |
|
|
|
message.error("验证失败"); |
|
|
|
setState((prevState) => ({ |
|
|
|
...prevState, |
|
|
|
type: "error", |
|
|
|
title: "点击进行校验", |
|
|
|
})); |
|
|
|
message.error('验证失败') |
|
|
|
setState(prevState => ({ |
|
|
|
...prevState, type: 'error', title: '点击进行校验', |
|
|
|
})) |
|
|
|
} |
|
|
|
setTimeout(() => { |
|
|
|
clear(); |
|
|
|
fetchCaptcha(); |
|
|
|
}, 1000); |
|
|
|
}) |
|
|
|
.catch(() => { |
|
|
|
clear() |
|
|
|
fetchCaptcha() |
|
|
|
}, 1000) |
|
|
|
|
|
|
|
}).catch(() => { |
|
|
|
setTimeout(() => { |
|
|
|
clear(); |
|
|
|
fetchCaptcha(); |
|
|
|
}, 1000); |
|
|
|
}); |
|
|
|
}, |
|
|
|
[api.checkCaptcha, setData, state, setState, setOpen, innerKey, onChange, fetchCaptcha], |
|
|
|
); |
|
|
|
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]); |
|
|
|
setState(prevState => ({ |
|
|
|
...prevState, type: 'default', title: '点击进行校验', |
|
|
|
})) |
|
|
|
setKey(undefined) |
|
|
|
onChange?.(undefined) |
|
|
|
refresh() |
|
|
|
} |
|
|
|
} |
|
|
|
}, [ fetchCaptcha, setState, setKey ]) |
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
|
|
|
|
if (open) { |
|
|
|
fetchCaptcha(); |
|
|
|
fetchCaptcha() |
|
|
|
} |
|
|
|
}, [open]); |
|
|
|
|
|
|
|
}, [ open ]) |
|
|
|
|
|
|
|
return ( |
|
|
|
<div className={styles.container}> |
|
|
@ -128,33 +132,32 @@ const SlideCapt = forwardRef<SlideCaptRef | undefined, SlideCaptProps>( |
|
|
|
horizontalPadding: 5, |
|
|
|
...config, |
|
|
|
}} |
|
|
|
style={{ color: "red" }} |
|
|
|
style={{ color: 'red' }} |
|
|
|
data={data!} |
|
|
|
events={{ |
|
|
|
refresh, |
|
|
|
confirm, |
|
|
|
close: () => { |
|
|
|
setOpen(false); |
|
|
|
}, |
|
|
|
setOpen(false) |
|
|
|
} |
|
|
|
}} |
|
|
|
/> |
|
|
|
} |
|
|
|
open={open} |
|
|
|
onOpenChange={setOpen} |
|
|
|
forceRender={true} |
|
|
|
trigger="click" |
|
|
|
> |
|
|
|
trigger="click"> |
|
|
|
<GoCaptcha.Button |
|
|
|
title={"点击进行校验"} |
|
|
|
title={'点击进行校验'} |
|
|
|
{...state} |
|
|
|
clickEvent={() => { |
|
|
|
setOpen(true); |
|
|
|
}} |
|
|
|
/> |
|
|
|
clickEvent={ |
|
|
|
() => { |
|
|
|
setOpen(true) |
|
|
|
} |
|
|
|
}/> |
|
|
|
</Popover> |
|
|
|
</div> |
|
|
|
); |
|
|
|
}, |
|
|
|
); |
|
|
|
) |
|
|
|
}) |
|
|
|
|
|
|
|
export default memo(SlideCapt); |
|
|
|
export default memo(SlideCapt) |