网易云拼图校验-笔记

306 阅读2分钟

网易云拼图校验-笔记

1.网易云拼图容器

<div id="captcha"></div>

2.初始化挂载拼图校验js

init() {
    if (!(window as any).initNECaptcha) {
            const s = document.createElement('script');
            s.type = 'text/javascript';
            // 可下载本地引入
            s.src = 'https://cstaticdun.126.net/load.min.js';
            document.body.appendChild(s);
    }
}

3.获取网易云盾验证

onCaptchaInsData() {
    let captchaIns = null;

    return new Promise((resolve, reject) => {
        (window as any).initNECaptcha(
            {
                captchaId: '', // 申请的ID
                element: '#captcha', // 容器id
                mode: 'popup',
                width: '320px',
                enableClose: false,
                onClose: function () {
                    captchaIns.refresh();
                },
                onVerify: function (err, data) {
                    if (!err) {
                        // 通过data.validate去请求发送验证码-此处补充方法
                        resolve(data.validate);
                    }
                }
            },
            function onload(instance) {
                captchaIns = instance;
                captchaIns.popUp();
            },
            function onerror() {
                MUtils.toast('获取滑块验证码失败', MESSAGE_TYPE.error);
                reject();
            }
        );
    });
}


export default defineComponent({
    setup(props, context) {
            const constants = {
                ONE_MIN: 60 // 验证码计时用
            };

            const state = reactive<StateModel>({
                dialogVisible: false, // 提示弹窗开关
                nextDisabled: true, // 继续按钮disabled
                userInfo: null, // 用户验证信息
                smsCode: null, // 验证码
                countDownTime: constants.ONE_MIN, // 验证码计时器秒
                codeTimer: null,
                verificationCodeKey: '' // 验证码key值
            });

            // 监听弹窗开关变化
            watch(
                () => state.dialogVisible,
                newVal => {
                    if (newVal) {
                        methods.init();
                    }
                }
            );

            // 监听是否关闭弹窗
            watch(
                () => props.closeCheckTip,
                newVal => {
                    if (newVal) {
                        state.dialogVisible = !newVal;
                    }
                }
            );

            // 验证码按钮文本
            const checkCodeText = computed(() => {
                return state.countDownTime < constants.ONE_MIN ? `重新获取${state.countDownTime}s` : '获取验证码';
            });

            // 验证码按钮disabled
            const disabled = computed(() => {
                return state.countDownTime < constants.ONE_MIN;
            });

            // 继续按钮disabled
            const nextDisabled = computed(() => {
                return state.verificationCodeKey && !state.smsCode;
            });

            // 方法
            const methods = {
                /**
                 * 页面初始化
                 */
                init(): void {
                    state.countDownTime = constants.ONE_MIN;
                    state.verificationCodeKey = '';
                    state.smsCode = null;
                    methods.clearTimer();

                    //首页初始化挂载拼图校验js
                    if (!(window as any).initNECaptcha) {
                        const s = document.createElement('script');
                        s.type = 'text/javascript';
                        s.src = CSTATICDUN_URL;
                        document.body.appendChild(s);
                    }
                },

                /**
                 * 打开提示弹窗
                 * @param {UserInfoModel} info 用户验证信息
                 */
                show(info: UserInfoModel): void {
                    state.userInfo = info;

                    state.dialogVisible = true;
                },

                /**
                 * 限制输入整数
                 */
                onSmsCode(): void {
                    state.smsCode = state.smsCode.replace(/[^0-9]/g, '');
                },

                /**
                 * 点击继续
                 */
                onContinue(): void {
                    // 去调接口导出文件
                    context.emit('openExportTip', {
                        smsCode: state.smsCode,
                        verificationCodeKey: state.verificationCodeKey,
                        phoneOwnerUserId: state.userInfo.phoneOwnerUserId
                    });
                },

                /**
                 * 获取网易云盾验证
                 */
                onCaptchaInsData() {
                    let captchaIns = null;

                    return new Promise((resolve, reject) => {
                        (window as any).initNECaptcha(
                            {
                                captchaId: CAPTCHA_ID,
                                element: '#captcha',
                                mode: 'popup',
                                width: '320px',
                                enableClose: false,
                                onClose: function () {
                                    captchaIns.refresh();
                                },
                                onVerify: function (err, data) {
                                    if (!err) {
                                            methods.getNextCloudKey(data.validate);
                                        resolve(data.validate);
                                    }
                                }
                            },
                            function onload(instance) {
                                captchaIns = instance;
                                captchaIns.popUp();
                            },
                            function onerror() {
                                MUtils.toast('获取滑块验证码失败', MESSAGE_TYPE.error);
                                reject();
                            }
                        );
                    });
                },

                /**
                 * 网易云验证码换key
                 * @param {string} key 网易云盾验证key
                 */
                getNextCloudKey(key: string) {
                    const userId = state.userInfo.phoneOwnerUserId;

                    return new Promise((resolve, reject) => {
                        NewGetSmsCodeToUserStore.request({ userId, NECaptchaValidate: key })
                            .getData()
                            .then(res => {
                                state.verificationCodeKey = res.value;
                                methods.onCheckCodeCount();
                                resolve(res);
                            })
                            .catch(err => {
                                reject(err);
                            });
                        });
                },

                /**
                 * 验证码定时器
                 */
                onCheckCodeCount(): void {
                    const timerFunction = () => {
                        if (state.countDownTime === 1) {
                                methods.clearTimer();
                                return (state.countDownTime = constants.ONE_MIN);
                        }
                        state.countDownTime = state.countDownTime - 1;
                    };

                    timerFunction();
                    state.codeTimer = setInterval(timerFunction, 1000);
                },

                /**
                 * 清除定时器
                 */
                clearTimer(): void {
                        clearInterval(state.codeTimer);
                        state.codeTimer = null;
                }
            };

        return {
                ...toRefs(state),
                ...methods,
                disabled,
                nextDisabled,
                checkCodeText
        };
    }
});