message-verify 1.0.1-beta.43 → 1.0.1-beta.44
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/dist/index.d.ts +1 -1
- package/dist/index.js +22 -23
- package/dist/modal/relogin-modal.d.ts +5 -0
- package/dist/modal/relogin-modal.js +24 -0
- package/dist/modal/verify-modal.d.ts +5 -0
- package/dist/modal/verify-modal.js +115 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/resource.d.ts +2 -0
- package/dist/utils/resource.js +7 -0
- package/dist/utils/type.d.ts +1 -0
- package/package.json +1 -1
- package/src/index.tsx +23 -31
- package/src/{relogin-modal.tsx → modal/relogin-modal.tsx} +5 -4
- package/src/{verify-modal.tsx → modal/verify-modal.tsx} +6 -6
- package/src/utils/type.ts +1 -0
- /package/src/{resource.ts → utils/resource.ts} +0 -0
package/dist/index.d.ts
CHANGED
@@ -1,4 +1,4 @@
|
|
1
1
|
import { VerifyModalConfig, LoginModalConfig } from './utils/type.js';
|
2
2
|
export declare const initFingerprint: () => Promise<string>;
|
3
3
|
export declare const createReLoginModal: (modalProps: LoginModalConfig) => void;
|
4
|
-
export declare const VerifyHandler: (
|
4
|
+
export declare const VerifyHandler: ({ data, config, http, verifyPromise, sendApi }: VerifyModalConfig) => Promise<any>;
|
package/dist/index.js
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
2
2
|
import ReactDOM from 'react-dom/client';
|
3
|
-
import VerifyModal from './verify-modal.js';
|
3
|
+
import VerifyModal from './modal/verify-modal.js';
|
4
4
|
import Fingerprint2 from 'fingerprintjs2';
|
5
|
-
import ReLoginModal from './relogin-modal.js';
|
5
|
+
import ReLoginModal from './modal/relogin-modal.js';
|
6
6
|
let fingerprintPromise = null; // 用 Promise 本身作为缓存
|
7
|
+
let modalRoot = null;
|
7
8
|
export const initFingerprint = async () => {
|
8
9
|
console.log('fingerprintPromise:', fingerprintPromise);
|
9
10
|
if (!fingerprintPromise) {
|
@@ -24,38 +25,36 @@ export const initFingerprint = async () => {
|
|
24
25
|
}
|
25
26
|
return fingerprintPromise;
|
26
27
|
};
|
27
|
-
|
28
|
-
|
28
|
+
const destroyModal = (modalId) => {
|
29
|
+
if (modalRoot) {
|
30
|
+
modalRoot.unmount();
|
31
|
+
document.getElementById(modalId)?.remove();
|
32
|
+
modalRoot = null;
|
33
|
+
}
|
34
|
+
};
|
35
|
+
const creatModal = (modalProps, modalId, ModalDom) => {
|
36
|
+
destroyModal(modalId);
|
29
37
|
const container = document.createElement('div');
|
38
|
+
container.id = modalId;
|
30
39
|
document.body.appendChild(container);
|
31
40
|
modalRoot = ReactDOM.createRoot(container);
|
32
|
-
modalRoot.render(_jsx(
|
41
|
+
modalRoot.render(_jsx(ModalDom, { props: {
|
33
42
|
...modalProps,
|
34
43
|
onClose: () => {
|
35
|
-
|
36
|
-
destroyModal();
|
44
|
+
destroyModal(modalId);
|
37
45
|
}
|
38
46
|
} }));
|
39
47
|
};
|
48
|
+
const createMessageVerifyModal = (modalProps) => {
|
49
|
+
const verifyModalId = 'verify-modal-container';
|
50
|
+
creatModal(modalProps, verifyModalId, VerifyModal);
|
51
|
+
};
|
40
52
|
// 新增 relogin 弹窗创建方法
|
41
53
|
export const createReLoginModal = (modalProps) => {
|
42
|
-
const
|
43
|
-
|
44
|
-
document.body.appendChild(container);
|
45
|
-
modalRoot = ReactDOM.createRoot(container);
|
46
|
-
modalRoot.render(_jsx(ReLoginModal, { props: {
|
47
|
-
...modalProps,
|
48
|
-
} }));
|
49
|
-
};
|
50
|
-
const destroyModal = () => {
|
51
|
-
if (modalRoot) {
|
52
|
-
modalRoot.unmount();
|
53
|
-
document.getElementById('antd-modal-container')?.remove();
|
54
|
-
modalRoot = null;
|
55
|
-
}
|
54
|
+
const reLoginModalId = 'relogin-modal-container';
|
55
|
+
creatModal(modalProps, reLoginModalId, ReLoginModal);
|
56
56
|
};
|
57
|
-
export const VerifyHandler = (
|
58
|
-
const { data, config, http, verifyPromise, sendApi } = modalProps || {};
|
57
|
+
export const VerifyHandler = ({ data, config, http, verifyPromise, sendApi }) => {
|
59
58
|
const toEmpty = () => {
|
60
59
|
verifyPromise.current = null;
|
61
60
|
};
|
@@ -0,0 +1,24 @@
|
|
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;
|
@@ -0,0 +1,115 @@
|
|
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
|
+
})
|
94
|
+
]);
|
95
|
+
if (res?.data?.status?.code === 0) {
|
96
|
+
apiResolve(res);
|
97
|
+
setVisible(false);
|
98
|
+
}
|
99
|
+
else {
|
100
|
+
message.error('验证失败');
|
101
|
+
setOtp('');
|
102
|
+
}
|
103
|
+
}
|
104
|
+
catch (error) {
|
105
|
+
console.warn('catch', error);
|
106
|
+
message.error('验证失败');
|
107
|
+
setOtp('');
|
108
|
+
}
|
109
|
+
}
|
110
|
+
} }), _jsx(Button, { disabled: countdown > 0 || !captchCode, onClick: handleResend, style: { padding: '8px' }, children: countdown > 0 ? t('countDownSecound', lang, { countdown }) : t('reSend', lang) })] }), countdown > 0 ? null :
|
111
|
+
_jsxs("div", { style: { marginTop: 12, display: 'flex', alignItems: 'center' }, children: [_jsx(Input, { placeholder: t('pleaseEnterPicVerifyCode', lang), onChange: (e) => {
|
112
|
+
setCaptchCode(e);
|
113
|
+
}, 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) })] }));
|
114
|
+
};
|
115
|
+
export default CreateMessageVerifyModal;
|
@@ -1 +1 @@
|
|
1
|
-
{"root":["../src/index.tsx","../src/main.tsx","../src/
|
1
|
+
{"root":["../src/index.tsx","../src/main.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/modal/relogin-modal.tsx","../src/modal/verify-modal.tsx","../src/utils/i18n.ts","../src/utils/resource.ts","../src/utils/status.ts","../src/utils/type.ts"],"version":"5.7.3"}
|
@@ -0,0 +1,7 @@
|
|
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);
|
package/dist/utils/type.d.ts
CHANGED
package/package.json
CHANGED
package/src/index.tsx
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
import ReactDOM from 'react-dom/client'
|
2
|
-
import VerifyModal from './verify-modal.js'
|
2
|
+
import VerifyModal from './modal/verify-modal.js'
|
3
3
|
import Fingerprint2 from 'fingerprintjs2';
|
4
|
-
import ReLoginModal from './relogin-modal.js';
|
4
|
+
import ReLoginModal from './modal/relogin-modal.js';
|
5
5
|
import { VerifyModalConfig, LoginModalConfig } from './utils/type.js';
|
6
6
|
|
7
7
|
let fingerprintPromise: Promise<string> | null = null; // 用 Promise 本身作为缓存
|
8
|
-
|
8
|
+
let modalRoot: ReactDOM.Root | null = null
|
9
9
|
export const initFingerprint = async (): Promise<string> => {
|
10
10
|
console.log('fingerprintPromise:', fingerprintPromise);
|
11
11
|
if (!fingerprintPromise) {
|
@@ -27,52 +27,44 @@ export const initFingerprint = async (): Promise<string> => {
|
|
27
27
|
return fingerprintPromise;
|
28
28
|
};
|
29
29
|
|
30
|
-
|
30
|
+
const destroyModal = (modalId: string) => {
|
31
|
+
if (modalRoot) {
|
32
|
+
modalRoot.unmount()
|
33
|
+
document.getElementById(modalId)?.remove()
|
34
|
+
modalRoot = null
|
35
|
+
}
|
36
|
+
}
|
31
37
|
|
32
|
-
const
|
38
|
+
const creatModal = (modalProps: VerifyModalConfig | LoginModalConfig, modalId: string, ModalDom:any) => {
|
39
|
+
destroyModal(modalId);
|
33
40
|
const container = document.createElement('div')
|
41
|
+
container.id = modalId
|
34
42
|
document.body.appendChild(container)
|
35
43
|
|
36
44
|
modalRoot = ReactDOM.createRoot(container)
|
37
45
|
modalRoot.render(
|
38
|
-
<
|
46
|
+
<ModalDom
|
39
47
|
props={{
|
40
48
|
...modalProps,
|
41
49
|
onClose: () => {
|
42
|
-
|
43
|
-
destroyModal()
|
50
|
+
destroyModal(modalId);
|
44
51
|
}
|
45
52
|
}}
|
46
53
|
/>
|
47
54
|
)
|
48
55
|
}
|
49
56
|
|
57
|
+
const createMessageVerifyModal = (modalProps: VerifyModalConfig) => {
|
58
|
+
const verifyModalId = 'verify-modal-container';
|
59
|
+
creatModal(modalProps, verifyModalId, VerifyModal);
|
60
|
+
}
|
50
61
|
// 新增 relogin 弹窗创建方法
|
51
62
|
export const createReLoginModal = (modalProps: LoginModalConfig) => {
|
52
|
-
const
|
53
|
-
|
54
|
-
document.body.appendChild(container)
|
55
|
-
|
56
|
-
modalRoot = ReactDOM.createRoot(container)
|
57
|
-
modalRoot.render(
|
58
|
-
<ReLoginModal
|
59
|
-
props={{
|
60
|
-
...modalProps,
|
61
|
-
}}
|
62
|
-
/>
|
63
|
-
)
|
64
|
-
}
|
65
|
-
|
66
|
-
const destroyModal = () => {
|
67
|
-
if (modalRoot) {
|
68
|
-
modalRoot.unmount()
|
69
|
-
document.getElementById('antd-modal-container')?.remove()
|
70
|
-
modalRoot = null
|
71
|
-
}
|
63
|
+
const reLoginModalId = 'relogin-modal-container';
|
64
|
+
creatModal(modalProps, reLoginModalId, ReLoginModal);
|
72
65
|
}
|
73
66
|
|
74
|
-
export const VerifyHandler = (
|
75
|
-
const {data, config, http, verifyPromise, sendApi} = modalProps || {};
|
67
|
+
export const VerifyHandler = ({data, config, http, verifyPromise, sendApi}: VerifyModalConfig): Promise<any> => {
|
76
68
|
const toEmpty = () => {
|
77
69
|
verifyPromise.current = null;
|
78
70
|
};
|
@@ -86,7 +78,7 @@ export const VerifyHandler = (modalProps: VerifyModalConfig): Promise<any> => {
|
|
86
78
|
apiReject: reject,
|
87
79
|
apiPromiseToEmpty: toEmpty,
|
88
80
|
sendApi
|
89
|
-
} as
|
81
|
+
} as VerifyModalConfig);
|
90
82
|
}).finally(toEmpty);
|
91
83
|
}
|
92
84
|
return verifyPromise.current;
|
@@ -1,14 +1,15 @@
|
|
1
1
|
import { useState } from 'react'
|
2
|
-
import { Modal, Button } from '
|
3
|
-
import { LoginModalConfig } from '
|
4
|
-
import t from '
|
2
|
+
import { Modal, Button } from '../compoments/index.js'
|
3
|
+
import { LoginModalConfig } from '../utils/type.js';
|
4
|
+
import t from '../utils/i18n.js'
|
5
5
|
|
6
6
|
const ReLoginModal = ({ props }: { props: LoginModalConfig }) => {
|
7
|
-
const { goLogin, lang } = props || {};
|
7
|
+
const { goLogin, lang, onClose: destroyModal } = props || {};
|
8
8
|
const [visible, setVisible] = useState(true);
|
9
9
|
const onClose = () => {
|
10
10
|
setVisible(false);
|
11
11
|
goLogin();
|
12
|
+
destroyModal?.();
|
12
13
|
};
|
13
14
|
return (
|
14
15
|
<Modal visible={visible} onClose={onClose} width={420}>
|
@@ -1,8 +1,8 @@
|
|
1
1
|
import { useEffect, useState } from 'react'
|
2
|
-
import { Modal, Input, Button, message } from '
|
3
|
-
import Api from '
|
4
|
-
import t from '
|
5
|
-
import { VerifyModalConfig } from '
|
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
6
|
import { axios } from '@yqg/resource';
|
7
7
|
|
8
8
|
const CreateMessageVerifyModal = ({ props }: { props: VerifyModalConfig }) => {
|
@@ -12,7 +12,7 @@ const CreateMessageVerifyModal = ({ props }: { props: VerifyModalConfig }) => {
|
|
12
12
|
const [captchaImage, setCaptchaImage] = useState<string>('');
|
13
13
|
const [captchCode, setCaptchCode] = useState<string>('');
|
14
14
|
const [captchaKey, setCaptchaKey] = useState<string>('');
|
15
|
-
const { data, http, lang, sendApi = '/admin/sms/send', config, apiResolve, apiPromiseToEmpty } = props || {};
|
15
|
+
const { data, http, lang, sendApi = '/admin/sms/send', config, apiResolve, apiPromiseToEmpty, onClose } = props || {};
|
16
16
|
const dataObj = JSON.parse(data || '{}');
|
17
17
|
const { mobile, verifyCodeKey } = dataObj || {};
|
18
18
|
|
@@ -73,7 +73,7 @@ const CreateMessageVerifyModal = ({ props }: { props: VerifyModalConfig }) => {
|
|
73
73
|
onClose={() => {
|
74
74
|
setVisible(false);
|
75
75
|
apiPromiseToEmpty?.();
|
76
|
-
|
76
|
+
onClose?.();
|
77
77
|
}}
|
78
78
|
>
|
79
79
|
<div style={{ fontSize: 14, color: '#666' }}>{t('alreadySend', lang, { phone: mobile })}</div>
|
package/src/utils/type.ts
CHANGED
File without changes
|