日报:完成注册功能

完成了注册的功能

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

具体后端
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')
    }
posted @ 2025-04-16 23:43  QixunQiu  阅读(22)  评论(0)    收藏  举报