message-verify 1.0.1-beta.48 → 1.0.1-beta.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/main.tsx CHANGED
@@ -1,12 +1,11 @@
1
1
  import { createRoot } from 'react-dom/client';
2
- import { initFingerprint, createReLoginModal, VerifyHandler } from './index.js'; // 或 './index'
2
+ import { createMessageVerifyModal, initFingerprint } from './index.js'; // 或 './index'
3
3
  import { axios } from '@yqg/resource';
4
4
 
5
5
  const data = "{\"mobile\":\"188****4035\",\"verifyCodeKey\":\"3f025b33-988e-47c0-950d-6beb776d043f\",\"needValid\":true,\"step\":2,\"message\":\"需要填写验证码\"}";
6
6
 
7
7
  const fp = await initFingerprint();
8
- const fp2 = await initFingerprint();
9
- console.log(fp, fp2);
8
+ console.log(fp);
10
9
 
11
10
  const config = {
12
11
  "transitional": {
@@ -14,6 +13,12 @@ const config = {
14
13
  "forcedJSONParsing": true,
15
14
  "clarifyTimeoutError": false
16
15
  },
16
+ "transformRequest": [
17
+ null
18
+ ],
19
+ "transformResponse": [
20
+ null
21
+ ],
17
22
  "timeout": 0,
18
23
  "xsrfCookieName": "XSRF-TOKEN",
19
24
  "xsrfHeaderName": "X-XSRF-TOKEN",
@@ -22,7 +27,9 @@ const config = {
22
27
  "headers": {
23
28
  "Accept": "application/json, text/plain, */*",
24
29
  "X-Device-Fingerprint": "185fcce88c629725321adf29daa5e444",
25
- "Content-Type": "application/json"
30
+ "Content-Type": "application/json",
31
+ "sms-code": "121212",
32
+ "sms-code-key": "212190c7-2f5e-4cc1-82ec-a242c2ab5425"
26
33
  },
27
34
  "url": "/classification/admin/level/edit",
28
35
  "method": "post",
@@ -38,21 +45,17 @@ const config = {
38
45
  "data": "{\"id\":1,\"classificationName\":\"个人基本概况信息\",\"classificationLevel\":2}",
39
46
  "baseURL": "http://localhost:62888"
40
47
  };
41
-
42
- const promise = {current: null};
43
48
  createRoot(document.getElementById('root')!).render(
44
49
  <>
45
- <button onClick={() => {
46
- return VerifyHandler({data, config, http: axios, verifyPromise: promise});
47
- }}>
48
- Show verify Modal
49
- </button>
50
- <button onClick={() => createReLoginModal({
51
- goLogin: () => {
52
- console.log('goLogin');
50
+ <button onClick={() => createMessageVerifyModal({
51
+ data,
52
+ config,
53
+ response: {
54
+ config
53
55
  },
54
- lang: 'zh',
56
+ lang: 'en',
57
+ http: axios,
55
58
  })}>
56
- Show login Modal
59
+ Show verify Modal
57
60
  </button>
58
61
  </>);
@@ -1,23 +1,20 @@
1
1
  import { useState } from 'react'
2
- import { Modal, Button } from '../compoments/index.js'
3
- import { LoginModalConfig } from '../utils/type.js';
4
- import t from '../utils/i18n.js'
2
+ import { Modal, Button } from './compoments/index.js'
3
+ import { ModalConfig } from './utils/type.js';
5
4
 
6
- const ReLoginModal = ({ props }: { props: LoginModalConfig }) => {
7
- const { goLogin, lang, onClose: destroyModal } = props || {};
5
+ const ReLoginModal = ({ props }: { props: ModalConfig }) => {
6
+ console.log('props', props);
8
7
  const [visible, setVisible] = useState(true);
9
8
  const onClose = () => {
10
9
  setVisible(false);
11
- goLogin();
12
- destroyModal?.();
13
10
  };
14
11
  return (
15
12
  <Modal visible={visible} onClose={onClose} width={420}>
16
13
  <div style={{ fontWeight: 500, fontSize: 20, marginBottom: 24 }}>
17
- {t('accountAlert', lang)}
14
+ 账号安全提醒
18
15
  </div>
19
16
  <div style={{ color: '#222', fontSize: 16, marginBottom: 40, lineHeight: '24px' }}>
20
- {t('alertContent', lang)}
17
+ 检测到您的登录环境或网络信息有变动,为保障账户安全,请重新登录验证身份
21
18
  </div>
22
19
  <div style={{ display: 'flex', justifyContent: 'center' }}>
23
20
  <Button
@@ -25,15 +22,16 @@ const ReLoginModal = ({ props }: { props: LoginModalConfig }) => {
25
22
  background: '#1677ff',
26
23
  color: '#fff',
27
24
  border: 'none',
28
- width: 80,
29
- height: 36,
30
- fontSize: 14,
25
+ width: 160,
26
+ height: 44,
27
+ fontSize: 18,
28
+ fontWeight: 500,
31
29
  borderRadius: 8,
32
30
  boxShadow: '0 2px 8px rgba(22,119,255,0.08)',
33
31
  }}
34
32
  onClick={onClose}
35
33
  >
36
- {t('ok', lang)}
34
+ 好的
37
35
  </Button>
38
36
  </div>
39
37
  </Modal>
package/src/utils/type.ts CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- export type VerifyModalConfig = {
2
+ export type ModalConfig = {
3
3
  data: string;
4
4
  onClose?: () => void
5
5
  config: {
@@ -8,7 +8,7 @@ export type VerifyModalConfig = {
8
8
  };
9
9
  [key: string]: unknown;
10
10
  };
11
- lang?: 'zh' | 'en' | 'id';
11
+ lang: 'zh' | 'en' | 'id';
12
12
  http: {
13
13
  (params: object): Promise<unknown>;
14
14
  defaults: {
@@ -19,15 +19,6 @@ export type VerifyModalConfig = {
19
19
  }
20
20
  }
21
21
  };
22
- sendApi?: string;
23
- apiReject?: any;
24
- apiResolve?: any;
25
- apiPromiseToEmpty?: () => void;
26
- verifyPromise: {current: Promise<any> | null}
27
- }
28
-
29
- export type LoginModalConfig = {
30
- goLogin: () => void;
31
- onClose?: () => void
32
- lang?: 'zh' | 'en' | 'id';
22
+ api?: string;
23
+ response: any;
33
24
  }
@@ -0,0 +1,129 @@
1
+ import { useEffect, useState } from 'react'
2
+ import { Modal, Input, Button, message } from './compoments/index.js'
3
+ import Api from './resource.js'
4
+ import t from './utils/i18n.js'
5
+ import { ModalConfig } from './utils/type.js';
6
+ import { axios } from '@yqg/resource';
7
+
8
+ const CreateMessageVerifyModal = ({ props }: { props: ModalConfig }) => {
9
+ const [visible, setVisible] = useState(true);
10
+ const [countdown, setCountdown] = useState(60);
11
+ const [otp, setOtp] = useState('');
12
+ const [captchaImage, setCaptchaImage] = useState<string>('');
13
+ const [captchCode, setCaptchCode] = useState<string>('');
14
+ const [captchaKey, setCaptchaKey] = useState<string>('');
15
+ const { data, config, http, lang, api='/admin/sms/send', response } = props || {};
16
+ const dataObj = JSON.parse(data || '{}');
17
+ const { mobile, verifyCodeKey } = dataObj || {};
18
+
19
+ const getKey = async () => {
20
+ try {
21
+ const res = await Api.getCaptchaKey();
22
+ const { body: key } = res.data || {};
23
+ setCaptchaKey(key);
24
+ if (key) {
25
+ const image = Api.getCaptchaImgUrl(key) as unknown;
26
+ setCaptchaImage(image as string);
27
+ }
28
+ } catch (err) {const msg =
29
+ typeof err === 'object' && err !== null && 'message' in err
30
+ ? (err as {message: string}).message
31
+ : String(err);
32
+ message.error(msg as React.ReactNode);
33
+ }
34
+ }
35
+
36
+ useEffect(() => {
37
+ let timer: number | null = null;
38
+ if (visible && countdown > 0) {
39
+ timer = setInterval(() => {
40
+ setCountdown((prev) => prev - 1);
41
+ }, 1000);
42
+ }
43
+ if (countdown === 0) {
44
+ getKey();
45
+ }
46
+ return () => {
47
+ if (timer) clearInterval(timer);
48
+ };
49
+ }, [visible, countdown]);
50
+
51
+ const handleResend = async () => {
52
+ const formData = new FormData();
53
+ formData.append('captchaKey', captchaKey);
54
+ formData.append('captcha', captchCode);
55
+ // 重新发送验证码
56
+ const res = await axios.post(api, formData);
57
+ const { code, detail } = res.data?.status || {};
58
+ if (code !== 0) {
59
+ message.error(detail || t('sendFailed', lang));
60
+ return;
61
+ }
62
+ message.success(t('sendSuccess', lang));
63
+ setCountdown(60);
64
+ }
65
+
66
+ return (
67
+ <Modal
68
+ width={420}
69
+ visible={visible}
70
+ onClose={() => {
71
+ setVisible(false);
72
+ props.onClose?.();
73
+ }}
74
+ >
75
+ <div style={{ fontSize: 14, color: '#666' }}>{t('alreadySend', lang, { phone: mobile })}</div>
76
+
77
+ <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 12 }}>
78
+ <Input.OTP
79
+ length={6}
80
+ value={otp}
81
+ onChange={async (val) => {
82
+ setOtp(val);
83
+ if (val.length === 6) {
84
+ const {data: {status: {code, detail} = {}}} = response || {};
85
+ http({
86
+ ...config,
87
+ headers: {
88
+ ...http.defaults.headers.common,
89
+ 'sms-code': val,
90
+ 'sms-code-key': verifyCodeKey,
91
+ 'Content-Type': config.headers['Content-Type'],
92
+ }
93
+ }) as any;
94
+ console.log(response, code, 'config');
95
+ if(code !== 0) {
96
+ message.error(detail || t('verifyFailed', lang));
97
+ return;
98
+ } else {
99
+ message.success(t('verifySuccess', lang));
100
+ setVisible(false);
101
+ }
102
+ }
103
+ }} />
104
+ <Button
105
+ disabled={countdown > 0 || !captchCode}
106
+ onClick={handleResend}
107
+ style={{ padding: '8px' }}
108
+ >
109
+ {countdown > 0 ? t('countDownSecound', lang, { countdown }) : t('reSend', lang)}
110
+ </Button>
111
+ </div>
112
+ {countdown > 0 ? null :
113
+ <div style={{ marginTop: 12, display: 'flex', alignItems: 'center' }}>
114
+ <Input
115
+ placeholder={t('pleaseEnterPicVerifyCode', lang)}
116
+ onChange={(e) => {
117
+ setCaptchCode(e as string)
118
+ }}
119
+ style={{ width: 300 }}
120
+ />
121
+
122
+ {captchaImage && <img src={captchaImage} alt={t('verifyCode', lang)} style={{ width: 100, height: 30, marginLeft: 8 }} onClick={getKey} />}
123
+ </div>}
124
+ {(countdown > 0 || captchCode) ? null : <div style={{ fontSize: 14, color: 'red' }}>{t('pleaseEnterAndSend', lang)}</div>}
125
+ </Modal>
126
+ );
127
+ };
128
+
129
+ export default CreateMessageVerifyModal;
@@ -1,5 +0,0 @@
1
- import { LoginModalConfig } from '../utils/type.js';
2
- declare const ReLoginModal: ({ props }: {
3
- props: LoginModalConfig;
4
- }) => import("react/jsx-runtime.js").JSX.Element;
5
- export default ReLoginModal;
@@ -1,24 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState } from 'react';
3
- import { Modal, Button } from '../compoments/index.js';
4
- import t from '../utils/i18n.js';
5
- const ReLoginModal = ({ props }) => {
6
- const { goLogin, lang, onClose: destroyModal } = props || {};
7
- const [visible, setVisible] = useState(true);
8
- const onClose = () => {
9
- setVisible(false);
10
- goLogin();
11
- destroyModal?.();
12
- };
13
- return (_jsxs(Modal, { visible: visible, onClose: onClose, width: 420, children: [_jsx("div", { style: { fontWeight: 500, fontSize: 20, marginBottom: 24 }, children: t('accountAlert', lang) }), _jsx("div", { style: { color: '#222', fontSize: 16, marginBottom: 40, lineHeight: '24px' }, children: t('alertContent', lang) }), _jsx("div", { style: { display: 'flex', justifyContent: 'center' }, children: _jsx(Button, { style: {
14
- background: '#1677ff',
15
- color: '#fff',
16
- border: 'none',
17
- width: 80,
18
- height: 36,
19
- fontSize: 14,
20
- borderRadius: 8,
21
- boxShadow: '0 2px 8px rgba(22,119,255,0.08)',
22
- }, onClick: onClose, children: t('ok', lang) }) })] }));
23
- };
24
- export default ReLoginModal;
@@ -1,5 +0,0 @@
1
- import { VerifyModalConfig } from '../utils/type.js';
2
- declare const CreateMessageVerifyModal: ({ props }: {
3
- props: VerifyModalConfig;
4
- }) => import("react/jsx-runtime.js").JSX.Element;
5
- export default CreateMessageVerifyModal;
@@ -1,143 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useEffect, useState } from 'react';
3
- import { Modal, Input, Button, message } from '../compoments/index.js';
4
- import Api from '../utils/resource.js';
5
- import t from '../utils/i18n.js';
6
- import { axios } from '@yqg/resource';
7
- const CreateMessageVerifyModal = ({ props }) => {
8
- const [visible, setVisible] = useState(true);
9
- const [countdown, setCountdown] = useState(60);
10
- const [otp, setOtp] = useState('');
11
- const [captchaImage, setCaptchaImage] = useState('');
12
- const [captchCode, setCaptchCode] = useState('');
13
- const [captchaKey, setCaptchaKey] = useState('');
14
- const { data, http, lang, sendApi = '/admin/sms/send', config, apiResolve, apiPromiseToEmpty, onClose } = props || {};
15
- const dataObj = JSON.parse(data || '{}');
16
- const { mobile, verifyCodeKey } = dataObj || {};
17
- const getKey = async () => {
18
- try {
19
- const res = await Api.getCaptchaKey();
20
- const { body: key } = res.data || {};
21
- setCaptchaKey(key);
22
- if (key) {
23
- const image = Api.getCaptchaImgUrl(key);
24
- setCaptchaImage(image);
25
- }
26
- }
27
- catch (err) {
28
- const msg = typeof err === 'object' && err !== null && 'message' in err
29
- ? err.message
30
- : String(err);
31
- message.error(msg);
32
- }
33
- };
34
- useEffect(() => {
35
- let timer = null;
36
- if (visible && countdown > 0) {
37
- timer = setInterval(() => {
38
- setCountdown((prev) => prev - 1);
39
- }, 1000);
40
- }
41
- if (countdown === 0) {
42
- getKey();
43
- }
44
- return () => {
45
- if (timer)
46
- clearInterval(timer);
47
- };
48
- }, [visible, countdown]);
49
- const handleResend = async () => {
50
- const formData = new FormData();
51
- formData.append('captchaKey', captchaKey);
52
- formData.append('captcha', captchCode);
53
- // 重新发送验证码
54
- const res = await axios.post(sendApi, formData);
55
- const { code, detail } = res.data?.status || {};
56
- if (code !== 0) {
57
- message.error(detail || t('sendFailed', lang));
58
- return;
59
- }
60
- message.success(t('sendSuccess', lang));
61
- // 重置倒计时、验证码
62
- setCountdown(60);
63
- setOtp('');
64
- };
65
- return (_jsxs(Modal, { width: 420, visible: visible, onClose: () => {
66
- setVisible(false);
67
- apiPromiseToEmpty?.();
68
- onClose?.();
69
- }, children: [_jsx("div", { style: { fontSize: 14, color: '#666' }, children: t('alreadySend', lang, { phone: mobile }) }), _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 8, marginTop: 12 }, children: [_jsx(Input.OTP, { length: 6, value: otp, onChange: async (val) => {
70
- setOtp(val);
71
- if (val.length === 6) {
72
- // try {
73
- // const res = await Promise.race([
74
- // new Promise((resolve, reject) => {
75
- // setTimeout(() => {
76
- // reject(new Error('Timeout'));
77
- // }, 1000);
78
- // }),
79
- // new Promise((resolve, reject) => {
80
- // http({
81
- // ...config,
82
- // headers: {
83
- // ...http.defaults.headers.common,
84
- // 'sms-code': val,
85
- // 'sms-code-key': verifyCodeKey,
86
- // 'Content-Type': config.headers['Content-Type'],
87
- // }
88
- // }).then(res => {
89
- // resolve(res);
90
- // }).catch(err => {
91
- // reject(err);
92
- // })
93
- // ]) as any;
94
- // if (res?.data?.status?.code === 0) {
95
- // apiResolve(res);
96
- // setVisible(false);
97
- // } else {
98
- // message.error('验证失败');
99
- // setOtp('');
100
- // }
101
- // } catch (error) {
102
- // console.warn('catch', error);
103
- // message.error('验证失败');
104
- // setOtp('');
105
- // }
106
- try {
107
- const res = new Promise((resolve, reject) => {
108
- http({
109
- ...config,
110
- headers: {
111
- ...http.defaults.headers.common,
112
- 'sms-code': val,
113
- 'sms-code-key': verifyCodeKey,
114
- 'Content-Type': config.headers['Content-Type'],
115
- }
116
- }).then(res => {
117
- resolve(res);
118
- }).catch(err => {
119
- reject(err);
120
- });
121
- });
122
- console.log('res', res);
123
- if (res?.data?.status?.code === 0) {
124
- apiResolve(res);
125
- setVisible(false);
126
- }
127
- else {
128
- message.error('验证失败');
129
- setOtp('');
130
- }
131
- }
132
- catch (error) {
133
- console.warn('catch', error);
134
- message.error('验证失败');
135
- setOtp('');
136
- }
137
- }
138
- } }), _jsx(Button, { disabled: countdown > 0 || !captchCode, onClick: handleResend, style: { padding: '8px' }, children: countdown > 0 ? t('countDownSecound', lang, { countdown }) : t('reSend', lang) })] }), countdown > 0 ? null :
139
- _jsxs("div", { style: { marginTop: 12, display: 'flex', alignItems: 'center' }, children: [_jsx(Input, { placeholder: t('pleaseEnterPicVerifyCode', lang), onChange: (e) => {
140
- setCaptchCode(e);
141
- }, style: { width: 300 } }), captchaImage && _jsx("img", { src: captchaImage, alt: t('verifyCode', lang), style: { width: 100, height: 30, marginLeft: 8 }, onClick: getKey })] }), (countdown > 0 || captchCode) ? null : _jsx("div", { style: { fontSize: 14, color: 'red' }, children: t('pleaseEnterAndSend', lang) }), _jsx("div", { style: { fontSize: 14, color: '#666', marginTop: 12 }, children: t('chidoriOpenPro', lang) })] }));
142
- };
143
- export default CreateMessageVerifyModal;
@@ -1,2 +0,0 @@
1
- declare const _default: import("@yqg/resource").default & Record<"getCaptchaKey" | "reSendCode" | "getCaptchaImgUrl", import("@yqg/resource").CustomMethod>;
2
- export default _default;
@@ -1,7 +0,0 @@
1
- import { assign, customPost } from '@yqg/resource';
2
- const api = {
3
- getCaptchaKey: customPost('/messageVerify/admin/captcha/key'),
4
- reSendCode: customPost('/admin/sms/send'),
5
- getCaptchaImgUrl: (captchaKey) => { return `/messageVerify/admin/captcha/image/${captchaKey}`; },
6
- };
7
- export default assign(api);
@@ -1,179 +0,0 @@
1
- import { useEffect, useState } from 'react'
2
- import { Modal, Input, Button, message } from '../compoments/index.js'
3
- import Api from '../utils/resource.js'
4
- import t from '../utils/i18n.js'
5
- import { VerifyModalConfig } from '../utils/type.js';
6
- import { axios } from '@yqg/resource';
7
-
8
- const CreateMessageVerifyModal = ({ props }: { props: VerifyModalConfig }) => {
9
- const [visible, setVisible] = useState(true);
10
- const [countdown, setCountdown] = useState(60);
11
- const [otp, setOtp] = useState('');
12
- const [captchaImage, setCaptchaImage] = useState<string>('');
13
- const [captchCode, setCaptchCode] = useState<string>('');
14
- const [captchaKey, setCaptchaKey] = useState<string>('');
15
- const { data, http, lang, sendApi = '/admin/sms/send', config, apiResolve, apiPromiseToEmpty, onClose } = props || {};
16
- const dataObj = JSON.parse(data || '{}');
17
- const { mobile, verifyCodeKey } = dataObj || {};
18
-
19
- const getKey = async () => {
20
- try {
21
- const res = await Api.getCaptchaKey();
22
- const { body: key } = res.data || {};
23
- setCaptchaKey(key);
24
- if (key) {
25
- const image = Api.getCaptchaImgUrl(key) as unknown;
26
- setCaptchaImage(image as string);
27
- }
28
- } catch (err) {
29
- const msg =
30
- typeof err === 'object' && err !== null && 'message' in err
31
- ? (err as { message: string }).message
32
- : String(err);
33
- message.error(msg as React.ReactNode);
34
- }
35
- }
36
-
37
- useEffect(() => {
38
- let timer: number | null = null;
39
- if (visible && countdown > 0) {
40
- timer = setInterval(() => {
41
- setCountdown((prev) => prev - 1);
42
- }, 1000);
43
- }
44
- if (countdown === 0) {
45
- getKey();
46
- }
47
- return () => {
48
- if (timer) clearInterval(timer);
49
- };
50
- }, [visible, countdown]);
51
-
52
- const handleResend = async () => {
53
- const formData = new FormData();
54
- formData.append('captchaKey', captchaKey);
55
- formData.append('captcha', captchCode);
56
- // 重新发送验证码
57
- const res = await axios.post(sendApi, formData);
58
- const { code, detail } = res.data?.status || {};
59
- if (code !== 0) {
60
- message.error(detail || t('sendFailed', lang));
61
- return;
62
- }
63
- message.success(t('sendSuccess', lang));
64
- // 重置倒计时、验证码
65
- setCountdown(60);
66
- setOtp('');
67
- }
68
-
69
- return (
70
- <Modal
71
- width={420}
72
- visible={visible}
73
- onClose={() => {
74
- setVisible(false);
75
- apiPromiseToEmpty?.();
76
- onClose?.();
77
- }}
78
- >
79
- <div style={{ fontSize: 14, color: '#666' }}>{t('alreadySend', lang, { phone: mobile })}</div>
80
-
81
- <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 12 }}>
82
- <Input.OTP
83
- length={6}
84
- value={otp}
85
- onChange={async (val) => {
86
- setOtp(val);
87
- if (val.length === 6) {
88
- // try {
89
- // const res = await Promise.race([
90
- // new Promise((resolve, reject) => {
91
- // setTimeout(() => {
92
- // reject(new Error('Timeout'));
93
- // }, 1000);
94
- // }),
95
- // new Promise((resolve, reject) => {
96
- // http({
97
- // ...config,
98
- // headers: {
99
- // ...http.defaults.headers.common,
100
- // 'sms-code': val,
101
- // 'sms-code-key': verifyCodeKey,
102
- // 'Content-Type': config.headers['Content-Type'],
103
- // }
104
- // }).then(res => {
105
- // resolve(res);
106
- // }).catch(err => {
107
- // reject(err);
108
- // })
109
- // ]) as any;
110
- // if (res?.data?.status?.code === 0) {
111
- // apiResolve(res);
112
- // setVisible(false);
113
- // } else {
114
- // message.error('验证失败');
115
- // setOtp('');
116
- // }
117
- // } catch (error) {
118
- // console.warn('catch', error);
119
- // message.error('验证失败');
120
- // setOtp('');
121
- // }
122
- try {
123
- const res = new Promise((resolve, reject) => {
124
- http({
125
- ...config,
126
- headers: {
127
- ...http.defaults.headers.common,
128
- 'sms-code': val,
129
- 'sms-code-key': verifyCodeKey,
130
- 'Content-Type': config.headers['Content-Type'],
131
- }
132
- }).then(res => {
133
- resolve(res);
134
- }).catch(err => {
135
- reject(err);
136
- })
137
- }) as any;
138
- console.log('res', res);
139
- if (res?.data?.status?.code === 0) {
140
- apiResolve(res);
141
- setVisible(false);
142
- } else {
143
- message.error('验证失败');
144
- setOtp('');
145
- }
146
- } catch (error) {
147
- console.warn('catch', error);
148
- message.error('验证失败');
149
- setOtp('');
150
- }
151
- }
152
- }} />
153
- <Button
154
- disabled={countdown > 0 || !captchCode}
155
- onClick={handleResend}
156
- style={{ padding: '8px' }}
157
- >
158
- {countdown > 0 ? t('countDownSecound', lang, { countdown }) : t('reSend', lang)}
159
- </Button>
160
- </div>
161
- {countdown > 0 ? null :
162
- <div style={{ marginTop: 12, display: 'flex', alignItems: 'center' }}>
163
- <Input
164
- placeholder={t('pleaseEnterPicVerifyCode', lang)}
165
- onChange={(e) => {
166
- setCaptchCode(e as string)
167
- }}
168
- style={{ width: 300 }}
169
- />
170
-
171
- {captchaImage && <img src={captchaImage} alt={t('verifyCode', lang)} style={{ width: 100, height: 30, marginLeft: 8 }} onClick={getKey} />}
172
- </div>}
173
- {(countdown > 0 || captchCode) ? null : <div style={{ fontSize: 14, color: 'red' }}>{t('pleaseEnterAndSend', lang)}</div>}
174
- <div style={{ fontSize: 14, color: '#666', marginTop: 12 }}>{t('chidoriOpenPro', lang)}</div>
175
- </Modal>
176
- );
177
- };
178
-
179
- export default CreateMessageVerifyModal;
File without changes