- <template>
- <div>
- login
- </div>
-
- </template>
-
- <script>
- export default {
- name: 'HomeView',
- data() {
- return {
-
- }
- },
- methods: {
- },
- }
- </script>
- <template>
- <div>
- register
- </div>
-
- </template>
-
- <script>
- export default {
- name: 'Register',
- data() {
- return {}
- },
- methods: {},
- }
- </script>
在router/index.js文件中注册 登录和注册的vue组件路由
- import Vue from 'vue'
- import VueRouter from 'vue-router'
- import HomeView from '../views/HomeView.vue'
- import Login from '../views/Login.vue'
- import Register from '../views/Register.vue'
-
- Vue.use(VueRouter)
-
- const routes = [
- {
- path: '/',
- name: 'Login',
- component: Login
- },
- {
- path: '/register',
- name: 'Register',
- component: Register
- },
- {
- path: '/home',
- name: 'home',
- component: HomeView
- },
- {
- path: '/about',
- name: 'about',
- // route level code-splitting
- // this generates a separate chunk (about.[hash].js) for this route
- // which is lazy-loaded when the route is visited.
- component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
- }
- ]
-
- const router = new VueRouter({
- routes
- })
-
- export default router
- <template>
- <body id="poster">
- <el-form class="login-container" label-position="left" label-width="0px">
- <h2 class="login_title">
- 系统登录
- </h2>
- <el-form-item label="">
- <el-input type="text" v-model="loginFrom.loginName" placeholder="账号"></el-input>
- </el-form-item>
-
- <el-form-item label="">
- <el-input type="password" v-model="loginFrom.password" placeholder="密码"></el-input>
- </el-form-item>
-
- <el-form-item>
- <el-button type="primary" style="width: 100%;background:#505458;border:none" @click="login">登录</el-button>
- 没有账号?<el-button @click="toRegister" style="margin-top: 5px">点我注册</el-button>
- </el-form-item>
- </el-form>
- </body>
-
- </template>
-
- <script>
- export default {
- name: 'HomeView',
- data() {
- return {
- loginFrom: {
- name: '',
- loginName:'',
- password:''
- }
- }
- },
- methods: {
- login() {
- console.log('submit!',this.loginFrom);
- this.axios.post('http://localhost:3333/user/login',this.loginFrom).then((resp)=>{
- let data = resp.data;
- if(data.success){
- this.loginFrom = {},
- this.$message({
- message: '登录成功',
- type: 'success'
- });
- this.$router.push({
- path:'/home'
- })
- }
- })
- this.$router.push({
- path:'/home'
- })
- },
- toRegister(){
- //Vue跳转
- this.$router.push({
- path:'/register'
- })
- }
- },
- }
- </script>
-
- <style>
-
- #poster{
- background-position: center;
- height: 100%;
- width: 100%;
- background-size: cover;
- position: fixed;
- }
- body{
- margin: 0px;
- padding: 0px;
- }
- .login-container{
- border-radius: 15px;
- background-clip: padding-box;
- margin:150px auto;
- padding: 35px 35px 15px 35px;
- width: 600px;
- height: 290px;
- background:#fff;
- border:1px solid #eaeaea;
- box-shadow:0 0 1000px #cac6c6;
- }
- .login_title{
- margin:0px auto 30px auto;
- text-align: center;
- color:#505458
- }
-
- </style>
- <template>
-
- <div id="poster">
- <el-form :model="ruleForm" ref="ruleForm" :rules="rules" label-width="100px" class="register-container">
- <h2 class="register_title" style="display:inline;">
- 系统登录
- </h2>
- <el-button style="margin:0px 0px 10px 10px" @click="toLogin">去登录</el-button>
-
- <el-form-item label="账号" prop="account">
- <el-input v-model="ruleForm.account" placeholder="请输入账号" autocomplete="off" prefix-icon="el-icon-user-solid"></el-input>
- </el-form-item>
-
- <el-form-item label="姓名" prop="name">
- <el-input type="text" v-model="ruleForm.name" placeholder="请输入姓名" autocomplete="off" prefix-icon="el-icon-user"></el-input>
- </el-form-item>
-
- <el-form-item label="性别">
- <el-select v-model="ruleForm.sex" placeholder="性别" style="right: 140px">
- <el-option label="男" value="男"></el-option>
- <el-option label="女" value="女"></el-option>
- </el-select>
- </el-form-item>
-
-
-
- <el-form-item label="电话" prop="phone">
- <el-input v-model="ruleForm.phone" placeholder="请输入电话号码" autocomplete="off" prefix-icon="el-icon-phone"></el-input>
- </el-form-item>
-
-
- <el-form-item label="密码" prop="password">
- <el-input type="password" v-model="ruleForm.password" autocomplete="off" placeholder="请输入密码" prefix-icon="el-icon-lock"></el-input>
- </el-form-item>
-
- <el-form-item label="确认密码" prop="checkPass">
- <el-input type="password" v-model="ruleForm.checkPass" autocomplete="off" placeholder="请确认密码" prefix-icon="el-icon-lock"></el-input>
- </el-form-item>
-
- <el-form-item style="margin-right:100px">
- <el-button type="primary" @click="submitForm('ruleForm')">注册</el-button>
- <el-button @click="resetForm('ruleForm')">重置</el-button>
- </el-form-item>
- </el-form>
- </div>
- </template>
-
- <script>
- export default {
- name: 'Register',
- data() {
- var validatePass = (rule, value, callback) => {
- if (value === '') {
- callback(new Error('请输入密码'));
- } else {
- if (this.ruleForm.checkPass !== '') {
- this.$refs.ruleForm.validateField('checkPass');
- }
- callback();
- }
- };
- var validatePass2 = (rule, value, callback) => {
- if (value === '') {
- callback(new Error('请再次输入密码'));
- } else if (value !== this.ruleForm.password) {
- callback(new Error('两次输入密码不一致!'));
- } else {
- callback();
- }
- };
- return {
- ruleForm: {
- account:'',
- password: '',
- name:'',
- checkPass: '',
- phone:'',
- sex: ''
- },
- rules: {
- account: [
- { required: true, message: '请输入账号', trigger: 'blur' },
- { min: 6, max:20, message: '长度在 6 到 15 个字符', trigger: 'blur' }
- ],
- name: [
- { required: true, message: '请输入用户姓名', trigger: 'blur' },
- { min: 2, max: 10, message: '长度在 2 到 10 个字符', trigger: 'blur' }
- ],
- phone: [
- //手机号格式校验规则
- { required: true, message: '请填写手机号', trigger: 'blur' },
- { pattern:/^1(3[0-9]|4[01456879]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\d{8}$/
- , message: '手机号格式不正确', trigger: 'blur' }
- ],
- password: [
- { validator: validatePass, trigger: 'blur' }
- ],
- checkPass: [
- { validator: validatePass2, trigger: 'blur' }
- ],
- }
- };
- },
- methods: {
- submitForm(ruleForm) {
- //清除表单
- this.ruleForm = {};
- //axios请求
- this.axios.post('http://localhost:3333/user/register', this.ruleForm).then((resp) => {
- console.log(resp)
- let data = resp.data;
- console.log(data)
- if (data.success) {
- //消息提示
- this.$message({
- message:'注册成功',
- type:'success'
- });
- }
- })
- },
- resetForm(formName) {
- this.$refs[formName].resetFields();
- },
- toLogin(){
- this.$router.push({
- path:'/'
- })
- }
- }
- }
- </script>
-
- <style>
- #poster{
- background-position: center;
- height: 100%;
- width: 100%;
- background-size: cover;
- position: fixed;
- margin: 0px;
- padding: 0px;
- }
-
- .register-container{
- border-radius: 15px;
- background-clip: padding-box;
- margin:80px auto;
- padding: 35px 35px 15px 35px;
- width: 600px;
- height: 480px;
- background:#fff;
- border:1px solid #eaeaea;
- box-shadow:0 0 1000px #cac6c6;
- }
- .register_title{
- margin:0px auto 30px auto;
- text-align: center;
- color:#505458
- }
-
- </style>
首先前端填写表单,发送post请求调接口
- submitForm(ruleForm) {
- //axios请求
- this.axios.post('http://localhost:3333/user/register', this.ruleForm).then((resp) => {
- console.log(resp)
- let data = resp.data;
- console.log(data)
- if (data.success) {
- //消息提示
- this.$message({
- message:'注册成功',
- type:'success'
- });
- }
- })
- },
registerUserVo对应前端传过来表单的实体类,然后对密码进行加盐处理
- @PostMapping("/register")
- public CommonDto register(@RequestBody RegisterUserVo registerUserVo){
- CommonDto<User> commonDto = new CommonDto<>();
- //密码加盐
- registerUserVo.setPassword(DigestUtils.md5DigestAsHex(registerUserVo.getPassword().getBytes()));
- userService.register(registerUserVo);
- commonDto.setMessage("注册成功");
- return commonDto;
- }
service层首先判断传过来的数据数据库中id是否为空,如果不为空,再根据account字段查询数据库中有无相同account数据,若没有才可注册,接着用雪花算法设置一个id,把数据插入数据库中
- @Override
- public void register(RegisterUserVo registerUserVo) {
- User user = BeanCopyUtils.copyBean(registerUserVo, User.class);
- if (ObjectUtils.isEmpty(registerUserVo.getId())){
- User userDB = selectByAccount(registerUserVo.getAccount());
- if(ObjectUtils.isEmpty(userDB)){
- user.setId(snowflake.nextId());
- userMapper.insert(user);
- }
- }
- }
- //查询account是否被注册
- public User selectByAccount(String account){
- LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
- wrapper.eq(User::getAccount,account);
- List<User> userList = userMapper.selectList(wrapper);
- if(CollectionUtils.isEmpty(userList)){
- return null;
- }else {
- return userList.get(0);
- }
- }
雪花算法
- package com.like.utils;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.stereotype.Component;
-
- import java.text.MessageFormat;
-
- @Slf4j
- @Component
- public class Snowflake {
- // ==============================Fields===========================================
- /**
- * 开始时间戳 (2000-01-01 00:00:00)
- */
- private static final long TWEPOCH = 946656000000L;
-
- /**
- * 机器id所占的位数 5
- */
- private static final long WORKER_ID_BITS = 5L;
-
- /**
- * 数据标识id所占的位数 5
- */
- private static final long DATA_CENTER_ID_BITS = 5L;
-
- /**
- * 支持的最大机器id,结果是 31
- */
- private static final long MAX_WORKER_ID = ~(-1L << WORKER_ID_BITS);
-
- /**
- * 支持的最大数据标识id,结果是 31
- */
- private static final long MAX_DATA_CENTER_ID = ~(-1L << DATA_CENTER_ID_BITS);
-
- /**
- * 序列在id中占的位数
- */
- private static final long SEQUENCE_BITS = 12L;
-
- /**
- * 机器ID向左移12位
- */
- private static final long WORKER_ID_SHIFT = SEQUENCE_BITS;
-
- /**
- * 数据标识id向左移17位(12+5)
- */
- private static final long DATA_CENTER_ID_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS;
-
- /**
- * 时间戳向左移22位(5+5+12)
- */
- private static final long TIMESTAMP_LEFT_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS + DATA_CENTER_ID_BITS;
-
- /**
- * 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095)
- */
- private static final long SEQUENCE_MASK = ~(-1L << SEQUENCE_BITS);
-
- /**
- * 步长 1024
- */
- private static final long STEP_SIZE = 1024;
-
- /**
- * unsigned int max value
- */
- private static final long UINT_MAX_VALUE = 0xffffffffL;
-
- /**
- * 工作机器ID(0~31)
- */
- private long workerId;
-
- /**
- * 工作机器ID 计数器
- */
- private long workerIdFlags = 0L;
-
- /**
- * 数据中心ID(0~31)
- */
- private long dataCenterId;
-
- /**
- * 数据中心ID 计数器
- */
- private long dataCenterIdFlags = 0L;
-
- /**
- * 毫秒内序列(0~4095)
- */
- private long sequence = 0L;
-
- /**
- * 毫秒内序列基数[0|1024|2048|3072]
- */
- private long basicSequence = 0L;
-
- /**
- * 上次生成ID的时间戳
- */
- private long lastTimestamp = -1L;
-
- /**
- * 工作模式
- */
- private final WorkMode workMode;
-
- public enum WorkMode { NON_SHARED, RATE_1024, RATE_4096; }
-
- //==============================Constructors=====================================
-
- public Snowflake() {
- this(0, 0, WorkMode.RATE_4096);
- }
-
- /**
- * 构造函数
- * @param workerId 工作ID (0~31)
- * @param dataCenterId 数据中心ID (0~31)
- */
- public Snowflake(long workerId, long dataCenterId) {
- this(workerId, dataCenterId, WorkMode.RATE_4096);
- }
-
- /**
- * 构造函数
- * @param workerId 工作ID (0~31)
- * @param dataCenterId 数据中心ID (0~31)
- * @param workMode 工作模式
- */
- public Snowflake(long workerId, long dataCenterId, WorkMode workMode) {
- this.workMode = workMode;
- if (workerId > MAX_WORKER_ID || workerId < 0) {
- throw new IllegalArgumentException(MessageFormat.format("worker Id can't be greater than {0} or less than 0", MAX_WORKER_ID));
- }
- if (dataCenterId > MAX_DATA_CENTER_ID || dataCenterId < 0) {
- throw new IllegalArgumentException(MessageFormat.format("datacenter Id can't be greater than {0} or less than 0", MAX_DATA_CENTER_ID));
- }
- this.workerId = workerId;
- this.workerIdFlags = setSpecifiedBitTo1(this.workerIdFlags, this.workerId);
- this.dataCenterId = dataCenterId;
- this.dataCenterIdFlags = setSpecifiedBitTo1(this.dataCenterIdFlags, this.dataCenterId);
- }
-
- // ==============================Methods==========================================
-
- /**
- * 获取机器id
- *
- * @return 所属机器的id
- */
- public long getWorkerId() {
- return workerId;
- }
-
- /**
- * 获取数据中心id
- *
- * @return 所属数据中心id
- */
- public long getDataCenterId() {
- return dataCenterId;
- }
-
- /**
- * 获得下一个ID (该方法是线程安全的)
- *
- * @return SnowflakeId
- */
- public synchronized long nextId() {
- long timestamp = timeGen();
- //如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常
- if (timestamp < this.lastTimestamp) {
- if (timestamp > TWEPOCH) {
- if (WorkMode.NON_SHARED == this.workMode) {
- nonSharedClockBackwards(timestamp);
- } else if (WorkMode.RATE_1024 == this.workMode) {
- rate1024ClockBackwards(timestamp);
- } else {
- throw new RuntimeException(MessageFormat.format("Clock moved backwards. Refusing to generate id for {0} milliseconds", lastTimestamp - timestamp));
- }
- } else {
- throw new RuntimeException(MessageFormat.format("Clock moved backwards. Refusing to generate id for {0} milliseconds", lastTimestamp - timestamp));
- }
- }
- //如果是同一时间生成的,则进行毫秒内序列
- if (this.lastTimestamp == timestamp) {
- this.sequence = (this.sequence + 1) & SEQUENCE_MASK;
- //毫秒内序列溢出
- if (this.sequence == 0) {
- //阻塞到下一个毫秒,获得新的时间戳
- timestamp = tilNextMillis(this.lastTimestamp);
- }
- }
- //时间戳改变,毫秒内序列重置
- else {
- this.sequence = this.basicSequence;
- }
- //上次生成ID的时间戳
- this.lastTimestamp = timestamp;
- //移位并通过或运算拼到一起组成64位的ID
- return ((timestamp - TWEPOCH) << TIMESTAMP_LEFT_SHIFT)
- | (this.dataCenterId << DATA_CENTER_ID_SHIFT)
- | (this.workerId << WORKER_ID_SHIFT)
- | this.sequence;
- }
-
- /**
- * 阻塞到下一个毫秒,直到获得新的时间戳
- *
- * @param lastTimestamp 上次生成ID的时间戳
- * @return 当前时间戳
- */
- protected long tilNextMillis(long lastTimestamp) {
- long timestamp0;
- do {
- timestamp0 = timeGen();
- } while (timestamp0 <= lastTimestamp);
- return timestamp0;
- }
-
- /**
- * 返回以毫秒为单位的当前时间
- *
- * @return 当前时间(毫秒)
- */
- protected long timeGen() {
- return System.currentTimeMillis();
- }
-
- /**
- * 尝试解决时钟回拨
【* 仅用于 单机生成不对外 的情况 *】 - *
- * @param timestamp 当前时间戳
- * @return void
- */
- private void nonSharedClockBackwards(long timestamp) {
- if (this.dataCenterIdFlags >= UINT_MAX_VALUE && this.workerIdFlags >= UINT_MAX_VALUE) {
- throw new RuntimeException(MessageFormat.format("Clock moved backwards. Refusing to generate id for {0} milliseconds", lastTimestamp - timestamp));
- } else {
- //如果仅用于生成不重复的数值,尝试变更 dataCenterId 或 workerId 修复时钟回拨问题
- log.warn("Clock moved backwards. Refusing to generate id for {} milliseconds", lastTimestamp - timestamp);
- //先尝试变更 dataCenterId,当 dataCenterId 轮询一遍之后,尝试变更 workerId 并重置 dataCenterId
- if (this.dataCenterIdFlags >= UINT_MAX_VALUE) {
- if (++this.workerId > MAX_WORKER_ID) { this.workerId = 0L; }
- this.workerIdFlags = setSpecifiedBitTo1(this.workerIdFlags, this.workerId);
- // 重置 dataCenterId 和 dataCenterIdFlags
- this.dataCenterIdFlags = this.dataCenterId = 0L;
- } else {
- if (++this.dataCenterId > MAX_DATA_CENTER_ID) { this.dataCenterId = 0L; }
- }
- this.dataCenterIdFlags = setSpecifiedBitTo1(this.dataCenterIdFlags, this.dataCenterId);
- this.lastTimestamp = -1L;
- log.warn("Try to fix the clock moved backwards. timestamp : {}, worker Id : {}, datacenter Id : {}", timestamp, workerId, dataCenterId);
- }
- }
-
- /**
- * 尝试解决时钟回拨
【* 仅用于每毫秒生成量 不大于 1024 的情况 *】 - *
- * @param timestamp 当前时间戳
- * @return void
- */
- private void rate1024ClockBackwards(long timestamp) {
- if (this.basicSequence > (SEQUENCE_MASK - STEP_SIZE)) {
- throw new RuntimeException(MessageFormat.format("Clock moved backwards. Refusing to generate id for {0} milliseconds", lastTimestamp - timestamp));
- } else {
- log.warn("Clock moved backwards. Refusing to generate id for {} milliseconds", lastTimestamp - timestamp);
- this.basicSequence += STEP_SIZE;
- this.lastTimestamp = -1L;
- log.warn("Try to fix the clock moved backwards. timestamp : {}, basicSequence : {}", timestamp, basicSequence);
- }
- }
-
- /**
- * Set the specified bit to 1
- *
- * @param value raw long value
- * @param index bit index (From 0~31)
- * @return long value
- */
- private long setSpecifiedBitTo1(long value, long index) {
- return value |= (1L << index);
- }
-
- /**
- * Set the specified bit to 0
- *
- * @param value raw long value
- * @param index bit index (From 0~31)
- * @return long value
- */
- private long setSpecifiedBitTo0(long value, long index) {
- return value &= ~(1L << index);
- }
-
- /**
- * Get the specified bit
- * @param value raw long value
- * @param index bit index(From 0-31)
- * @return 0 or 1
- */
- private int getSpecifiedBit(long value, long index) {
- return (value & (1L << index)) == 0 ? 0 : 1;
- }
-
- }
BeanCopy类
- package com.like.utils;
-
- import org.springframework.beans.BeanUtils;
-
- import java.util.List;
- import java.util.stream.Collectors;
-
- public class BeanCopyUtils {
-
- private BeanCopyUtils(){
-
- }
-
-
- public static
V copyBean(Object source,Class clazz) { - V result;
- try {
- result = clazz.getDeclaredConstructor().newInstance();
- BeanUtils.copyProperties(source, result);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- return result;
- }
-
- public static
List copyBeanList(List list,Class clazz) { - return list.stream().
- map(o -> copyBean(o, clazz))
- .collect(Collectors.toList());
- }
-
- }
首先拿到前端传来的数据,用LoginVo接收,然后根据账号判断是否注册过,若已注册,则判断密码是否正确,从而放行
- login() {
- console.log('submit!',this.loginForm);
- this.axios.post('http://localhost:3333/user/login',this.loginForm).then((resp)=>{
- let data = resp.data;
- if(data.success){
- this.loginForm = {},
- this.$message({
- message: data.message,
- type: 'success'
- });
- this.$router.push({
- path:'/home'
- })
- }
- })
- }
LoginUserVo
- package com.like.common;
-
- import lombok.AllArgsConstructor;
- import lombok.Data;
- import lombok.EqualsAndHashCode;
- import lombok.NoArgsConstructor;
-
- @Data
- @AllArgsConstructor
- @NoArgsConstructor
- @EqualsAndHashCode(callSuper = false)
- public class LoginUserVo {
- /**
- * 账号
- */
- private String account;
- /**
- * 密码
- */
- private String password;
- }
controller层
- @PostMapping("/login")
- public CommonDto login(@RequestBody LoginUserVo loginUserVo){
- CommonDto commonDto = userService.login(loginUserVo);
- return commonDto;
- }
service层
- @Override
- public CommonDto login(LoginUserVo loginUserVo) {
- CommonDto commonDto = new CommonDto();
- User userDB = selectByAccount(loginUserVo.getAccount());
- if(ObjectUtils.isEmpty(userDB)){
- commonDto.setSuccess(false);
- commonDto.setContent("账号不存在");
- return commonDto;
- }
- String loginUserVoPassword = DigestUtils.md5DigestAsHex(loginUserVo.getPassword().getBytes());
- String password = userDB.getPassword();
-
- if(loginUserVoPassword.equals(password)){
- commonDto.setMessage("恭喜你登录成功");
- }
- commonDto.setContent(loginUserVo);
- return commonDto;
- }