Skip to content
This repository was archived by the owner on Aug 29, 2024. It is now read-only.

Commit a0f03ec

Browse files
committed
feat: handle timeout
1 parent 5d240f4 commit a0f03ec

File tree

4 files changed

+60
-7
lines changed

4 files changed

+60
-7
lines changed

lib/components/Captcha/index.tsx

+37-3
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,43 @@ const Captcha = ({
2727
inputName,
2828
cbSuccess,
2929
cbFail,
30-
// cbTimeout, // TODO
30+
cbTimeout,
3131
}: CaptchaProps) => {
3232
const [captKey, setCaptKey] = useState("");
33+
34+
const [isCaptchaBodyOpen, setIsCaptchaBodyOpen] = useState(false);
35+
3336
const [captStatus, setCaptStatus] = useState<Status>("default");
3437
const [imageBase64, setImageBase64] = useState<string | null>(null);
3538
const [thumbBase64, setThumbBase64] = useState<string | null>(null);
3639

3740
const captAutoRefreshCount = useRef(0);
3841

42+
const captTimeoutHandler = useRef<ReturnType<typeof setTimeout> | null>(null);
43+
const cancelTimeout = () => {
44+
if (captTimeoutHandler.current) {
45+
clearTimeout(captTimeoutHandler.current);
46+
captTimeoutHandler.current = null;
47+
}
48+
};
49+
const setCaptTimeoutEvent = (when: number) => {
50+
// 清除上一个超时事件
51+
cancelTimeout();
52+
53+
// 设置新的超时事件
54+
captTimeoutHandler.current = setTimeout(() => {
55+
handleCloseEvent();
56+
57+
// 设置为超时状态
58+
setCaptStatus("timeout");
59+
60+
// 回调超时事件
61+
if (cbTimeout) {
62+
cbTimeout();
63+
}
64+
}, when - new Date().getTime());
65+
};
66+
3967
const handleRequestCaptcha = async () => {
4068
// 清理当前的
4169
setImageBase64(null);
@@ -57,12 +85,16 @@ const Captcha = ({
5785
setCaptKey(captcha.k);
5886
setImageBase64(captcha.b);
5987
setThumbBase64(captcha.t);
88+
setCaptTimeoutEvent(captcha.e * 1000); // 将 Unix 秒转换为毫秒
6089
} catch (e) {
6190
console.log(e);
6291
}
6392
};
6493

6594
const handleSubmitCaptcha = async (dots: Dot[]) => {
95+
// 提交了就不用再在意是否超时了
96+
cancelTimeout();
97+
6698
try {
6799
const res = await fetch(`${instance}/captcha/submit`, {
68100
method: "POST",
@@ -81,6 +113,7 @@ const Captcha = ({
81113
if (cbSuccess) {
82114
cbSuccess(captKey);
83115
}
116+
setCaptTimeoutEvent(res.e * 1000); // 将 Unix 秒转换为毫秒
84117
} else {
85118
if (captAutoRefreshCount.current > maxFailCount) {
86119
// 错误次数太多,歇一会吧
@@ -116,9 +149,10 @@ const Captcha = ({
116149
const handleCancelEvent = () => {
117150
setCaptStatus("default");
118151
handleCloseEvent();
119-
};
120152

121-
const [isCaptchaBodyOpen, setIsCaptchaBodyOpen] = useState(false);
153+
// 取消了就不用再在意是否超时了
154+
cancelTimeout();
155+
};
122156

123157
const handleCaptchaBodyVisibleChange = (visible: boolean) => {
124158
if (visible) {

lib/components/CaptchaBtn/index.tsx

+14-2
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,26 @@
1+
import type { ReactNode } from "react";
2+
13
import "./styles.css";
24

35
import DefaultImg from "./images/default.svg";
46
import CheckImg from "./images/check.svg";
57
import ErrorImg from "./images/error.svg";
68
import SuccessImg from "./images/success.svg";
79

8-
const iconMap = {
10+
const iconMap: {
11+
readonly [_ in Status]: string;
12+
} = {
913
default: DefaultImg,
1014
check: CheckImg,
1115
error: ErrorImg,
1216
over: ErrorImg,
1317
success: SuccessImg,
18+
timeout: ErrorImg,
1419
};
1520

16-
const messageMap = {
21+
const messageMap: {
22+
readonly [_ in Status]: ReactNode;
23+
} = {
1724
default: <>点击按键开始验证</>,
1825
check: <>正在验证···</>,
1926
error: (
@@ -23,6 +30,11 @@ const messageMap = {
2330
),
2431
over: <>失败次数过多,等会再来吧</>,
2532
success: <>验证通过</>,
33+
timeout: (
34+
<>
35+
验证超时,<b>再试一次</b>
36+
</>
37+
),
2638
};
2739

2840
interface CaptchaBtnProps {

lib/components/CaptchaBtn/styles.css

+7-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
.cap-btn .cap-state__check,
66
.cap-btn .cap-state__error,
77
.cap-btn .cap-state__success,
8-
.cap-btn .cap-state__over {
8+
.cap-btn .cap-state__over,
9+
.cap-btn .cap-state__timeout {
910
position: absolute;
1011
width: 100%;
1112
height: 48px;
@@ -67,6 +68,11 @@
6768
border: 1px solid #8bc640;
6869
pointer-events: none;
6970
}
71+
.cap-btn .cap-state__timeout {
72+
color: #ed4630;
73+
background: #fef0f0;
74+
border: 1px solid #ff5a34;
75+
}
7076
.cap-btn .cap-btn__inner .cap-btn__ico {
7177
position: relative;
7278
width: 24px;

lib/types/status.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ type Status =
33
| "check" // 正在验证
44
| "error" // 验证错误
55
| "over" // 失败次数过多
6-
| "success"; // 成功
6+
| "success" // 成功
7+
| "timeout"; // 超时

0 commit comments

Comments
 (0)