第53章 短信验证服务和登录的前端定义实现

news2024/11/19 3:49:26

1 src\router\index.js添加定义

  {

        path: '/LoginSms',

        name: '手机号登录',

        component: () => import('../views/LoginSmsView.vue')

    },

    {

        path: '/Users/Register',

        name: '用户注册',

        component: () => import('../views/Users/RegisterView.vue'),

    },

2 向src\common\http.api.js添加定义

/****************************API集中管理--用户模块************************************/

//通过1个指定电子邮箱获取1个指定的用户实例,该API主要用于验证电子邮箱的唯一性。

export const getCustomerByEmail = async params => {

    return await axiosInterceptor.get('/Customer/IsEmail', {

        params: params

    });

};

//通过1个指定手机号获取1个指定的用户实例,该API主要用于验证手机号的唯一性。

export const getCustomerByPhone = async params => {

    return await axiosInterceptor.get('/Customer/IsPhone', {

        params: params

    });

};

//通过1个指定手机号获取1个指定的有效短信验证码。

export const getCodeByPhone = async params => {

    return await axiosInterceptor.get('/Customer/IsCode', {

        params: params

    });

};

//1个指定用户实例持久化到用户表中。

export const postCustomerRegister = async params => {

    return await axiosInterceptor.post('/Customer/Register', params);

};

//1个指定手机发送1个指定的短信验证码,并把该短信验证码实例例持久化到短信验证表中。

export const postSmsValidateCreate = async params => {

    return await axiosInterceptor.post('/Customer/SmsValidateCreate', params);

};

//1个指定手机号的登录操作。

export const postCustomerLoginSms = async params => {

    return await axiosInterceptor.post('/Customer/LoginSms', params);

};

3 src\views\Users\RegisterView.vue

<template>

    <el-form :model="registerForm" :rules="registerRule" ref="refRule" label-width="100px" class="demo-ruleForm"

        label-position="left" status-icon>

        <h3 class="title">用户注册</h3>

        <el-form-item label="账号:" prop="name">

            <el-input type="text" v-model="registerForm.name" maxlength="16" minlength="2" show-word-limit />

        </el-form-item>

        <el-form-item label="电子邮箱:" prop="email">

            <el-input v-model="registerForm.email" />

        </el-form-item>

        <el-form-item label="手机号:" prop="phone">

            <el-input type="text" v-model="registerForm.phone">

                <template #prepend>+86</template>

            </el-input>

        </el-form-item>

        <el-form-item label="密码:" prop="password">

            <el-input type="password" v-model="registerForm.password"  show-password />

        </el-form-item>

        <el-form-item label="确认密码:" prop="confirmPassword">

            <el-input type="password" v-model="registerForm.confirmPassword" show-password />

        </el-form-item>

    </el-form>

    <el-button type="primary" @click="onSubmit"> </el-button>

</template>

<script>

    import {

        getCustomerByEmail,

        getCustomerByPhone,

        postCustomerRegister

    } from '../../common/http.api.js';

    export default {

        data() {

            //验证1个指定的电子邮箱已经是否被注册。

            const validateEmailUnique = async (rule, value, callback) => {

                if (value) {

                    let data = await this.isEmailUnique(value);

                    //console.log(data);

                    if (data.status == 200 && data.response) {

                        callback(new Error("该电子邮箱已经被注册!"));

                    } else {

                        callback();

                    }

                }

            };

            //验证1个指定的手机号已经是否被注册。

            const validatePhoneUnique = async (rule, value, callback) => {

                if (value) {

                    let data = await this.isPhoneUnique(value);

                    // console.log(data);

                    if (data.status == 200 && data.response) {

                        callback(new Error("该手机号已经被注册!"));

                    } else {

                        callback();

                    }

                }

            };

            //验证密码与确认密码的输入是否一致。

            const validateConfirmPassword = (rule, value, callback) => {

                if (value === "") {

                    callback(new Error("请输入确认密码!"));

                } else if (value !== this.registerForm.password) {

                    callback(new Error("两次输入密码不一致!"));

                } else {

                    callback();

                }

            };

            return {

                //用户注册表单初始化。

                registerForm: {

                    name: '',

                    email: '',

                    phone: '',

                    password: '',

                    confirmPassword: '',

                },

                //用户注册表单输入验证初始化。

                registerRule: {

                    name: [{

                            required: true,

                            message: '请输入账号名!',

                            trigger: 'blur',

                        },

                        {

                            min: 2,

                            max: 16,

                            message: '账号名的长度应在216个字符之间!',

                            trigger: 'blur'

                        },

                    ],

                    email: [{

                            required: true,

                            message: '请输入电子邮箱!',

                            trigger: 'blur',

                        },

                        {

                            pattern: /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/,

                            message: "电子邮箱格式错误!"

                        },

                        {

                            validator: validateEmailUnique,

                            trigger: "blur",

                        },

                    ],

                    phone: [{

                            required: true,

                            message: "请输入手机号!",

                            trigger: 'blur',

                        },

                        {

                            pattern: 11 && /^((13|14|15|16|17|18|19)[0-9]{1}\d{8})$/,

                            message: "手机号格式错误!"

                        },

                        {

                            validator: validatePhoneUnique,

                            trigger: "blur",

                        },

                    ],

                    password: [{

                            required: true,

                            message: "请输入密码!",

                            trigger: "blur"

                        },

                        {

                            min: 6,

                            max: 20,

                            message: "长度在620个字符!",

                            trigger: "blur",

                        },

                        {

                            required: true,

                            pattern: /^(?![a-zA-Z]+$)(?![A-Z0-9]+$)(?![A-Z\W_!@#$%^&*`~()-+=]+$)(?![a-z0-9]+$)(?![a-z\W_!@#$%^&*`~()-+=]+$)(?![0-9\W_!@#$%^&*`~()-+=]+$)[a-zA-Z0-9\W_!@#$%^&*`~()-+=]{6,20}$/,

                            message: "包含大小写字母、数字和特殊字符的三种!",

                            trigger: "blur",

                        },

                    ],

                    confirmPassword: [{

                        validator: validateConfirmPassword,

                        trigger: "blur"

                    }, ],

                },

            };

        },

        methods: {

            //通过1个指定电子邮箱获取1个指定的用户实例,验证电子邮箱的唯一性。

            async isEmailUnique(email) {

                let emailParam = {

                    email: email,

                };

                let res = await getCustomerByEmail(emailParam);

                return res.data;

            },

            //1个指定手机号获取1个指定的用户实例,验证手机号的唯一性。

            async isPhoneUnique(phone) {

                let phoneParam = {

                    phone: phone,

                };

                let res = await getCustomerByPhone(phoneParam);

                return res.data;

            },

            //添加提交事件

            async onSubmit() {

                this.$refs.refRule.validate(async (valid) => {

                    if (valid) {

                       

                        let customer = {

                            Name: this.registerForm.name,

                            Email: this.registerForm.email,

                            Phone: this.registerForm.phone,

                            Password: this.registerForm.password,

                        };

                       

                       let res = await postCustomerRegister(JSON.stringify(customer));

                       if (res.status == 200) {

                            this.$router.push('/LoginSms')

                       } else {

                           this.$message.error(res.msg);

                       }

                    } else {

                        this.$message.error('输入不能通过验证 !');

                        return false;

                    }

                });

            },

        },

        async mounted() {

        },

    }

</script>

<style>

</style>

4 src\views\LoginSmsView.vue

<template>

    <div class="wrapper">

        <div class="bg bg-blur" style="display: none;"></div>

        <div style="height: 20%;"></div>

        <el-form :model="loginSmsForm" :rules="loginSmsRule" ref="refRule" label-position="left" label-width="0px"

            class="login-container">

            <h3 class="title">手机号登录</h3>

            <el-form-item prop="phone">

                <!-- refPhoneRequired:用于在短信验证码发送前必须先输入1个指定的手机号。 -->

                <el-input type="text" v-model="loginSmsForm.phone" ref="refPhoneRequired" auto-complete="off" placeholder="手机号" >

                </el-input>

            </el-form-item>

            <el-form-item prop="password">

                <el-input v-model="loginSmsForm.password" auto-complete="off" show-password placeholder="密码"></el-input>

            </el-form-item>

            <el-form-item prop="code">

                <el-input v-model="loginSmsForm.code" auto-complete="off" placeholder="短信验证码" class="inputCode">

                </el-input>

                <el-button v-show="sendCode" type="primary" style="width:130px" @click="postSmsValidate">

                    <el-icon style="vertical-align: middle; margin-right: 5px;">

                        <Iphone />

                    </el-icon>

                    发送短信验证码

                </el-button>

                <el-button v-show="!sendCode" color="#909399" :dark="isDark" disabled style="width:130px">

                    <el-icon style="vertical-align: middle; margin-right: 5px;">

                        <Clock />

                    </el-icon>

                    重新发送<strong>{{time}}</strong>

                </el-button>

            </el-form-item>

            <el-form-item style="width:100%;">

                <el-button type="primary" style="width:100%;" @click="onSubmit">

                    登录

                </el-button>

            </el-form-item>

        </el-form>

    </div>

</template>

<script>

    import {

        postSmsValidateCreate,

        getCustomerByPhone,

        getCodeByPhone,

        postCustomerLoginSms

    } from '../common/http.api.js';

    export default {

        data() {

            //验证1个指定的手机号已经是否被注册。

            const validatePhoneUnique = async (rule, value, callback) => {

                if (value) {

                    let data = await this.isPhoneUnique(value);

                    // console.log(data);

                    if (data.status == 200 && data.response) {

                        callback();

                    } else {

                        callback(new Error("该手机号未被注册,请使用该手机号进行注册!"));

                    }

                }

            };

            //验证1个指定手机号获取1个指定的有效短信验证码是否有效。

            const validateCode = async (rule, value, callback) => {

                if (value) {

                    let data = await this.isCode(this.loginSmsForm.phone, value);

                    // console.log(data);

                    if (data.status == 200 && data.response) {

                        callback();

                    } else {

                        callback(new Error("没有有效短信验证码,请重新发送短信验证码到手机!"));

                    }

                }

            };

            return {

                //通过v-show控制显示获取按钮'还是倒计时'

                sendCode: true,

                //短信验证码发送最小间隔倒计时时间:60秒。

                time: 60,

                isDark: true,

                loginSmsForm: {

                    phone: '',

                    password: '',

                    code: '',

                },

                //用户注册表单输入验证初始化。

                loginSmsRule: {

                    phone: [{

                            required: true,

                            message: "请输入手机号!",

                            trigger: 'blur',

                        },

                        {

                            pattern: 11 && /^((13|14|15|16|17|18|19)[0-9]{1}\d{8})$/,

                            message: "手机号格式错误!"

                        },

                        {

                            validator: validatePhoneUnique,

                            trigger: "blur",

                        },

                    ],

                    password: [{

                        required: true,

                        message: "请输入密码!",

                        trigger: "blur"

                    }],

                    code: [{

                            required: true,

                            message: "请输入短信验证码!",

                            trigger: 'blur',

                        },

                        {

                            min: 6,

                            max: 6,

                            message: "短信验证码必是6位数字!",

                            trigger: "blur",

                        },

                        {

                            validator: validateCode,

                            trigger: "blur",

                        },

                    ],

                },

            };

        },

        methods: {

            //1个指定手机号获取1个指定的用户实例,验证手机号的唯一性。

            async isPhoneUnique(phone) {

                let phoneParam = {

                    phone: phone,

                };

                let res = await getCustomerByPhone(phoneParam);

                return res.data;

            },

            //通过1个指定手机号获取1个指定的有效短信验证码,为登录操作提供数据支撑。

            async isCode(phone, code) {

                let codeParam = {

                    phone: phone,

                    code: code,

                };

                console.log(codeParam)

                let res = await getCodeByPhone(codeParam);

                return res.data;

            },

            async postSmsValidate() {

                if (this.loginSmsForm.phone == '') {

                    this.$refs.refPhoneRequired.focus();

                    this.$message.error('必须先输入手机号!');

                } else {

                    let phone = this.loginSmsForm.phone;

                    let res = await postSmsValidateCreate(JSON.stringify(phone));

                    if (res.status == 200) {

                        this.sendCode = false;

                        //设置秒倒计时器。

                        var timetimer = setInterval(() => {

                            this.time--;

                            if (this.time <= 0) {

                                this.sendCode = true;

                                this.time = 60;

                                //用于限定秒倒计时器实例,能且只能被触发执行1次。

                                clearInterval(timetimer);

                            }

                        }, 1000);

                    } else {

                        this.$message.error(res.msg);

                    }

                }

               

            },

            async onSubmit() {

                this.$refs.refRule.validate(async (valid) => {

                    if (valid) {

                        let loginParams = {

                            phone: this.loginSmsForm.phone,

                            password: this.loginSmsForm.password,

                            code: this.loginSmsForm.code

                        };

                        let res = await postCustomerLoginSms(JSON.stringify(loginParams));

                        //console.log(res);

                        let userToken = 'Bearer ' + res.data.response.token;

                        this.$store.commit("saveToken", userToken);

                        //1个指定用户的1个指定令牌字符串的过期时间进行全局化存储。

                        var curTime = new Date();

                        var expiresIn = new Date(curTime.setSeconds(curTime.getSeconds() + res.data

                            .response.expiresIn));

                        this.$store.commit("saveExpiresIn", expiresIn);

                        if (res.status == 200) {

                            let token = localStorage.getItem('Token');

                            if (token === null || token === '') {

                                await this.$router.replace(this.$route.query.redirect ? this.$route.query

                                    .redirect : "/");

                            }

                            await this.$router.replace(this.$route.query.redirect ? this.$route.query

                                .redirect : "/Login");

                        } else {

                            this.$message.error(res.msg);

                        }

                    }

                });

            },

        },

        mounted() {

        },

    }

</script>

<style lang="scss">

    .wrapper {

        background: #50a3a2;

        background: -webkit-linear-gradient(top left, #50a3a2 0%, #53e3a6 100%);

        background: linear-gradient(to bottom right, #127c7b 0, #50a3a2);

        opacity: 0.8;

        position: absolute;

        left: 0;

        width: 100%;

        height: 100%;

        overflow: hidden;

    }

    .bg {

        margin: 0px;

        position: absolute;

        left: 0;

        top: 0;

        right: 0;

        bottom: 0;

        background-repeat: no-repeat;

        background-size: cover;

        width: 100%;

        height: 100%;

    }

    .login-container {

        -webkit-border-radius: 5px;

        border-radius: 5px;

        -moz-border-radius: 5px;

        background-clip: padding-box;

        margin: auto;

        width: 350px;

        padding: 35px 35px 15px 35px;

        background: #fff;

        border: 1px solid #eaeaea;

        box-shadow: 0 0 25px #cac6c6;

        z-index: 9999;

        position: relative;

    }

    .login-container .title {

        margin: 0px auto 40px auto;

        text-align: center;

        color: #505458;

    }

    .inputCode {

        width: 150px;

        margin-right: 10px;

    }

</style>

对以上功能更为具体实现和注释见:230304_012shopvue(短信验证服务和登录的前端定义实现)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/388665.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Javascript借用原型对象继承父类型方法

借用原型对象继承父类型方法 目的: 儿子继承父类属性和方法&#xff0c;父类之后新增的方法不会被儿子继承。 前言&#xff1a; 先理解一个问题&#xff1a; Son.prototype Father.prototype; 这一操作相当于把Son的原型对象指向Father。 意味着Son的prototype的地址与Fa…

Vue基础学习 v-指令(2) 本地应用(记事本)

v-bind 设置元素的属性&#xff08;比如&#xff1a;src&#xff0c;title&#xff0c;class&#xff09; v-bind:属性名值 <div id"app"><img v-bind:src"imgSrc" alt"" v-bind:title"imgTitle"></div><scrip…

数学建模(一):LP 问题

文章目录数学建模&#xff08;一&#xff09;&#xff1a;LP 问题一、 MATLAB求解二、 Python 求解数学建模&#xff08;一&#xff09;&#xff1a;LP 问题 在人们的生产实践中&#xff0c;经常会遇到如何利用现有资源来安排生产&#xff0c;以取得最大经济效益的问题。此类问…

关于分布式事务的理解

关于分布式事务的理解 分布式事务之前先简单介绍下介于本地事务和分布式事务之间的两个事务&#xff1a;全局事务&#xff08;Global Transactions&#xff09;和共享事务&#xff08;Share Transactions&#xff09;的原理与实现。 先给全局事务做个限定&#xff1a;一种适用…

JVM运行时数据区划分

Java内存空间 内存是非常重要的系统资源&#xff0c;是硬盘和cpu的中间仓库及桥梁&#xff0c;承载着操作系统和应用程序的实时运行。JVM内存布局规定了JAVA在运行过程中内存申请、分配、管理的策略&#xff0c;保证了JVM的高效稳定运行。不同的jvm对于内存的划分方式和管理机…

使用secure crt连接ensp中虚拟设备

0 前言 ensp中虚拟设备如路由器、防火墙等本质上是 virtualbox中运行的虚机&#xff0c;因此可通过 telnet 连接 127.0.0.1 及对应端口方式连接到ensp中设备&#xff1b; 1 连接方法 1.1 查看设备所监听端口 设备图标上&#xff0c;右键 设置 点击 配置&#xff0c;可查看到…

UGUI 上使用 Particle System 支持 Sorting Layer 排序渲染

UGUI 上使用 Particle System 支持 Sorting Layer 排序渲染 Unity 中 Particle System 在 UGUI 上是可以根据 Sorting Layer 以及 Order in Layer 和 UI 组件(Image、Text等) 排序渲染的 Layer 值高的能够遮挡 Layer 值低的 组件 开发中会有这样的需求&#xff1a;要求 Part…

CAD异形图形的绘制

这个CAD图形的难点在于如何画角度98长165的斜线&#xff0c;剩下的图形就很好画了&#xff0c;那么用到的命令有圆、直线、导圆角、偏移等多个CAD命令的结合 目标对象 操作步骤 1.先使用直线命令画相交于A点的两条辅助线段&#xff0c;然后以A点为圆心画半径47.5和直径65的圆…

Java -数据结构,【优先级队列 / 堆】

一、二叉树的顺序存储 在前面我们已经讲了二叉树的链式存储&#xff0c;就是一棵树的左孩子和右孩子 而现在讲的是&#xff1a;顺序存储一棵二叉树。 1.1、存储方式 使用数组保存二叉树结构&#xff0c;方式即将二叉树用层序遍历方式放入数组中。 一般只适合表示完全二叉树&a…

真实需求和梦想实现满足

多少的时光和岁月中都不曾认真系统的深度思考自己的真实需求和欲望之间是否一致&#xff0c;随着时间的流逝才发现自己追求的是一场空&#xff0c;自己的真实需求并不是苦苦追求的东西&#xff0c;这也是当梦想照进现实&#xff01;欲望是无善无恶的&#xff0c;不必为了满足自…

性能测试——LoadRunner: virtual user generator的使用

LoadRunner 在安装时取消勾选指定LoadRunner代理将要使用的证书&#xff0c;安装完成后会显示下面三个软件 Vitual User Generator&#xff1a;生成性能测试脚本Controller&#xff1a;创建测试场景&#xff0c;运行测试脚本&#xff0c;监控运行&#xff0c;收集到运行的数…

Spring——AOP是什么?如何使用?

一、什么是AOP&#xff1f;在不修改源代码的情况下 增加功能二、底层是什么&#xff1f;动态代理aop是IOC的一个扩展功能&#xff0c;现有IOC&#xff0c;再有AOP&#xff0c;只是在IOC的整个流程中新增的一个扩展点而已&#xff1a;BeanPostProcessorbean的创建过程中有一个步…

【JAVA】List接口

&#x1f3c6;今日学习目标&#xff1a;List接口 &#x1f603;创作者&#xff1a;颜颜yan_ ✨个人主页&#xff1a;颜颜yan_的个人主页 ⏰本期期数&#xff1a;第四期 &#x1f389;专栏系列&#xff1a;JAVA List接口一、ArrayList二、LinkedList总结一、ArrayList ArrayLis…

python完美实现一个自己的音乐服务器

最近发现&#xff0c;经常用的网易云音乐&#xff0c;有很多歌曲下架了&#xff0c;能听的越来越少了&#xff1b;歌单里的一些歌曲&#xff0c;现在要开通 VIP 才能听了。其实自己常听的歌曲不是很多&#xff0c;现在却有很多听不了了。怎么办呢&#xff0c;付费吗&#xff1f…

Python进阶-----面对对象5.0(面对对象三大特征之--多态)

目录 前言&#xff1a; 多态 习题 前言&#xff1a; 上一期讲了Python面对对象中的继承&#xff0c;而今天讲的是多态&#xff0c;其实多态跟继承是紧密相关的&#xff0c;换句话说多态是继承的一种表现形式&#xff0c;下面就一起来看看吧&#xff01;&#xff08;上一期链…

性价比高的骨传导蓝牙耳机,推荐几款性能高的骨传导耳机

​骨传导耳机&#xff0c;顾名思义是一种声音传递方式&#xff0c;利用头骨作为震动传导发声。不像一般耳机那样通过外耳或内耳传递声音。声音由耳部传播到头后产生振动刺激颅脑内听觉中枢引起听觉。因此是一种非入耳式的声音传播方式。而在选购过程中&#xff0c;对于价格、功…

自动驾驶目标检测项目实战(二)—基于Faster-RCNN的交通标志检测

自动驾驶目标检测项目实战——基于Faster-RCNN的交通标志检测 目前目标检测算法有很多&#xff0c;流行的就有faster-rnn和yolov&#xff0c;本文使用了faster-rnn框架进行训练&#xff0c;效果还不错&#xff0c;准确率&#xff0c;当然也可以使用更高版本的Yolov进行实战。本…

RK3568触摸屏驱动调试总结

硬件电路分析 RK3568 CPU通过I2C与触控板外设wdt87xx连接。 首先要根据电路图获取如下I2C的信息&#xff1a; 项目Value接在哪个I2Ci2c1I2C 寄存器地址0x2cHID 地址0x20中断B5 1、接在哪个I2C 如图,1接在I2C1&#xff1a; 2、使用哪个GPIO引脚接收触控板的中断 如图&#xf…

Ubantu从0开始配置深度学习RTX 4090+3090显卡的服务器

文章目录1. 基础2. 用户访问3. Pytorch环境的问题4. 显卡调度问题方法一&#xff1a;在shell命令前强制指定显卡方法二&#xff1a;在代码中强制指定显卡5. 各种各样的小BUG5.1 Liunx创建新用户登录异常&#xff1a;/usr/bin/xauth: error/timeout in locking authority file /…

Unity之向量计算

文章目录前言向量加法向量减法向量乘法/除法向量点乘&#xff08;内积&#xff09;向量叉乘&#xff08;外积&#xff09;向量归一化向量小结前言 讲讲Unity中的向量有关知识&#xff0c;一些概念在初高中就学过&#xff0c;就不解释了。向量只能与自己相同维度进行计算&#…