日报:完成注册功能
完成了注册的功能

可以检测是否重名,输入是否符合规范,密码的二重验证。

具体后端
RegisterRequest
package com.example.demo.dto;
import lombok.Data;
/*
* Qi
* 25/4/16
* 注册
* */
@Data
public class RegisterRequest {
private String id;
private String username;
private String phone;
private String email;
private String password;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
UserController
package com.example.demo.controller;
import com.example.demo.common.Result;
import com.example.demo.dto.LoginRequest;
import com.example.demo.dto.RegisterRequest;
import com.example.demo.entity.User;
import com.example.demo.exception.CustomException;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
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;
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
/*
* vivy
* 25/4/14
* 登录
* */
@PostMapping("/login")
public Result login(@RequestBody LoginRequest loginRequest) {
if (loginRequest.getAccount() == null || loginRequest.getPassword() == null) {
return Result.fail("账号和密码不能为空");
}
User user = userService.login(loginRequest);
if (user != null) {
// 不返回密码
user.setPassword(null);
return Result.success(user);
} else {
return Result.fail("账号或密码错误");
}
}
/*
* Qi
* 25/4/16
* 注册
* */
@PostMapping("/register")
public Result register(@RequestBody RegisterRequest registerRequest) {
// 参数验证
if (registerRequest.getUsername() == null || registerRequest.getPassword() == null
|| registerRequest.getPhone() == null || registerRequest.getEmail() == null) {
return Result.fail("注册信息不完整");
}
try {
User user = userService.register(registerRequest);
user.setPassword(null); // 不返回密码
return Result.success(user);
} catch (CustomException e) {
return Result.fail(e.getMsg());
} catch (Exception e) {
return Result.fail("注册失败,请稍后重试");
}
}
}
UserServiceImpl
package com.example.demo.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.demo.dto.LoginRequest;
import com.example.demo.dto.RegisterRequest;
import com.example.demo.entity.User;
import com.example.demo.exception.CustomException;
import com.example.demo.mapper.UserMapper;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
/*
* vivy
* 25/4/14
* 登录
* */
@Override
public User login(LoginRequest loginRequest) {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("username", loginRequest.getAccount())
.or().eq("phone", loginRequest.getAccount())
.or().eq("email", loginRequest.getAccount())
.or().eq("id", loginRequest.getAccount());
User user = userMapper.selectOne(queryWrapper);
if (user != null && user.getPassword().equals(loginRequest.getPassword())) {
// 实际项目中应该使用加密算法比较密码
return user;
}
return null;
}
/*
* Qi
* 25/4/16
* 注册
* */
@Override
public User register(RegisterRequest registerRequest) {
// 检查用户名是否已存在
QueryWrapper<User> usernameWrapper = new QueryWrapper<>();
usernameWrapper.eq("username", registerRequest.getUsername());
if (userMapper.selectCount(usernameWrapper) > 0) {
throw new CustomException("400", "用户名已存在");
}
// 检查手机号是否已存在
QueryWrapper<User> phoneWrapper = new QueryWrapper<>();
phoneWrapper.eq("phone", registerRequest.getPhone());
if (userMapper.selectCount(phoneWrapper) > 0) {
throw new CustomException("400", "手机号已被注册");
}
// 检查邮箱是否已存在
QueryWrapper<User> emailWrapper = new QueryWrapper<>();
emailWrapper.eq("email", registerRequest.getEmail());
if (userMapper.selectCount(emailWrapper) > 0) {
throw new CustomException("400", "邮箱已被注册");
}
// 生成工号
String employeeId = generateEmployeeId();
// 创建新用户
User user = new User();
user.setUsername(registerRequest.getUsername());
user.setPhone(registerRequest.getPhone());
user.setEmail(registerRequest.getEmail());
user.setPassword(registerRequest.getPassword());
user.setRole("engineer");
user.setId(employeeId); // 设置生成的工号
userMapper.insert(user);
return user;
}
/**
* 生成工号:年份+4位序号,如20250001
*/
private String generateEmployeeId() {
// 获取当前年份
String currentYear = String.valueOf(LocalDateTime.now().getYear());
// 查询当前年份最大序号
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.likeRight("id", currentYear) // 查询以当前年份开头的工号
.orderByDesc("id") // 按工号降序排序
.last("LIMIT 1"); // 只取第一条记录
User lastUser = userMapper.selectOne(queryWrapper);
String newId;
if (lastUser == null) {
// 如果该年份没有用户,则从0001开始
newId = currentYear + "0001";
} else {
// 获取最后一个工号的序号部分并加1
String lastId = lastUser.getId();
int sequence = Integer.parseInt(lastId.substring(4)) + 1;
newId = currentYear + String.format("%04d", sequence);
}
return newId;
}
}
UserService
package com.example.demo.service;
import com.example.demo.dto.LoginRequest;
import com.example.demo.dto.RegisterRequest;
import com.example.demo.entity.User;
public interface UserService {
User login(LoginRequest loginRequest);
/*
* Qi
* 25/4/16
* 注册
* */
User register(RegisterRequest registerRequest);
}
register.vue
<!-- Qi -->
<!-- 05/4/16 -->
<template>
<div class="register-container">
<el-card class="register-card">
<h2>用户注册</h2>
<el-form :model="registerForm" :rules="rules" ref="registerFormRef" label-width="80px">
<el-form-item label="用户名" prop="username">
<el-input v-model="registerForm.username" placeholder="请输入用户名"></el-input>
</el-form-item>
<el-form-item label="手机号" prop="phone">
<el-input v-model="registerForm.phone" placeholder="请输入手机号"></el-input>
</el-form-item>
<el-form-item label="邮箱" prop="email">
<el-input v-model="registerForm.email" placeholder="请输入邮箱"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input v-model="registerForm.password" type="password" placeholder="请输入密码"></el-input>
</el-form-item>
<el-form-item label="确认密码" prop="confirmPassword">
<el-input v-model="registerForm.confirmPassword" type="password" placeholder="请确认密码"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm">注册</el-button>
<el-button @click="resetForm">重置</el-button>
</el-form-item>
<div class="login-link">
已有账号?<el-link type="primary" @click="goToLogin">立即登录</el-link>
</div>
</el-form>
</el-card>
</div>
</template>
<script setup>
import { ref, reactive } from 'vue'
import { useRouter } from 'vue-router'
import { register } from '@/api/user'
import { ElMessage } from 'element-plus'
const router = useRouter()
const registerForm = reactive({
username: '',
phone: '',
email: '',
password: '',
confirmPassword: ''
})
const validatePass2 = (rule, value, callback) => {
if (value !== registerForm.password) {
callback(new Error('两次输入密码不一致!'))
} else {
callback()
}
}
const rules = {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' }
],
phone: [
{ required: true, message: '请输入手机号', trigger: 'blur' },
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' }
],
email: [
{ required: true, message: '请输入邮箱', trigger: 'blur' },
{ type: 'email', message: '请输入正确的邮箱地址', trigger: 'blur' }
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 6, message: '密码长度不能小于6位', trigger: 'blur' }
],
confirmPassword: [
{ required: true, message: '请再次输入密码', trigger: 'blur' },
{ validator: validatePass2, trigger: 'blur' }
]
}
const registerFormRef = ref(null)
const submitForm = async () => {
if (!registerFormRef.value) return
try {
const valid = await registerFormRef.value.validate()
if (valid) {
const { username, phone, email, password } = registerForm
const res = await register({ username, phone, email, password })
if (res.code === 200) {
ElMessage.success('注册成功')
router.push('/login')
} else {
ElMessage.error(res.msg || '注册失败')
}
}
} catch (error) {
console.error('注册错误:', error)
ElMessage.error(error.response?.data?.msg || '注册失败')
}
}
const resetForm = () => {
if (registerFormRef.value) {
registerFormRef.value.resetFields()
}
}
const goToLogin = () => {
router.push('/login')
}
</script>
<style scoped>
.register-container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #f5f5f5;
}
.register-card {
width: 480px;
}
h2 {
text-align: center;
margin-bottom: 30px;
}
.login-link {
text-align: center;
margin-top: 20px;
}
</style>
index.js新增
{
path: '/register',
name: 'register',
component: () => import('../views/register.vue')
}
浙公网安备 33010602011771号