SpringBoot3+Vue3实现登录注册功能

登录

页面Login.vue

F12 应用中会存储用户信息

image-20250304081910180.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
<template>
<div class="bg">
<div style="width: 350px;background-color: #fff; /*opacity: 0.9;*/ border-radius: 5px; box-shadow: 0 0 10px rgba(0,0,0,0.1); padding: 40px 20px">
<el-form ref="formRef" :model="data.form" :rules="data.rules">

<div style="margin-bottom: 40px; text-align: center; font-weight: bold;font-size: 24px">欢 迎 登 录</div>
<el-form-item prop="username">
<el-input size="large" v-model="data.form.username" autocomplete="off" prefix-icon="User" placeholder="请输入账号" />
</el-form-item>

<el-form-item prop="password">
<el-input size="large" show-password v-model="data.form.password" autocomplete="off" prefix-icon="Lock" placeholder="请输入密码"/>
</el-form-item>

<el-form-item prop="role">
<el-select size="large" style="width: 100%" v-model="data.form.role">
<el-option label="管理员" value="ADMIN"></el-option>
<el-option label="普通用户" value="USER"></el-option>
</el-select>
</el-form-item>

<div style="margin-bottom: 20px;">
<el-button style="width: 100%" size="large" type="primary" @click="login">登 录</el-button>
</div>

<div style="text-align: right">
还没有账号?请<a style="color: #1869e0" href="/register">注册</a>
</div>
</el-form>
</div>
</div>
</template>

<script setup>
import { reactive, ref } from "vue";
import { ElMessage } from "element-plus";
import axios from 'axios'; // ✅ 正确导入 axios
import router from "@/router/index.js";
import request from '@/utils/request'; // ✅ 从你的工具目录导入

const formRef = ref();
const data = reactive({
form: {
username: '',
password: '',
role: 'ADMIN'
},
rules: {
username: [
{ required: true, message: '请输入账号', trigger: 'blur' },
{ min: 3, message: '账号最少3位', trigger: 'blur' }
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' }
]
}
});

const login = () => {
formRef.value.validate((valid) => {
if (valid) { // 验证通过才发送请求
request.post('/login', data.form).then(res => {
if (res.code === '200') {
localStorage.setItem("code2025_user", JSON.stringify(res.data || {}));
ElMessage.success('登录成功');
router.push('/');
} else {
ElMessage.error(res.msg);
}
});
} else {
ElMessage.error('请检查输入是否合法');
return false;
}
});
};

</script>

<style scoped> /*限定在当前的页面 在css中 //是非法的 */
.bg {
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
background-image: url("@/assets/imgs/登录.png");
background-size: cover;
}

/* 修改背景颜色 */
.bg {
background-color: #f17df0;
}

/* 修改表单区域的颜色 */
.bg div {
background-color: #ffffff;
color: #333333;
}
</style>

登录接口

controller

1
2
3
4
5
6
7
8
9
10
11
12
@PostMapping("/login")
public Result login(@RequestBody Account account){
Account dbAccount = null;
if("ADMIN".equals(account.getRole())) {
dbAccount = adminService.login(account);
}else if("USER".equals(account.getRole())){
dbAccount = userService.login(account);
}else{
throw new CustomerException("非法请求");
}
return Result.success(dbAccount);
}

service

1
2
3
4
5
6
7
8
9
10
11
public Admin login(Admin admin) {
Admin dbAdmin = adminMapper.selectByUsername(admin.getUsername());
if(dbAdmin == null){
throw new CustomerException("账号不存在");
}
// 验证账号密码是否正确
if(!dbAdmin.getPassword().equals(admin.getPassword())){
throw new CustomerException("账号或密码错误");
}
return dbAdmin;
}

退出登录

在Manager.vue哪里实现 退出登录哪里绑定logout

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script setup>
import router from "@/router/index.js";

const logout = () => {
localStorage.removeItem("code2025_user")
location.href = '/login'
}

//检测缓存中有没有用户信息
let userStr = localStorage.getItem('code2025_user')
if(userStr) {
let user = JSON.parse(userStr)
if(!user.id){
location.href = '/login'
}
}else{
location.href = '/login'
}
</script>

模仿管理员开发用户管理

数据库表user

1
2
3
4
5
6
7
8
9
10
11
CREATE TABLE `user` (
`id` int NOT NULL AUTO_INCREMENT COMMENT 'ID',
`username` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '账号',
`password` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '密码',
`name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '名称',
`phone` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '手机',
`email` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '邮箱',
`role` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '角色',
PRIMARY KEY (`id`),
UNIQUE KEY `username_index` (`username`) USING BTREE COMMENT '账号\r\n'
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户信息';
1
2
3
4
5
ALTER TABLE admin
MODIFY `role` VARCHAR(255) DEFAULT 'ADMIN' COMMENT '角色';

ALTER TABLE user
MODIFY `role` VARCHAR(255) DEFAULT 'USER' COMMENT '角色';

user相关接口

user管理页面

开发的过程就是复制admin相关的Entity,Controller,Service,Mapper,Mapper.xml,然后改名为Admin==> User即可

遇到"未找到接口"的问题

这是因为没有重启后台,重启即可,或者是接口没写

注册

页面Register.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
<template>
<div class="bg">
<div style="width: 350px;background-color: #fff; /*opacity: 0.9;*/ border-radius: 5px; box-shadow: 0 0 10px rgba(0,0,0,0.1); padding: 40px 20px">
<el-form status-icon ref="formRef" :model="data.form" :rules="data.rules">

<div style="margin-bottom: 40px; text-align: center; font-weight: bold;font-size: 24px">欢 迎 注 册</div>
<el-form-item prop="username">
<el-input size="large" v-model="data.form.username" autocomplete="off" prefix-icon="User" placeholder="请输入账号" />
</el-form-item>

<el-form-item prop="password">
<el-input size="large" show-password v-model="data.form.password" autocomplete="off" prefix-icon="Lock" placeholder="请输入密码"/>
</el-form-item>

<el-form-item prop="confirmPassword">
<el-input size="large" show-password v-model="data.form.confirmPassword" autocomplete="off" prefix-icon="Lock" placeholder="请再次确认密码"/>
</el-form-item>

<div style="margin-bottom: 20px;">
<el-button style="width: 100%; background-color: #7eaedf;border-color: #7eaedf;" size="large" type="primary" @click="register">注 册</el-button>
</div>

<div style="text-align: right">
已有账号?请<a style="color: #7eaedf" href="/login">登录</a>
</div>
</el-form>
</div>
</div>
</template>

<script setup>
import { reactive, ref } from "vue";
import { ElMessage } from "element-plus";
import axios from 'axios'; // ✅ 正确导入 axios
import router from "@/router/index.js";
import request from '@/utils/request'; // ✅ 从你的工具目录导入


const validatePass = (rule,value,callback) => {
//value 表示用户输入的确认密码
if(value!== data.form.password){
callback(new Error('两次输入的密码不匹配!'))
}else {
callback()
}
}

const formRef = ref();
const data = reactive({
form: {
username: '',
password: ''
},
rules: {
username: [
{ required: true, message: '请输入账号', trigger: 'blur' },
{ min: 3, message: '账号最少3位', trigger: 'blur' }
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' }
],
confirmPassword: [
{ required: true,message: '请再次确认密码',trigger:'blur' },
{ validator: validatePass,trigger: 'blur'}
]
}
});




const register = () => {
formRef.value.validate((valid) => {
if (valid) { // 验证通过才发送请求
request.post('/register', data.form).then(res => {
if (res.code === '200') {
ElMessage.success('注册成功成功');
router.push('/login');
} else {
ElMessage.error(res.msg);
}
});
} else {
ElMessage.error('请检查输入是否合法');
return false;
}
});
};

</script>

<style scoped>

.bg {
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
background-image: url("@/assets/imgs/注册.png");
background-size: cover;
}

/* 修改背景颜色 */
.bg {
background-color: #f17df0;
}

/* 修改表单区域的颜色 */
.bg div {
background-color: #ffffff;
color: #333333;
}

</style>

注册接口

1
2
3
4
5
6
7
8
9
10
 @PostMapping("/register")
public Result register(@RequestBody User user){
userService.register(user);
return Result.success();
}


public void register(User user) {
this.add(user);
}

自定义的错误

不是系统的错误 不是代码的bug