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

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(短信验证服务和登录的前端定义实现)。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【面试】Java集合面试题

文章目录集合容器概述什么是集合集合的特点集合和数组的区别使用集合框架的好处常用的集合类有哪些&#xff1f;List&#xff0c;Set&#xff0c;Map三者的区别&#xff1f;集合框架底层数据结构哪些集合类是线程安全的&#xff1f;Java集合的快速失败机制 “fail-fast”&#…

css 样式开发中遇到的问题

1.文本换行 汉字和英文数字字符适配 word-break: break-all;word-wrap: break-word;text-align: left; 2.文本换行以及出现省略号 word-break: break-word;overflow: hidden;text-overflow: ellipsis; // ...展示display: -webkit-box; // 弹性伸缩盒盒子模型显示-webkit-line…

面试常问的Linux之 I/O 复用

I/O 复用 一、I/O的概念 在Linux系统中&#xff0c;I/O&#xff08;输入/输出&#xff09;指的是计算机系统的数据交换过程&#xff0c;包括从外部设备读取数据&#xff08;输入&#xff09;和将数据发送到外部设备&#xff08;输出&#xff09;。I/O操作是Linux系统中非常重要…

人工智能从来不是一帆风顺的

不久之前&#xff0c;人们还常说&#xff0c;计算机视觉的辨别能力尚不如一岁大的孩子。如今看来&#xff0c;这句话要改写了。 ----- 特伦斯谢诺夫斯基 目录 人工智能初现端倪 人工智能初现 人工智能“第一次危机”——“设计派”行不通 第一次危机破局——学习派初见成效…

Python-np.expand_dims()

1. np.expand_dims 用于扩展数组的维度 执行程序后注意观察中括号[ ]的位置和数量 np.expand_dims(a, axis0)表示在axis0维度处扩展维度&#xff0c;加一层中括号[ ]; np.expand_dims(a, axis1)表示在axis1维度处扩展维度&#xff0c;加一层中括号[ ]; np.expand_dims(a, …

Golang每日一练(leetDay0025)

目录 73. 矩阵置零 Set Matrix Zeroes &#x1f31f;&#x1f31f; 74. 搜索二维矩阵 Search A 2d-Matrix &#x1f31f;&#x1f31f; 75. 颜色分类 Sort Colors &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Pyth…

大数据领域的发展及其对现实世界的价值

大数据已经成为全球各行业领域不可或缺的一部分&#xff0c;并且其应用不断涌现。尽管很多人最初对“大数据”这一术语表示怀疑和不信任&#xff0c;但大数据技术已经确立了稳定的发展方向。根据调研机构的预测&#xff0c;到2027年&#xff0c;全球大数据市场规模将达到1090亿…

PostgreSQL之Full VACUUM

前面我们介绍了PG中的Concurrent VACUUM&#xff0c;详细请参考PostgreSQL之Concurrent VACUUM&#xff0c;这篇我们继续来了解一下PG中的Full VACUUM。 我们了解Concurrent VACUUM允许在执行的时候仍然允许对正在VACUUM的表进行读取操作&#xff0c;因此这个操作对业务的影响也…

学成在线:第五天(p82-p93)

1、面试&#xff1a;在分片广播中&#xff0c;如何保证多个执行器不会重复执行任务&#xff1f; &#xff08;虽然有分片序号&#xff0c;但是加入只有两个执行器&#xff0c;有很多任务&#xff0c;这两个执行器得到的分片序号也就只是两个数字&#xff0c;后面的分片是如何能…

蓝桥杯刷题冲刺 | 倒计时11天

作者&#xff1a;指针不指南吗 专栏&#xff1a;蓝桥杯倒计时冲刺 &#x1f43e;马上就要蓝桥杯了&#xff0c;最后的这几天尤为重要&#xff0c;不可懈怠哦&#x1f43e; 文章目录1.质因子2.蓝桥王国1.质因子 题目 链接&#xff1a; 1545. 质因子 - AcWing题库 给定一个整数 N…

NexNoSQL Client:Elasticsearch、Redis、MongoDB三合一的可视化客户端管理工具

背景&#xff1a; 工作中我们使用了Elasticsearch作为存储&#xff0c;来支持内容的搜索&#xff0c;Elasticsearch这个软件大家都耳熟能详&#xff0c;它是一个分布式、高扩展、高实时的搜索与数据分析引擎&#xff0c;不仅仅支持文本索引&#xff0c;还支持聚合操作&#xf…

Java面向对象部分 个人学习记录

注:此博客是个人学习记录&#xff0c;会有错的地方&#xff0c;面向对象部分我可能会画很多图来加深我的理解 不引出了&#xff0c;直接开始 class Dog{String name;int age;String type;public Dog(String name,int age,String type){this.namename;this.ageage;this.typetyp…

全志V3S嵌入式驱动开发(准备)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 要学好嵌入式&#xff0c;其实最好自己可以画板子、调试板子、写软件、调试软件这样来学习。简单的51单片机、stm32这样的mcu或许画起来不是很复杂…

Python 自动化指南(繁琐工作自动化)第二版:零、前言

关于作者 Al Sweigart 是一名软件开发人员和技术书籍作者。Python 是他最喜欢的编程语言&#xff0c;他是该语言的几个开源模块的开发者。他的其他书籍可以在他的网站上根据知识共享许可免费获得。他的猫现在重 11 磅。 关于技术评审 Philip James 从事 Python 工作已经超过…

MobTech 秒验|本机号码一键登录会泄露隐私吗

本机号码一键登录是一种新型的应用登录方式&#xff0c;它可以利用运营商的数据网关认证能力&#xff0c;实现手机号免密登录&#xff0c;提高用户体验和转化率&#xff0c;降低验证成本和流失率。本机号码一键登录支持三大运营商号码认证&#xff0c;3秒内完成手机号验证&…

Java小课堂:自定义注解(案例:自定义DecimalFormat注解)

文章目录 引言I 预备知识1.1 元注解1.2 Target注解的ElementType枚举1.3 Retention注解的RetentionPolicy枚举II 自定义注解2.1 基本条件2.2 注解自定义属性的格式III 案例3.1 自定义DecimalFormat注解3.2 自定义json序列化解析引言 需求: 编辑费率限制的值时填写几位就保存几…

如何在前端中实现精美的图片和文字的垂直对齐

&#x1f31f;所属专栏&#xff1a;前端只因变凤凰之路 &#x1f414;作者简介&#xff1a;rchjr——五带信管菜只因一枚 &#x1f62e;前言&#xff1a;该系列将持续更新前端的相关学习笔记&#xff0c;欢迎和我一样的小白订阅&#xff0c;一起学习共同进步~&#x1f449;文章…

关于线性与条带化下LVM增加磁盘数据分布的讨论

关于线性与条带化下LVM增加磁盘数据分布的讨论一、环境介绍二、线性模式逻辑卷创建逻辑卷删除三、条带化逻辑卷创建逻辑卷删除LVM有两种模式&#xff1a;线性模式&#xff1a;先写满组成线性逻辑卷的第一个物理卷&#xff0c;再向第2个物理卷中写入数据&#xff0c;以此类推&am…

必看>>>>Linux数据库被其他服务器远程访问(修改权限、开设端口)

目录 一&#xff1a;修改权限 1.1 进入Linux数据库 1.2 修改数据库的远程连接权限 1.2.1 数据库远程权限修改命令 1.2.2 数据库远程权限查看命名 1.3 给Linux机添加端口 1.4 远程数据库连接 注意mysql中的中英文输入 一&#xff1a;修改权限 1.1 进入Linux数据库 文章…

【职场热点】软件测试岗位,真正达到月收入1万以上的有多少

在某一线城市相亲角&#xff0c;有位阿姨自称孩子是程序员、36岁、月入3万8&#xff0c;并直言“月入1万如讨饭”&#xff0c;引来大量互联网人自嘲式认领“乞丐”身份。今年2月&#xff0c;“月收入一万”的鄙视链压力给到了二线城市&#xff0c;有位入行2年的软件测试员发帖称…