Changgou e-commerce project-02-user registration-2021-06-11

Posted by sayma on Sun, 30 Jan 2022 12:27:40 +0100

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="">&nbsp;</label>
              <input type="checkbox" class="chb" checked="checked" /> I have read and agreed to the user registration agreement
            </li>
            <li>
              <label for="">&nbsp;</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="">&nbsp;</label>
              <input type="checkbox" class="chb" checked="checked" /> I have read and agreed to the user registration agreement
            </li>
            <li>
              <label for="">&nbsp;</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="">&nbsp;</label>
              <input type="checkbox" class="chb" checked="checked" /> I have read and agreed to the user registration agreement
            </li>
            <li>
              <label for="">&nbsp;</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="">&nbsp;</label>
              <input type="checkbox" class="chb" checked="checked" /> I have read and agreed to the user registration agreement
            </li>
            <li>
              <label for="">&nbsp;</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
      }
    }

Topics: Java Vue.js