4. User module (8081)
4.1 construction environment
4.1.1 back end web service: changgou4 service web
- Modify POM XML document
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>changgou4-parent-ali</artifactId> <groupId>com.czxy.changgou</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>changgou4_service_web</artifactId> <dependencies> <!--Custom item--> <dependency> <groupId>com.czxy.changgou</groupId> <artifactId>changgou4_common_db</artifactId> </dependency> <dependency> <groupId>com.czxy.changgou</groupId> <artifactId>changgou4_pojo</artifactId> </dependency> <!--web Start dependence--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- nacos client --> <dependency> <groupId>com.alibaba.nacos</groupId> <artifactId>nacos-client</artifactId> </dependency> <!-- nacos Service discovery --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--redis--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </dependency> <!--swagger2--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> </dependency> </dependencies> </project>
- Create application YML document
#Port number server: port: 8081 spring: application: name: web-service #service name datasource: driverClassName: com.mysql.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/changgou_db?useUnicode=true&characterEncoding=utf8 username: root password: 1234 druid: #druid connection pool configuration initial-size: 1 #Initialize connection pool size min-idle: 1 #Minimum number of connections max-active: 20 #maximum connection test-on-borrow: true #Verification when obtaining connections will affect performance redis: database: 0 host: 127.0.0.1 port: 6379 cloud: nacos: discovery: server-addr: 127.0.0.1:8848 #nacos service address sentinel: transport: dashboard: 127.0.0.1:8080
- Create startup class
package com.czxy.changgou4; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; /** * @author Uncle Tong * @email liangtong@itcast.cn */ @SpringBootApplication @EnableDiscoveryClient public class Web-serviceApplication { public static void main(String[] args) { SpringApplication.run( Web-serviceApplication.class , args ); } }
4.1.2 create JavaBean at the back end: User
- Add a User object to the changgou4 POJO project
package com.czxy.changgou4.pojo; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; import java.beans.Transient; import java.util.Date; /** JavaBean corresponding to database * Created by liangtong. */ @TableName("tb_user") @Data @NoArgsConstructor @AllArgsConstructor public class User { /* CREATE TABLE `tb_user` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `created_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL, `email` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Email', `mobile` varchar(20) COLLATE utf8_unicode_ci NOT NULL COMMENT 'Mobile phone number ', `username` varchar(255) COLLATE utf8_unicode_ci NOT NULL COMMENT 'Nickname ', `password` char(60) COLLATE utf8_unicode_ci NOT NULL COMMENT 'Password ', `face` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Avatar ', `expriece` int(10) unsigned DEFAULT '0' COMMENT 'Experience value ', PRIMARY KEY (`id`), UNIQUE KEY `users_mobile_unique` (`mobile`), UNIQUE KEY `users_name_unique` (`name`), UNIQUE KEY `users_email_unique` (`email`) ) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci */ @TableId(value="id",type = IdType.AUTO) private Long id; @TableField(value="username") private String username; @TableField(value="password") private String password; @TableField(value="face") private String face; @TableField(value="expriece") private Integer expriece; @TableField(value="email") private String email; @TableField(value="mobile") private String mobile; @TableField(value="created_at") private Date createdAt; @TableField(value="updated_at") private Date updatedAt; @TableField(exist = false) private String code; @TableField(exist = false) private String password_confirm; }
4.1.3 front end page: create common components
- 1) Delete all contents in the components directory and create three new components
- 2) Create topnav Vue component for configuring top navigation
<template> <!-- Top navigation start --> <div class="topnav"> <div class="topnav_bd w990 bc"> <div class="topnav_left"> </div> <div class="topnav_right fr"> <ul> <li>Hello, welcome to Changgou![<a href="login.html">Sign in</a>] [<a href="register.html">Free registration</a>] </li> <li class="line">|</li> <li>My order</li> <li class="line">|</li> <li>customer service</li> </ul> </div> </div> </div> <!-- Top navigation end --> </template> <script> export default { } </script> <style> </style>
- 3) Create headerlogo Vue component, used to configure "page header, only LOGO"
<template> <!-- Header page start --> <div class="header w990 bc mt15"> <div class="logo w990"> <h2 class="fl"><a href="index.html"><img src="/images/logo.png" alt="Changgou mall"></a></h2> </div> </div> <!-- Page header end --> </template> <script> export default { } </script> <style> </style>
- 4) Create footer Vue component, used to configure "bottom copyright"
<template> <!-- Bottom copyright start --> <div class="footer w1210 bc mt15"> <p class="links"> <a href="">About us</a> | <a href="">contact us</a> | <a href="">Talent recruitment</a> | <a href="">Merchant settlement</a> | <a href="">Chihiro network</a> | <a href="">Luxury net</a> | <a href="">Advertising services</a> | <a href="">mobile terminal </a> | <a href="">Links</a> | <a href="">Sales alliance</a> | <a href="">Changgou Forum</a> </p> <p class="copyright"> © 2006-2020 All rights reserved. ICP Record Certificate No:Beijing ICP Certificate No. 070359 </p> <p class="auth"> <a href=""><img src="/images/xin.png" alt="" /></a> <a href=""><img src="/images/kexin.jpg" alt="" /></a> <a href=""><img src="/images/police.jpg" alt="" /></a> <a href=""><img src="/images/beian.gif" alt="" /></a> </p> </div> <!-- Bottom copyright end --> </template> <script> export default { } </script> <style> </style>
4.2 user registration: user name occupation
4.2.1 interface
http://localhost:10010/web-service/user/checkusername
4.2.2 back end
- Create interfaces or classes required by layer 3
- Step 1: create UserMapper and write findByUsername() to complete "query user by user name"
package com.czxy.changgou4.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.czxy.changgou4.pojo.User; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; /** * Created by liangtong. */ @org.apache.ibatis.annotations.Mapper public interface UserMapper extends BaseMapper<User> { /** * Query by user name * @param username * @return */ @Select("select * from tb_user where username = #{username}") User findByUsername(@Param("username") String username); }
- Step 2: create UserService interface and query function
package com.czxy.changgou4.service; import com.baomidou.mybatisplus.extension.service.IService; import com.czxy.changgou4.pojo.User; /** * @author Uncle Tong * @email liangtong@itcast.cn */ public interface UserService extends IService<User> { /** * Query by user name * @param username * @return */ public User findByUsername(String username); }
- Step 3: create UserServiceImpl implementation class and query function
package com.czxy.changgou4.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.czxy.changgou4.mapper.UserMapper; import com.czxy.changgou4.pojo.User; import com.czxy.changgou4.service.UserService; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; /** * @author Uncle Tong * @email liangtong@itcast.cn */ @Service @Transactional public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService { @Override public User findByUsername(String username) { return baseMapper.findByUsername(username); } }
- Step 4: create UserController and complete user name check
package com.czxy.changgou4.controller; import com.czxy.changgou4.pojo.User; import com.czxy.changgou4.service.UserService; import com.czxy.changgou4.vo.BaseResult; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; /** * Created by liangtong. */ @RestController @RequestMapping("/user") public class UserController { @Resource private UserService userService; @PostMapping("/checkusername") public BaseResult checkUsername(@RequestBody User user){ //Query user User findUser = userService.findByUsername( user.getUsername() ); //judge if(findUser != null){ return BaseResult.error("User name already exists"); } else { return BaseResult.ok("User name available"); } } }
4.2.3 front end
- Step 1: create register vue
- Step 2: add common components
<template> <div> <TopNav></TopNav> <div style="clear:both;"></div> <HeaderLogo></HeaderLogo> <div style="clear:both;"></div> <!-- text --> <div style="clear:both;"></div> <Footer></Footer> </div> </template> <script> import TopNav from '../components/TopNav' import HeaderLogo from '../components/HeaderLogo' import Footer from '../components/Footer' export default { head: { title: 'User registration' }, components : { TopNav, HeaderLogo, Footer } } </script> <style> </style>
- Step 3: write the registration form and import the unique style
<template> <div> <TopNav></TopNav> <div style="clear:both;"></div> <HeaderLogo></HeaderLogo> <div style="clear:both;"></div> <!-- text --> <!-- Login main part start --> <div class="login w990 bc mt10 regist"> <div class="login_hd"> <h2>User registration</h2> <b></b> </div> <div class="login_bd"> <div class="login_form fl"> <form action="" method="post"> <ul> <li> <label for="">user name:</label> <input type="text" class="txt" name="username" /> <p>3-20 Bit character, which can be composed of Chinese, letters, numbers and underscores</p> <p class="error">User name already exists</p> </li> <li> <label for="">password:</label> <input type="password" class="txt" name="password" /> <p>6-20 Bit character, the combination of letters, numbers and symbols can be used, and pure numbers, pure letters and pure symbols are not recommended</p> </li> <li> <label for="">Confirm password:</label> <input type="password" class="txt" name="password" /> <p>Please enter the password again</p> </li> <li> <label for="">phone number:</label> <input type="text" class="txt" name="mobile" /> <p>Please enter your mobile phone number</p> </li> <li class="checkcode"> <label for="">Verification Code:</label> <input type="text" name="checkcode" /> <button > Send verification code<span>5 second</span> </button> </li> <li> <label for=""> </label> <input type="checkbox" class="chb" checked="checked" /> I have read and agreed to the user registration agreement </li> <li> <label for=""> </label> <input type="submit" value="" class="login_btn" /> </li> </ul> </form> </div> <div class="mobile fl"> <h3>Mobile quick registration</h3> <p>Chinese mainland mobile phone users edit SMS.<strong>XX</strong>"Send to:</p> <p><strong>1069099988</strong></p> </div> </div> </div> <!-- Login main part end --> <div style="clear:both;"></div> <Footer></Footer> </div> </template> <script> import TopNav from '../components/TopNav' import HeaderLogo from '../components/HeaderLogo' import Footer from '../components/Footer' export default { head: { title: 'User registration', link: [ {rel:'stylesheet',href:'style/login.css'} ], script: [ { type: 'text/javascript', src: 'js/header.js' }, { type: 'text/javascript', src: 'js/index.js' }, ] }, components : { TopNav, HeaderLogo, Footer } } </script> <style> </style>
- Step 4: modify the API JS, write an ajax function to check the user name
const request = { test : ()=> { return axios.get('/test') }, //Check user name checkUsername : ( username )=> { return axios.post('/web-service/user/checkusername', { username }) } }
- Step 5: modify register Vue page, complete the check function
- Send ajax to check whether the user name is available
- If available, the corresponding information is displayed and displayed in the success style
- If not available, the corresponding information is displayed and prompted with the error style
<template> <div> <TopNav></TopNav> <div style="clear:both;"></div> <HeaderLogo></HeaderLogo> <div style="clear:both;"></div> <!-- text --> <!-- Login main part start --> <div class="login w990 bc mt10 regist"> <div class="login_hd"> <h2>User registration</h2> <b></b> </div> <div class="login_bd"> <div class="login_form fl"> <form action="" method="post"> <ul> <li> <label for="">user name:</label> <input type="text" class="txt" name="username" v-model="user.username" @blur="checkUsernameFn" /> <p>3-20 Bit character, which can be composed of Chinese, letters, numbers and underscores</p> <p :class="userMsg.usernameData.code == 1 ? 'success' : 'error'">{{userMsg.usernameData.message}} </p> </li> <li> <label for="">password:</label> <input type="password" class="txt" name="password" /> <p>6-20 Bit character, the combination of letters, numbers and symbols can be used, and pure numbers, pure letters and pure symbols are not recommended</p> </li> <li> <label for="">Confirm password:</label> <input type="password" class="txt" name="password" /> <p>Please enter the password again</p> </li> <li> <label for="">phone number:</label> <input type="text" class="txt" name="mobile" /> <p>Please enter your mobile phone number</p> </li> <li class="checkcode"> <label for="">Verification Code:</label> <input type="text" name="checkcode" /> <button > Send verification code<span>5 second</span> </button> </li> <li> <label for=""> </label> <input type="checkbox" class="chb" checked="checked" /> I have read and agreed to the user registration agreement </li> <li> <label for=""> </label> <input type="submit" value="" class="login_btn" /> </li> </ul> </form> </div> <div class="mobile fl"> <h3>Mobile quick registration</h3> <p>Chinese mainland mobile phone users edit SMS.<strong>XX</strong>"Send to:</p> <p><strong>1069099988</strong></p> </div> </div> </div> <!-- Login main part end --> <div style="clear:both;"></div> <Footer></Footer> </div> </template> <script> import TopNav from '../components/TopNav' import HeaderLogo from '../components/HeaderLogo' import Footer from '../components/Footer' export default { head: { title: 'User registration', link: [ {rel:'stylesheet',href:'style/login.css'} ], script: [ { type: 'text/javascript', src: 'js/header.js' }, { type: 'text/javascript', src: 'js/index.js' }, ] }, components : { TopNav, HeaderLogo, Footer }, data() { return { user : { //Form binding object username : "" }, userMsg : { //error message usernameData : "" } } }, methods: { async checkUsernameFn() { let {data} = await this.$request.checkUsername( this.user.username ) this.userMsg.usernameData = data } }, } </script> <style> </style>
4.3 user registration: mobile phone number check
4.3.1 interface
http://localhost:10010/web-service/user/checkmobile
4.3.2 back end
- Step 1: modify UserService and add findByMobile() method to query the phone number
/** * Query by mobile phone number * @param mobile * @return */ User findByMobile(String mobile);
- Step 2: write UserServiceImpl and implement findByMobile() method
@Override public User findByMobile(String mobile) { // Patchwork condition QueryWrapper queryWrapper = new QueryWrapper(); queryWrapper.eq("mobile", mobile); // Query one List<User> list = baseMapper.selectList(queryWrapper); if(list.size() == 1) { return list.get(0); } return null; }
- Step 3: modify UserController and add checkMobile() method
/** * Query by mobile phone number * @param user * @return */ @PostMapping("/checkmobile") public BaseResult checkMobile(@RequestBody User user){ //Query user User findUser = userService.findByMobile( user.getMobile() ); //judge if(findUser != null){ return BaseResult.error("Phone number already registered"); } else { return BaseResult.ok("Phone number available"); } }
4.3.3 front end
- Step 1: modify the API JS, add checkMobile() function
const request = { test : ()=> { return axios.get('/test') }, //Check user name checkUsername : ( username )=> { return axios.post('/web-service/user/checkusername', { username }) }, //Check phone number checkMobile : ( mobile )=> { return axios.post('/web-service/user/checkmobile', { mobile }) } }
- Step 2: modify register Vue, add checkMobileFn() to check the phone number
methods: { async checkUsernameFn() { //Check user name let {data} = await this.$request.checkUsername( this.user.username ) this.userMsg.usernameData = data }, async checkMobileFn() { //Check the phone let {data} = await this.$request.checkMobile( this.user.mobile ) this.userMsg.mobileData = data } },
- Step 3: write 2 variables required
data() { return { user : { //Form encapsulation data username : "", mobile : "" }, userMsg : { //Error prompt data usernameData : "", mobileData : "" } } },
- Step 4: process the page
<li> <label for="">phone number:</label> <input type="text" class="txt" name="mobile" v-model="user.mobile" @blur="checkMobileFn" /> <p>Please enter your mobile phone number</p> <p :class="userMsg.mobileData.code == 1 ? 'success' : 'error'">{{userMsg.mobileData.message}} </p> </li>
- Full version
<template> <div> <TopNav></TopNav> <div style="clear:both;"></div> <HeaderLogo></HeaderLogo> <div style="clear:both;"></div> <!-- text --> <!-- Login main part start --> <div class="login w990 bc mt10 regist"> <div class="login_hd"> <h2>User registration</h2> <b></b> </div> <div class="login_bd"> <div class="login_form fl"> <form action="" method="post"> <ul> <li> <label for="">user name:</label> <input type="text" class="txt" name="username" v-model="user.username" @blur="checkUsernameFn" /> <p>3-20 Bit character, which can be composed of Chinese, letters, numbers and underscores</p> <p :class="userMsg.usernameData.code == 1 ? 'success' : 'error'">{{userMsg.usernameData.message}} </p> </li> <li> <label for="">password:</label> <input type="password" class="txt" name="password" /> <p>6-20 Bit character, the combination of letters, numbers and symbols can be used, and pure numbers, pure letters and pure symbols are not recommended</p> </li> <li> <label for="">Confirm password:</label> <input type="password" class="txt" name="password" /> <p>Please enter the password again</p> </li> <li> <label for="">phone number:</label> <input type="text" class="txt" name="mobile" v-model="user.mobile" @blur="checkMobileFn" /> <p>Please enter your mobile phone number</p> <p :class="userMsg.mobileData.code == 1 ? 'success' : 'error'">{{userMsg.mobileData.message}} </p> </li> <li class="checkcode"> <label for="">Verification Code:</label> <input type="text" name="checkcode" /> <button > Send verification code<span>5 second</span> </button> </li> <li> <label for=""> </label> <input type="checkbox" class="chb" checked="checked" /> I have read and agreed to the user registration agreement </li> <li> <label for=""> </label> <input type="submit" value="" class="login_btn" /> </li> </ul> </form> </div> <div class="mobile fl"> <h3>Mobile quick registration</h3> <p>Chinese mainland mobile phone users edit SMS.<strong>XX</strong>"Send to:</p> <p><strong>1069099988</strong></p> </div> </div> </div> <!-- Login main part end --> <div style="clear:both;"></div> <Footer></Footer> </div> </template> <script> import TopNav from '../components/TopNav' import HeaderLogo from '../components/HeaderLogo' import Footer from '../components/Footer' export default { head: { title: 'User registration', link: [ {rel:'stylesheet',href:'style/login.css'} ], script: [ { type: 'text/javascript', src: 'js/header.js' }, { type: 'text/javascript', src: 'js/index.js' }, ] }, components : { TopNav, HeaderLogo, Footer }, data() { return { user : { //Form encapsulation data username : "", mobile : "", password : "", code : "" }, userMsg : { //Error prompt data usernameData : "", mobileData : "" } } }, methods: { async checkUsernameFn() { //Check user name let {data} = await this.$request.checkUsername( this.user.username ) this.userMsg.usernameData = data }, async checkMobileFn() { //Check the phone let {data} = await this.$request.checkMobile( this.user.mobile ) this.userMsg.mobileData = data } }, } </script> <style> </style>
4.4 user registration: front-end technology – Redis
4.5 user registration: advanced technology - Alibaba big fish
4.6 user registration: SMS verification code
- 4.6.1 analysis
4.6.2 interface
http://localhost:10010/web-service/sms
4.6.3 back end
- Create SmsController class, call Alibaba big fish tool class and send SMS.
package com.czxy.changgou4.controller; import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse; import com.czxy.changgou4.pojo.User; import com.czxy.changgou4.utils.SmsUtil; import com.czxy.changgou4.vo.BaseResult; import org.apache.commons.lang.RandomStringUtils; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.util.concurrent.TimeUnit; /** * Created by liangtong. */ @RestController @RequestMapping("/sms") public class SmsController { @Resource private StringRedisTemplate redisTemplate; @PostMapping public BaseResult sendSms(@RequestBody User user){ long start = System.currentTimeMillis(); try { //Send SMS //1 production verification code String code = RandomStringUtils.randomNumeric(4); System.out.println("Verification Code:" + code); //2 and store it in reids, key: "sms_register" + mobile phone number, value: verification code, 1 hour redisTemplate.opsForValue().set( "sms_register" + user.getMobile() , code , 1 , TimeUnit.HOURS); /**/ //3 Send SMS SendSmsResponse smsResponse = SmsUtil.sendSms(user.getMobile(), user.getUsername() , code, "", ""); //https://help.aliyun.com/document_detail/55284.html?spm=5176.doc55322.6.557.KvvIJx if("OK".equalsIgnoreCase(smsResponse.getCode())){ return BaseResult.ok("Sending succeeded "); } else { return BaseResult.error(smsResponse.getMessage()); } /* //Analog data System.out.println("Verification Code: "+ code"; return BaseResult.ok("Sending succeeded "); */ } catch (Exception e) { long end = System.currentTimeMillis(); System.out.println( end - start); return BaseResult.error("fail in send" ); } } }
4.6.4 front end
- Step 1: modify apiclient JS, send SMS ajax operation
//send message sendSms : ( user )=> { return axios.post('/web-service/sms', user ) }
- Step 2: modify register Vue page, bind the click event sendSmsFn to "send verification code"
<button @click.prevent="sendSmsFn" > Send verification code<span>5 second</span> </button>
- Step 3: modify register Vue page, write sendSmsFn function, it is recommended to use ajax... then()... catch to handle exceptions
sendSmsFn () { this.$request.sendSms( this.user ) .then(( response )=>{ //Prompt message for sending SMS this.userMsg.smsData = response.data }) .catch(( error )=>{ //Error message alert( error.message ) }) }
- Step 4: modify register Vue page, providing variable smsData
userMsg : { //Error prompt data usernameData : "", mobileData : "", smsData : "" }
- Step 5: modify register Vue page, displaying smsData prompt information
<p :class="userMsg.smsData.code == 1 ? 'success' : 'error'">{{userMsg.smsData.message}} </p>
4.6.5 countdown
- Step 1: provide 3 variables to control the countdown
btnDisabled : false, //Countdown control variable seconds : 5, //Default countdown seconds timer : null, //Receive timer, clear timer
- Step 2: control the display of countdown on the label
<button :disabled="btnDisabled" @click.prevent="sendSmsFn" > Send verification code<span v-show="btnDisabled">{{seconds}}second</span> </button>
- Step 3: after sending a short message, turn on the countdown control
sendSmsFn () { this.$request.sendSms( this.user ) .then(( response )=>{ //Prompt message for sending SMS this.userMsg.smsData = response.data //Button not available this.btnDisabled = true; //count down this.timer = setInterval( ()=>{ if(this.seconds <= 1){ //end // Reset seconds this.seconds = 5; // Button available this.btnDisabled = false; // Stop Timer clearInterval(this.timer); } else { this.seconds --; } } , 1000); }) .catch(( error )=>{ //Error message alert( error.message ) }) }
4.7 user registration
4.7.1 interface
http://localhost:10010/web-service/user/register
4.7.2 back end
*The server needs to verify again before saving
-
Is the user name registered
-
Whether the mobile phone number is registered
-
Whether the verification code is invalid
-
Whether the verification code is wrong
-
The password needs to be encrypted with BCrypt
-
Step 1: modify UserService interface and add register method
/** * User registration * @param user * @return */ public boolean register(User user) ;
- Step 2: improve UserServiceImpl implementation class
@Override public boolean register(User user) { //Password encryption String newPassword = BCrypt.hashpw(user.getPassword()); user.setPassword(newPassword); //Processing data user.setCreatedAt(new Date()); user.setUpdatedAt(user.getCreatedAt()); int insert = baseMapper.insert(user); return insert == 1; }
- Step 3: modify UserController and add register method
/** * User registration * @param user * @return */ @PostMapping("/register") public BaseResult register(@RequestBody User user){ //Server verification User findUser = userService.findByUsername(user.getUsername()); if(findUser != null) { return BaseResult.error("User name already exists"); } findUser = userService.findByMobile(user.getMobile()); if(findUser != null) { return BaseResult.error("Phone number already exists"); } //Verification Code String code = stringRedisTemplate.opsForValue().get("sms_register" + user.getMobile()); //Delete the verification code in redis stringRedisTemplate.delete("sms_register" + user.getMobile()); if(code == null) { return BaseResult.error("Verification code failure"); } if(!code.equals(user.getCode())) { return BaseResult.error("Incorrect verification code"); } //register boolean register = userService.register(user); if(register) { return BaseResult.ok("login was successful"); } return BaseResult.error("login has failed"); }
4.7.3 date processing (optional)
- Write DateMetaObjectHandler to handle creation time and modification date
package com.czxy.changgou4.handler; import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import org.apache.ibatis.reflection.MetaObject; import org.springframework.stereotype.Component; import java.util.Date; /** * @author Uncle Tong * @email liangtong@itcast.cn */ @Component public class DateMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { this.setFieldValByName("createdAt", new Date(), metaObject); this.setFieldValByName("updatedAt", new Date(), metaObject); } @Override public void updateFill(MetaObject metaObject) { this.setFieldValByName("updatedAt", new Date(), metaObject); } }
- Improve the User JavaBean and set the filling method
@TableField(value="created_at",fill = FieldFill.INSERT) private Date createdAt; @TableField(value="updated_at",fill = FieldFill.INSERT_UPDATE) private Date updatedAt;
4.7.4 front end
- Step 1: modify the API JS, add registration function
//register register : ( user )=> { return axios.post('/web-service/user/register', user ) }
- Step 2: process the form, input the verification code, bind the data, and submit the button binding event
<li class="checkcode"> <label for="">Verification Code:</label> <input type="text" name="checkcode" v-model="user.code" /> <button :disabled="btnDisabled" @click.prevent="sendSmsFn" > Send verification code<span v-show="btnDisabled">{{seconds}}second</span> </button> <p :class="userMsg.smsData.code == 1 ? 'success' : 'error'">{{userMsg.smsData.message}} </p> </li> <li> <label for=""> </label> <input type="checkbox" class="chb" checked="checked" /> I have read and agreed to the user registration agreement </li> <li> <label for=""> </label> <input type="submit" value="" @click.prevent="registerFn" class="login_btn" /> </li>
- Step 3: improve the user data in the data area
user : { //Form encapsulation data username : "", //user name mobile : "13699282444", //cell-phone number password : "", //password code : "" //Verification Code },
- Step 4: write the registerFn function
async registerFn() { let { data } = await this.$request.register( this.user ) if( data.code == 20000) { //success this.$router.push('/login') } else { //Failure -- use a location to display the error message with the sending verification code this.userMsg.smsData = data } }