本节代码开源地址
代码地址
用户注册前端
1.在src/api下创建/auth/auth.js
import request from '@/utils/request'
export function userRegister(UserDTO) {
return request({
url: '/auth/user/register',
method: 'post',
data: UserDTO
})
}
2.在src/views创建/auth/register.vue
<template>
<div class="columns py-6">
<div class="column is-half is-offset-one-quarter">
<el-card shadow="never">
<div slot="header" class="has-text-centered has-text-weight-bold">新用户入驻</div>
<div>
<el-form
ref="ruleForm"
v-loading="loading"
:model="ruleForm"
status-icon
:rules="rules"
label-width="100px"
class="demo-ruleForm"
>
<el-form-item label="账号" prop="name">
<el-input v-model="ruleForm.name" />
</el-form-item>
<el-form-item label="密码" prop="pass">
<el-input v-model="ruleForm.pass" type="password" autocomplete="off" />
</el-form-item>
<el-form-item label="确认密码" prop="checkPass">
<el-input v-model="ruleForm.checkPass" type="password" autocomplete="off" />
</el-form-item>
<el-form-item label="邮箱" prop="email">
<el-input v-model="ruleForm.email" autocomplete="off" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')">立即注册</el-button>
<el-button @click="resetForm('ruleForm')">重置</el-button>
</el-form-item>
</el-form>
</div>
</el-card>
</div>
</div>
</template>
<script>
import { userRegister } from "@/api/auth/auth";
export default {
name: "Register",
data() {
const validatePass = (rule, value, callback) => {
if (value === "") {
callback(new Error("请再次输入密码"));
} else if (value !== this.ruleForm.pass) {
callback(new Error("两次输入密码不一致!"));
} else {
callback();
}
};
return {
loading: false,
ruleForm: {
name: "",
pass: "",
checkPass: "",
email: ""
},
rules: {
name: [
{ required: true, message: "请输入账号", trigger: "blur" },
{
min: 2,
max: 10,
message: "长度在 2 到 10 个字符",
trigger: "blur"
}
],
pass: [
{ required: true, message: "请输入密码", trigger: "blur" },
{
min: 6,
max: 20,
message: "长度在 6 到 20 个字符",
trigger: "blur"
}
],
checkPass: [
{ required: true, message: "请再次输入密码", trigger: "blur" },
{ validator: validatePass, trigger: "blur" }
],
email: [
{ required: true, message: "请输入邮箱地址", trigger: "blur" },
{
type: "email",
message: "请输入正确的邮箱地址",
trigger: ["blur", "change"]
}
]
}
};
},
methods: {
submitForm(formName) {
this.$refs[formName].validate(valid => {
if (valid) {
this.loading = true;
userRegister(this.ruleForm)
.then(value => {
const { code, message } = value;
if (code === 200) {
this.$message({
message: "账号注册成功",
type: "success"
});
setTimeout(() => {
this.loading = false;
this.$router.push({ path: this.redirect || "/login" });
}, 0.1 * 1000);
} else {
this.$message.error("注册失败," + message);
}
})
.catch(() => {
this.loading = false;
});
} else {
return false;
}
});
},
resetForm(formName) {
this.$refs[formName].resetFields();
}
}
};
</script>
<style scoped>
</style>
3.测试页面
image-20210211232353719
用户注册后端
1.实体类
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.AllArgsConstructor;
import lombok.Builder;ums_user
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
@Data
@Builder
@TableName("ums_user")
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class UmsUser implements Serializable {
private static final long serialVersionUID = -5051120337175047163L;
@TableId(value = "id", type = IdType.ASSIGN_ID)
private String id;
@TableField("username")
private String username;
@TableField("alias")
private String alias;
@JsonIgnore()
@TableField("password")
private String password;
@Builder.Default
@TableField("avatar")
private String avatar = "https://s3.ax1x.com/2020/12/01/DfHNo4.jpg";
@TableField("email")
private String email;
@TableField("mobile")
private String mobile;
@Builder.Default
@TableField("bio")
private String bio = "自由职业者";
@Builder.Default
@TableField("score")
private Integer score = 0;
@JsonIgnore
@TableField("token")
private String token;
@Builder.Default
@TableField("active")
private Boolean active = true;
/**
* 状态。1:使用,0:已停用
*/
@Builder.Default
@TableField("`status`")
private Boolean status = true;
/**
* 用户角色
*/
@TableField("role_id")
private Integer roleId;
@TableField(value = "create_time", fill = FieldFill.INSERT)
private Date createTime;
@TableField(value = "modify_time", fill = FieldFill.INSERT_UPDATE)
private Date modifyTime;
}
2.mapper接口
public interface UmsUserMapper extends BaseMapper<UmsUser> {
}
3.DTO
import lombok.AllArgsConstructor;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
@Data
@AllArgsConstructor
public class RegisterDTO {
@NotEmpty(message = "请输入账号")
@Length(min = 2, max = 15, message = "长度在2-15")
private String name;
@NotEmpty(message = "请输入密码")
@Length(min = 6, max = 20, message = "长度在6-20")
private String pass;
@NotEmpty(message = "请再次输入密码")
@Length(min = 6, max = 20, message = "长度在6-20")
private String checkPass;
@NotEmpty(message = "请输入电子邮箱")
@Email(message = "邮箱格式不正确")
private String email;
}
4.controller
@RestController
@RequestMapping("/auth/user")
public class UmsUserController {
@Autowired
private UmsUserService umsUserService;
/**
* 注册
*
* @param registerDTO 接收参数
* @return
*/
@PostMapping("/register")
private ApiResult register(@RequestBody RegisterDTO registerDTO) {
Boolean register = umsUserService.register(registerDTO);
return ApiResult.success(register);
}
}
5.service
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.notepad.blog.common.api.ApiResult;
import com.notepad.blog.common.exception.ApiAsserts;
import com.notepad.blog.domain.UmsUser;
import com.notepad.blog.domain.dto.RegisterDTO;
import com.notepad.blog.mapper.UmsUserMapper;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import java.util.Date;
@Service
public class UmsUserService extends ServiceImpl<UmsUserMapper, UmsUser> {
public UmsUser register(RegisterDTO registerDTO) {
// 查询是否有相同的用户名
String userName = registerDTO.getName();
String email = registerDTO.getEmail();
LambdaQueryWrapper<UmsUser> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(UmsUser::getUsername, userName)
.or()
.eq(UmsUser::getEmail, userName);
UmsUser umuser = this.getOne(queryWrapper);
if (!ObjectUtils.isEmpty(umuser)) {
ApiAsserts.fail("账号或邮箱已存在");
}
// 否则注册
UmsUser umsUser = UmsUser.builder()
.username(userName)
.alias(userName)
.password(registerDTO.getPass())
.email(email)
.createTime(new Date())
.status(true)
.build();
this.save(umsUser);
return umsUser;
}
}
密码加密
package com.notepad.blog.common.utils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5Utils {
public static String getPwd(String pwd) {
try {
// 创建加密对象
MessageDigest digest = MessageDigest.getInstance("md5");
// 调用加密对象的方法,加密的动作已经完成
byte[] bs = digest.digest(pwd.getBytes());
// 接下来,我们要对加密后的结果,进行优化,按照mysql的优化思路走
// mysql的优化思路:
// 第一步,将数据全部转换成正数:
String hexString = "";
for (byte b : bs) {
// 第一步,将数据全部转换成正数:
// 解释:为什么采用b&255
/*
* b:它本来是一个byte类型的数据(1个字节) 255:是一个int类型的数据(4个字节)
* byte类型的数据与int类型的数据进行运算,会自动类型提升为int类型 eg: b: 1001 1100(原始数据)
* 运算时: b: 0000 0000 0000 0000 0000 0000 1001 1100 255: 0000
* 0000 0000 0000 0000 0000 1111 1111 结果:0000 0000 0000 0000
* 0000 0000 1001 1100 此时的temp是一个int类型的整数
*/
int temp = b & 255;
// 第二步,将所有的数据转换成16进制的形式
// 注意:转换的时候注意if正数>=0&&<16,那么如果使用Integer.toHexString(),可能会造成缺少位数
// 因此,需要对temp进行判断
if (temp < 16 && temp >= 0) {
// 手动补上一个“0”
hexString = hexString + "0" + Integer.toHexString(temp);
} else {
hexString = hexString + Integer.toHexString(temp);
}
}
return hexString;
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "";
}
public static void main(String[] args) {
String pwd = MD5Utils.getPwd("234");
System.out.println(pwd);
}
}
404页面
1.在src/views创建/error/404.vue
<template>
<div class="columns mt-6">
<div class="column mt-6">
<div class="mt-6">
<p class="content">UH OH! 页面丢失</p>
<p class="content subtitle mt-6">
您所寻找的页面不存在, {{ times }} 秒后,将返回首页!
</p>
</div>
</div>
</div>
</template>
<script>
export default {
name: "404",
data() {
return {
times: 10
}
},
created() {
this.goHome();
},
methods: {
goHome: function () {
this.timer = setInterval(() => {
this.times--
if (this.times === 0) {
clearInterval(this.timer)
this.$router.push({path: '/'});
}
}, 1000)
}
}
}
</script>
<style scoped>
</style>
2.配置路由
,{
path: '/404',
name: '404',
component: () => import('@/views/error/404'),
meta: {title: '404-Notfound'}
},{
path: '*',
redirect: '404',
hidden: true
}
3.测试页面
http://localhost:8080/#/404
image-20210211231915169
网友评论