message-verify 0.0.44-beta.0 → 0.0.45-beta.0

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/README.md CHANGED
@@ -1,54 +1,12 @@
1
- # React + TypeScript + Vite
1
+ # MessageVerify 验证码弹窗组件接入说明
2
2
 
3
- This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
3
+ ## 组件简介
4
4
 
5
- Currently, two official plugins are available:
5
+ `CreateMessageVerifyModal` 是一个用于短信验证码校验的弹窗组件,支持国际化,适用于敏感接口需要二次验证的场景。
6
6
 
7
- - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh
8
- - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
7
+ ## 快速接入
9
8
 
10
- ## Expanding the ESLint configuration
9
+ ### 1. 引入组件
11
10
 
12
- If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
13
-
14
- ```js
15
- export default tseslint.config({
16
- extends: [
17
- // Remove ...tseslint.configs.recommended and replace with this
18
- ...tseslint.configs.recommendedTypeChecked,
19
- // Alternatively, use this for stricter rules
20
- ...tseslint.configs.strictTypeChecked,
21
- // Optionally, add this for stylistic rules
22
- ...tseslint.configs.stylisticTypeChecked,
23
- ],
24
- languageOptions: {
25
- // other options...
26
- parserOptions: {
27
- project: ['./tsconfig.node.json', './tsconfig.app.json'],
28
- tsconfigRootDir: import.meta.dirname,
29
- },
30
- },
31
- })
32
- ```
33
-
34
- You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
35
-
36
- ```js
37
- // eslint.config.js
38
- import reactX from 'eslint-plugin-react-x'
39
- import reactDom from 'eslint-plugin-react-dom'
40
-
41
- export default tseslint.config({
42
- plugins: {
43
- // Add the react-x and react-dom plugins
44
- 'react-x': reactX,
45
- 'react-dom': reactDom,
46
- },
47
- rules: {
48
- // other rules...
49
- // Enable its recommended typescript rules
50
- ...reactX.configs['recommended-typescript'].rules,
51
- ...reactDom.configs.recommended.rules,
52
- },
53
- })
54
- ```
11
+ ```typescript
12
+ import {createMessageVerifyModal} from 'message-verify';
@@ -3,6 +3,7 @@ interface ModalProps {
3
3
  visible: boolean;
4
4
  onClose: () => void;
5
5
  children: React.ReactNode;
6
+ width?: number | string;
6
7
  }
7
8
  declare const Modal: React.FC<ModalProps>;
8
9
  export default Modal;
@@ -32,9 +32,12 @@ const closeBtnStyle = {
32
32
  cursor: 'pointer',
33
33
  lineHeight: 1,
34
34
  };
35
- const Modal = ({ visible, onClose, children }) => {
35
+ const Modal = ({ visible, onClose, children, width }) => {
36
36
  if (!visible)
37
37
  return null;
38
- return (_jsx("div", { style: modalStyle, children: _jsxs("div", { style: contentStyle, children: [_jsx("button", { style: closeBtnStyle, onClick: onClose, "aria-label": "\u5173\u95ED", children: "\u00D7" }), children] }) }));
38
+ return (_jsx("div", { style: modalStyle, children: _jsxs("div", { style: {
39
+ ...contentStyle,
40
+ width: width ? (typeof width === 'number' ? `${width}px` : width) : undefined, // 应用width
41
+ }, children: [_jsx("button", { style: closeBtnStyle, onClick: onClose, "aria-label": "\u5173\u95ED", children: "\u00D7" }), children] }) }));
39
42
  };
40
43
  export default Modal;
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ export type ModalConfig = {
2
2
  data: string;
3
3
  onClose?: () => void;
4
4
  config: object;
5
+ lang: 'zh' | 'en' | 'id';
5
6
  http: {
6
7
  (params: object): Promise<unknown>;
7
8
  defaults: {
@@ -0,0 +1,10 @@
1
+ declare const _default: {
2
+ pleaseEnterPicVerifyCode: string;
3
+ alreadySend: string;
4
+ verifyCode: string;
5
+ pleaseEnterAndSend: string;
6
+ sendSuccess: string;
7
+ reSend: string;
8
+ countDownSecound: string;
9
+ };
10
+ export default _default;
@@ -0,0 +1,9 @@
1
+ export default {
2
+ pleaseEnterPicVerifyCode: 'Please enter the image verification code',
3
+ alreadySend: 'A verification SMS has been sent to your phone: {phone}',
4
+ verifyCode: 'Verification Code',
5
+ pleaseEnterAndSend: 'Please enter the image verification code first, then resend the code',
6
+ sendSuccess: 'Successfully sent',
7
+ reSend: 'Resend',
8
+ countDownSecound: '{countdown} seconds'
9
+ };
@@ -0,0 +1,10 @@
1
+ declare const _default: {
2
+ pleaseEnterPicVerifyCode: string;
3
+ alreadySend: string;
4
+ verifyCode: string;
5
+ pleaseEnterAndSend: string;
6
+ sendSuccess: string;
7
+ reSend: string;
8
+ countDownSecound: string;
9
+ };
10
+ export default _default;
@@ -0,0 +1,9 @@
1
+ export default {
2
+ pleaseEnterPicVerifyCode: 'Silakan masukkan kode verifikasi gambar',
3
+ alreadySend: 'SMS verifikasi telah dikirim ke nomor ponsel Anda: {phone}',
4
+ verifyCode: 'Kode Verifikasi',
5
+ pleaseEnterAndSend: 'Harap masukkan kode verifikasi gambar terlebih dahulu, lalu kirim ulang kode',
6
+ sendSuccess: 'Berhasil dikirim',
7
+ reSend: 'Kirim Ulang',
8
+ countDownSecound: '{countdown} detik'
9
+ };
@@ -0,0 +1,10 @@
1
+ declare const _default: {
2
+ pleaseEnterPicVerifyCode: string;
3
+ alreadySend: string;
4
+ verifyCode: string;
5
+ pleaseEnterAndSend: string;
6
+ sendSuccess: string;
7
+ reSend: string;
8
+ countDownSecound: string;
9
+ };
10
+ export default _default;
@@ -0,0 +1,9 @@
1
+ export default {
2
+ pleaseEnterPicVerifyCode: '请输入图形验证码',
3
+ alreadySend: '已发送短信至您的手机:{phone}',
4
+ verifyCode: '验证码',
5
+ pleaseEnterAndSend: '请输入图形验证码后,重新发送验证码',
6
+ sendSuccess: '发送成功',
7
+ reSend: '重新发送',
8
+ countDownSecound: '{countdown}秒'
9
+ };
package/dist/main.js CHANGED
@@ -5,6 +5,7 @@ const data = "{\"mobile\":\"188****4035\",\"verifyCodeKey\":\"3f025b33-988e-47c0
5
5
  createRoot(document.getElementById('root')).render(_jsx("button", { onClick: () => createMessageVerifyModal({
6
6
  data,
7
7
  config: {},
8
+ lang: 'en',
8
9
  http: Object.assign(() => Promise.resolve({}), {
9
10
  defaults: {
10
11
  headers: {
@@ -1 +1 @@
1
- {"root":["../src/index.tsx","../src/main.tsx","../src/resource.ts","../src/verify-modal.tsx","../src/vite-env.d.ts","../src/compoments/button.tsx","../src/compoments/index.ts","../src/compoments/input.tsx","../src/compoments/message.tsx","../src/compoments/modal.tsx","../src/utils/status.ts"],"version":"5.7.3"}
1
+ {"root":["../src/index.tsx","../src/main.tsx","../src/resource.ts","../src/verify-modal.tsx","../src/vite-env.d.ts","../src/compoments/button.tsx","../src/compoments/index.ts","../src/compoments/input.tsx","../src/compoments/message.tsx","../src/compoments/modal.tsx","../src/locales/en.ts","../src/locales/id.ts","../src/locales/zh.ts","../src/utils/i18n.ts","../src/utils/status.ts"],"version":"5.7.3"}
@@ -0,0 +1,3 @@
1
+ type LocaleType = 'zh' | 'en' | 'id';
2
+ declare function t(key: string, language?: LocaleType, params?: Record<string, string | number>): string;
3
+ export default t;
@@ -0,0 +1,20 @@
1
+ import zh from '../locales/zh';
2
+ import en from '../locales/en';
3
+ import id from '../locales/id';
4
+ const locales = {
5
+ zh,
6
+ en,
7
+ id
8
+ };
9
+ function t(key, language = 'zh', params) {
10
+ const messages = locales[language] || locales.zh;
11
+ let template = messages[key] || '';
12
+ if (params) {
13
+ Object.keys(params).forEach(paramKey => {
14
+ const reg = new RegExp(`{${paramKey}}`, 'g');
15
+ template = template.replace(reg, String(params[paramKey]));
16
+ });
17
+ }
18
+ return template;
19
+ }
20
+ export default t;
@@ -2,6 +2,7 @@ type ModalConfig = {
2
2
  data: string;
3
3
  onClose?: () => void;
4
4
  config: object;
5
+ lang: 'zh' | 'en' | 'id';
5
6
  http: {
6
7
  (params: object): Promise<unknown>;
7
8
  defaults: {
@@ -13,7 +14,7 @@ type ModalConfig = {
13
14
  };
14
15
  };
15
16
  };
16
- declare const ModalDom: ({ props }: {
17
+ declare const CreateMessageVerifyModal: ({ props }: {
17
18
  props: ModalConfig;
18
19
  }) => import("react/jsx-runtime.js").JSX.Element;
19
- export default ModalDom;
20
+ export default CreateMessageVerifyModal;
@@ -1,15 +1,16 @@
1
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useEffect, useState } from 'react';
3
3
  import { Modal, Input, Button, message } from './compoments/index.js';
4
4
  import Api from './resource.js';
5
- const ModalDom = ({ props }) => {
5
+ import t from './utils/i18n.js';
6
+ const CreateMessageVerifyModal = ({ props }) => {
6
7
  const [visible, setVisible] = useState(true);
7
8
  const [countdown, setCountdown] = useState(3);
8
9
  const [otp, setOtp] = useState('');
9
10
  const [captchaImage, setCaptchaImage] = useState('');
10
11
  const [captchCode, setCaptchCode] = useState('');
11
12
  const [captchaKey, setCaptchaKey] = useState('');
12
- const { data, config, http } = props || {};
13
+ const { data, config, http, lang } = props || {};
13
14
  const dataObj = JSON.parse(data || '{}');
14
15
  const { mobile, verifyCodeKey } = dataObj || {};
15
16
  const getKey = async () => {
@@ -17,9 +18,7 @@ const ModalDom = ({ props }) => {
17
18
  const { body: key } = res.data || {};
18
19
  setCaptchaKey(key);
19
20
  if (key) {
20
- console.log('res=>key', key);
21
21
  const image = Api.getCaptchaImgUrl(key);
22
- console.log('image', image);
23
22
  setCaptchaImage(image);
24
23
  }
25
24
  };
@@ -38,21 +37,19 @@ const ModalDom = ({ props }) => {
38
37
  clearInterval(timer);
39
38
  };
40
39
  }, [visible, countdown]);
41
- useEffect(() => {
42
- console.log('mobile', mobile);
43
- }, [mobile]);
40
+ // useEffect(() => {
41
+ // console.log('mobile', mobile);
42
+ // }, [mobile])
44
43
  const handleResend = async () => {
45
44
  setCountdown(60);
46
45
  const res = await Api.reSendCode({ captchaKey, captcha: captchCode });
47
46
  console.log('handleResend=>res', res);
48
- message.success('发送成功');
47
+ message.success(t('sendSuccess', lang));
49
48
  };
50
- return (_jsxs(Modal, { visible: visible, onClose: () => {
49
+ return (_jsxs(Modal, { width: 420, visible: visible, onClose: () => {
51
50
  setVisible(false);
52
51
  props.onClose?.();
53
- }, children: [_jsxs("div", { style: { fontSize: 14, color: '#666' }, children: ["\u5DF2\u53D1\u9001\u77ED\u4FE1\u81F3\u60A8\u7684\u624B\u673A\uFF1A", mobile] }), countdown > 0 ? null : _jsxs("div", { style: { marginBlock: 8, display: 'flex', alignItems: 'center', width: 300 }, children: [_jsx(Input, { placeholder: "\u8BF7\u8F93\u5165\u56FE\u5F62\u9A8C\u8BC1\u7801", onChange: (e) => {
54
- setCaptchCode(e);
55
- } }), captchaImage && _jsx("img", { src: captchaImage, alt: "\u9A8C\u8BC1\u7801", style: { width: 100, height: 30, marginLeft: 8 }, onClick: getKey })] }), (countdown > 0 || captchCode) ? null : _jsx("div", { style: { fontSize: 14, color: 'red' }, children: "\u8BF7\u8F93\u5165\u56FE\u5F62\u9A8C\u8BC1\u7801\u540E\uFF0C\u91CD\u65B0\u53D1\u9001\u9A8C\u8BC1\u7801" }), _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 8, marginTop: 8 }, children: [_jsx(Input.OTP, { length: 6, value: otp, onChange: (val) => {
52
+ }, 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: (val) => {
56
53
  setOtp(val);
57
54
  if (val.length === 6) {
58
55
  http.defaults.headers.common['sms-code'] = val;
@@ -60,6 +57,9 @@ const ModalDom = ({ props }) => {
60
57
  http(config);
61
58
  setVisible(false);
62
59
  }
63
- } }), _jsx(Button, { disabled: countdown > 0 || !captchCode, onClick: handleResend, children: countdown > 0 ? `${countdown}秒` : '重新发送' })] })] }));
60
+ } }), _jsx(Button, { disabled: countdown > 0 || !captchCode, onClick: handleResend, style: { padding: '10px' }, children: countdown > 0 ? t('countDownSecound', lang, { countdown }) : t('reSend', lang) })] }), countdown > 0 ? null :
61
+ _jsxs("div", { style: { marginTop: 12, display: 'flex', alignItems: 'center' }, children: [_jsx(Input, { placeholder: t('pleaseEnterPicVerifyCode', lang), onChange: (e) => {
62
+ setCaptchCode(e);
63
+ }, 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) })] }));
64
64
  };
65
- export default ModalDom;
65
+ export default CreateMessageVerifyModal;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "message-verify",
3
- "version": "0.0.44-beta.0",
3
+ "version": "0.0.45-beta.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "dependencies": {
@@ -4,6 +4,7 @@ interface ModalProps {
4
4
  visible: boolean;
5
5
  onClose: () => void;
6
6
  children: React.ReactNode;
7
+ width?: number | string;
7
8
  }
8
9
 
9
10
  const modalStyle: React.CSSProperties = {
@@ -42,12 +43,15 @@ const closeBtnStyle: React.CSSProperties = {
42
43
  lineHeight: 1,
43
44
  };
44
45
 
45
- const Modal: React.FC<ModalProps> = ({ visible, onClose, children }) => {
46
+ const Modal: React.FC<ModalProps> = ({ visible, onClose, children, width }) => {
46
47
  if (!visible) return null;
47
48
 
48
49
  return (
49
50
  <div style={modalStyle}>
50
- <div style={contentStyle}>
51
+ <div style={{
52
+ ...contentStyle,
53
+ width: width ? (typeof width === 'number' ? `${width}px` : width) : undefined, // 应用width
54
+ }}>
51
55
  <button style={closeBtnStyle} onClick={onClose} aria-label="关闭">
52
56
  ×
53
57
  </button>
package/src/index.tsx CHANGED
@@ -5,6 +5,7 @@ export type ModalConfig = {
5
5
  data: string;
6
6
  onClose?: () => void
7
7
  config: object;
8
+ lang: 'zh' | 'en' | 'id';
8
9
  http: {
9
10
  (params: object): Promise<unknown>;
10
11
  defaults: {
@@ -0,0 +1,9 @@
1
+ export default {
2
+ pleaseEnterPicVerifyCode: 'Please enter the image verification code',
3
+ alreadySend: 'A verification SMS has been sent to your phone: {phone}',
4
+ verifyCode: 'Verification Code',
5
+ pleaseEnterAndSend: 'Please enter the image verification code first, then resend the code',
6
+ sendSuccess: 'Successfully sent',
7
+ reSend: 'Resend',
8
+ countDownSecound: '{countdown} seconds'
9
+ };
@@ -0,0 +1,9 @@
1
+ export default {
2
+ pleaseEnterPicVerifyCode: 'Silakan masukkan kode verifikasi gambar',
3
+ alreadySend: 'SMS verifikasi telah dikirim ke nomor ponsel Anda: {phone}',
4
+ verifyCode: 'Kode Verifikasi',
5
+ pleaseEnterAndSend: 'Harap masukkan kode verifikasi gambar terlebih dahulu, lalu kirim ulang kode',
6
+ sendSuccess: 'Berhasil dikirim',
7
+ reSend: 'Kirim Ulang',
8
+ countDownSecound: '{countdown} detik'
9
+ };
@@ -0,0 +1,9 @@
1
+ export default {
2
+ pleaseEnterPicVerifyCode: '请输入图形验证码',
3
+ alreadySend:'已发送短信至您的手机:{phone}',
4
+ verifyCode: '验证码',
5
+ pleaseEnterAndSend: '请输入图形验证码后,重新发送验证码',
6
+ sendSuccess: '发送成功',
7
+ reSend: '重新发送',
8
+ countDownSecound: '{countdown}秒'
9
+ };
package/src/main.tsx CHANGED
@@ -7,6 +7,7 @@ createRoot(document.getElementById('root')!).render(
7
7
  <button onClick={() => createMessageVerifyModal({
8
8
  data,
9
9
  config: {},
10
+ lang: 'en',
10
11
  http: Object.assign(
11
12
  () => Promise.resolve({}),
12
13
  {
@@ -0,0 +1,30 @@
1
+ import zh from '../locales/zh';
2
+ import en from '../locales/en';
3
+ import id from '../locales/id';
4
+
5
+ type LocaleType = 'zh' | 'en' | 'id';
6
+ type LocaleMessages = Record<string, string>;
7
+
8
+ const locales: Record<LocaleType, LocaleMessages> = {
9
+ zh,
10
+ en,
11
+ id
12
+ };
13
+
14
+ function t(
15
+ key: string,
16
+ language: LocaleType = 'zh',
17
+ params?: Record<string, string | number>,
18
+ ): string {
19
+ const messages = locales[language] || locales.zh;
20
+ let template = messages[key] || '';
21
+ if (params) {
22
+ Object.keys(params).forEach(paramKey => {
23
+ const reg = new RegExp(`{${paramKey}}`, 'g');
24
+ template = template.replace(reg, String(params[paramKey]));
25
+ });
26
+ }
27
+ return template;
28
+ }
29
+
30
+ export default t;
@@ -1,11 +1,13 @@
1
1
  import { useEffect, useState } from 'react'
2
2
  import { Modal, Input, Button, message } from './compoments/index.js'
3
3
  import Api from './resource.js'
4
+ import t from './utils/i18n.js'
4
5
 
5
6
  type ModalConfig = {
6
7
  data: string;
7
8
  onClose?: () => void;
8
9
  config: object;
10
+ lang: 'zh' | 'en' | 'id';
9
11
  http: {
10
12
  (params: object): Promise<unknown>;
11
13
  defaults: {
@@ -17,26 +19,23 @@ type ModalConfig = {
17
19
  }
18
20
  };
19
21
  }
20
- const ModalDom = ({ props }: { props: ModalConfig }) => {
22
+ const CreateMessageVerifyModal = ({ props }: { props: ModalConfig }) => {
21
23
  const [visible, setVisible] = useState(true);
22
24
  const [countdown, setCountdown] = useState(3);
23
25
  const [otp, setOtp] = useState('');
24
26
  const [captchaImage, setCaptchaImage] = useState<string>('');
25
27
  const [captchCode, setCaptchCode] = useState<string>('');
26
28
  const [captchaKey, setCaptchaKey] = useState<string>('');
27
- const { data, config, http } = props || {};
29
+ const { data, config, http, lang } = props || {};
28
30
  const dataObj = JSON.parse(data || '{}');
29
31
  const { mobile, verifyCodeKey } = dataObj || {};
30
32
 
31
-
32
33
  const getKey = async () => {
33
34
  const res = await Api.getCaptchaKey();
34
35
  const { body: key } = res.data || {};
35
36
  setCaptchaKey(key);
36
37
  if(key) {
37
- console.log('res=>key', key);
38
38
  const image = Api.getCaptchaImgUrl(key) as unknown;
39
- console.log('image', image);
40
39
  setCaptchaImage(image as string);
41
40
  }
42
41
  }
@@ -56,58 +55,64 @@ const ModalDom = ({ props }: { props: ModalConfig }) => {
56
55
  };
57
56
  }, [visible, countdown]);
58
57
 
59
- useEffect(() => {
60
- console.log('mobile', mobile);
61
- }, [mobile])
58
+ // useEffect(() => {
59
+ // console.log('mobile', mobile);
60
+ // }, [mobile])
62
61
 
63
62
  const handleResend = async() => {
64
63
  setCountdown(60);
65
64
  const res = await Api.reSendCode({captchaKey, captcha: captchCode});
66
65
  console.log('handleResend=>res', res);
67
- message.success('发送成功');
66
+ message.success(t('sendSuccess', lang));
68
67
  }
69
68
 
70
69
  return (
71
70
  <Modal
71
+ width={420}
72
72
  visible={visible}
73
73
  onClose={() => {
74
74
  setVisible(false);
75
75
  props.onClose?.();
76
76
  }}
77
77
  >
78
- <div style={{ fontSize: 14, color: '#666' }}>已发送短信至您的手机:{mobile}</div>
79
- {countdown > 0 ? null : <div style={{ marginBlock: 8, display: 'flex', alignItems: 'center', width: 300 }}>
80
- <Input
81
- placeholder="请输入图形验证码"
82
- onChange={(e) => {
83
- setCaptchCode(e as string)
84
- }}
85
- />
86
-
87
- {captchaImage && <img src={captchaImage} alt="验证码" style={{ width: 100, height: 30, marginLeft: 8 }} onClick={getKey} />}
88
- </div>}
89
- {(countdown > 0 || captchCode) ? null : <div style={{ fontSize: 14, color: 'red' }}>请输入图形验证码后,重新发送验证码</div>}
90
- <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 8 }}>
91
- <Input.OTP length={6}
92
- value={otp}
93
- onChange={(val) => {
94
- setOtp(val);
95
- if(val.length === 6) {
96
- http.defaults.headers.common['sms-code'] = val as string;
97
- http.defaults.headers.common['sms-code-key'] = verifyCodeKey as string;
98
- http(config);
99
- setVisible(false);
100
- }
101
- }} />
78
+ <div style={{ fontSize: 14, color: '#666' }}>{t('alreadySend', lang, { phone: mobile})}</div>
79
+
80
+ <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 12 }}>
81
+ <Input.OTP
82
+ length={6}
83
+ value={otp}
84
+ onChange={(val) => {
85
+ setOtp(val);
86
+ if(val.length === 6) {
87
+ http.defaults.headers.common['sms-code'] = val as string;
88
+ http.defaults.headers.common['sms-code-key'] = verifyCodeKey as string;
89
+ http(config);
90
+ setVisible(false);
91
+ }
92
+ }} />
102
93
  <Button
103
94
  disabled={countdown > 0 || !captchCode}
104
95
  onClick={handleResend}
96
+ style={{ padding: '10px' }}
105
97
  >
106
- {countdown > 0 ? `${countdown}秒` : '重新发送'}
98
+ {countdown > 0 ? t('countDownSecound', lang, { countdown }) : t('reSend', lang)}
107
99
  </Button>
108
100
  </div>
101
+ {countdown > 0 ? null :
102
+ <div style={{ marginTop: 12, display: 'flex', alignItems: 'center' }}>
103
+ <Input
104
+ placeholder={t('pleaseEnterPicVerifyCode', lang)}
105
+ onChange={(e) => {
106
+ setCaptchCode(e as string)
107
+ }}
108
+ style={{ width: 300 }}
109
+ />
110
+
111
+ {captchaImage && <img src={captchaImage} alt={t('verifyCode', lang)} style={{ width: 100, height: 30, marginLeft: 8 }} onClick={getKey} />}
112
+ </div>}
113
+ {(countdown > 0 || captchCode) ? null : <div style={{ fontSize: 14, color: 'red' }}>{t('pleaseEnterAndSend', lang)}</div>}
109
114
  </Modal>
110
115
  );
111
116
  };
112
117
 
113
- export default ModalDom;
118
+ export default CreateMessageVerifyModal;