文章目录
前言
Vue+element-plus的管理系统模板有很多,其开发步骤类似
一、大致页面
二、工程结构
二、创建步骤
1.安装Vue
全局安装@vue/cli(仅第一次执行)
注意:要以管理员的身份打开cmd1.如果出现下载缓慢可以先配置淘宝镜像:
npm config set registry https://registry.npm.taobao.org
npm install -g @vue/cli
创建脚手架工程
在目录位置打开cmd,运行命令行:
vue create xxxx
选择Vue版本
运行项目:
1.先进入创建的文件夹的路径:
cd vue_text
- 然后输入 :
npm run serve
2.安装/引入element-plus
在项目中打开cmd命令窗口,输入命令
npm install element-plus --save
安装成功,在main.js将其引入到自己的项目中
三、部分代码
1.main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import 'element-plus/dist/index.css'
import store from './store'
import '@/assets/css/global.css'
import ElementPlus from 'element-plus'
createApp(App).use(store).use(router).use(ElementPlus).mount('#app')
2.App.vue
<template>
<div>
<el-config-provider :locale="locale">
<router-view />
</el-config-provider>
</div>
</template>
<script>
import locale from "element-plus/lib/locale/lang/zh-cn";
export default {
name: 'App',
components: {
},
setup() {
return { locale };
}
}
</script>
<style>
</style>
3.布局框架文件layout.vue
<!--用作框架-->
<template>
<div>
<el-config-provider :locale="locale">
<!-- 头部-->
<Header/>
<!-- 主体-->
<div style="display: flex">
<!-- 侧边栏-->
<Aside/>
<!-- 主体内容区域-->
<router-view style="flex: 1"/>
</div>
</el-config-provider>
</div>
</template>
<script>
import Header from "../components/Header";
import Aside from "../components/Aside";
import locale from "element-plus/lib/locale/lang/zh-cn";
export default {
name: "Layout",
components:{
Header,
Aside,
},
setup() {
return { locale };
}
}
</script>
<style scoped>
</style>
4.头部栏components/Header.vue
<!--头部导航栏-->
<template>
<div class="topNavigation">
<div class="headerMenu">后台管理</div>
<div style="flex: 1"></div>
<div style="width: 100px">
<el-dropdown>
<el-button>{{user.nickname}}<el-icon><arrow-down /></el-icon></el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>个人信息</el-dropdown-item>
<el-dropdown-item @click="quit">退出系统</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
</template>
<script>
import { ArrowDown } from '@element-plus/icons-vue'
import router from "../router";
export default {
name: "Header",
components:{
ArrowDown
},
data(){
return{
user:{},
}
},
created() {
this.user = JSON.parse(sessionStorage.getItem("user")||"{}");
},
methods:{
quit(){
sessionStorage.clear();
router.push("/login");
},
}
}
</script>
<style>
.topNavigation {
height: 50px;
line-height: 50px;
border-bottom: 1px solid #f6eaff;
display: flex;
}
.headerMenu {
width: 200px;
padding-left: 30px;
font-weight: bold;
color: dodgerblue;
}
</style>
5.左侧导航栏components/Asid.vue
<!--左侧边栏-->
<template>
<nav>
<el-row class="tac">
<!-- 加入outer实现导航栏点击跳转,index项值为对应的路由-->
<el-menu
router
style="width: 200px ; min-height: 90vh"
active-text-color="#ffd04b"
class="el-menu-vertical-demo"
default-active="user"
text-color="black"
:default-openeds="['数据管理']"
>
<el-sub-menu index="系统管理">
<template #title>
<el-icon>
<user/>
</el-icon>
<span>系统管理</span>
</template>
<el-menu-item index="user">用户管理</el-menu-item>
<el-menu-item index="book">图书管理</el-menu-item>
</el-sub-menu>
<el-sub-menu index="数据管理">
<template #title>
<el-icon>
<grid/>
</el-icon>
<span>登录与注册</span>
</template>
<el-menu-item index="login">登录</el-menu-item>
<el-menu-item index="register">注册</el-menu-item>
</el-sub-menu>
</el-menu>
</el-row>
</nav>
</template>
<script>
import {Location, Grid, Document, Setting,User} from '@element-plus/icons-vue'
export default {
name: "Aside",
components: {
Location,
Grid,
Document,
Setting,
User
}
}
</script>
<style scoped>
</style>
6.布局框架Layout.vue
用以控制各个组件在页面中的布局
<!--用作框架-->
<template>
<div>
<el-config-provider :locale="locale">
<!-- 头部-->
<Header/>
<!-- 主体-->
<div style="display: flex">
<!-- 侧边栏-->
<Aside/>
<!-- 主体内容区域-->
<router-view style="flex: 1"/>
</div>
</el-config-provider>
</div>
</template>
<script>
import Header from "../components/Header";
import Aside from "../components/Aside";
import locale from "element-plus/lib/locale/lang/zh-cn";
export default {
name: "Layout",
components:{
Header,
Aside,
},
setup() {
return { locale };
}
}
</script>
<style scoped>
</style>
7.路由配置router/index.js
// 路由
import { createRouter, createWebHistory } from 'vue-router'
import Layout from "../layout/Layout";
const routes = [
{
path: '/', //当访问根路径时,会转向访问Layout界面
name: 'Layout',
component: Layout,
redirect: 'user',//重定向,访问根目录重定向到/home
// 嵌套路由配置
children: [
{ path: 'user', name: 'User', component:()=>import("../views/UserView") },
{ path: 'book', name: 'Book', component:()=>import("../views/BookView") },
]
},
{
path: '/login',
name: 'Login',
component: ()=>import("../views/LoginView")
},
{
path: '/register',
name: 'Register',
component: ()=>import("../views/RegisterView")
}
];
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
});
export default router
8.封装axios工具 utils/reques.js
// 封装axios
import axios from 'axios'
import router from "@/router";
const request = axios.create({
baseURL: '/api', // 注意!! 这里是全局统一加上了 '/api' 前缀,也就是说所有接口都会加上'/api'前缀在,页面里面写接口的时候就不要加 '/api'了,否则会出现2个'/api',类似 '/api/api/user'这样的报错,切记!!!
timeout: 5000
})
// request 拦截器
// 可以自请求发送前对请求做一些处理
// 比如统一加token,对请求参数统一加密
request.interceptors.request.use(config => {
config.headers['Content-Type'] = 'application/json;charset=utf-8';
// config.headers['token'] = user.token; // 设置请求头
//判断用户是否登录,没有登陆就跳转到login界面
let userJson = sessionStorage.getItem("user");
if(!userJson){
router.push("/login");
}
return config
}, error => {
return Promise.reject(error)
});
// response 拦截器
// 可以在接口响应后统一处理结果
request.interceptors.response.use(
response => {
let res = response.data;
// 如果是返回的文件
if (response.config.responseType === 'blob') {
return res
}
// 兼容服务端返回的字符串数据,如果返回的是String,就转换一下
if (typeof res === 'string') {
res = res ? JSON.parse(res) : res
}
return res;
},
error => {
console.log('err' + error) // for debug
return Promise.reject(error)
}
)
export default request
四、功能页面
1.登陆页面 views/LoginView.vue
<template>
<div class="contanier">
<div class="loginArea">
<h2 style="text-align: center;padding: 10px 0">系统登录</h2>
<el-form :model="loginForm" :rules="rules" ref="ruleForm">
<el-form-item label="用户名:" prop="username">
<el-input v-model.trim="loginForm.username" clearable></el-input>
</el-form-item>
<el-form-item label="密 码:" prop="password">
<el-input type="password" v-model.trim="loginForm.password" show-password clearable></el-input>
</el-form-item>
<el-form-item>
<el-button @click="loginBut('ruleForm')" style="width: 40%" type="primary">登 录</el-button>
<el-button @click="registerBut" style="width: 40%;margin-left: 80px" type="primary">注 册</el-button>
</el-form-item>
</el-form>
</div>
</div>
</template>
<script>
import {User, Key, Lock} from '@element-plus/icons-vue'
import request from "../utils/reques";
export default {
name: "LoginView",
components: {
User, Key, Lock
},
data() {
return {
loginForm: {
username: '',
password: '',
},
// 表单校验
rules: {
username: [
{required: true, message: '请输入账号', trigger: 'blur'},
{min: 3, max: 11, message: '长度在 3 到 5 个字符', trigger: 'blur'}
],
password: [
{required: true, message: '请输入密码', trigger: 'blur'},
{min: 3, max: 11, message: '长度在 3 到 5 个字符', trigger: 'blur'}
]
}
}
},
methods: {
//登录按钮
loginBut(formName) {
/**
* 配置axios请求,请求的url和请求参数
* .then()链式操作,前一步完成后,结果传入
*/
//表单校验
this.$refs[formName].validate((valid) => {
if (valid) {
request.post("/user/login", this.loginForm).then(res => {
if (res.code == "0") {
this.$message({
message: '登录成功o(* ̄▽ ̄*)ブ',
type: 'success'
});
//缓存用户信息,将登录的用户信息存入到sessionStorage
sessionStorage.setItem("user",JSON.stringify(res.data));
//登陆成功页面跳转,跳转到到根目录
this.$router.push("/")
} else {
this.$message({
message: "登录失败,,ԾㅂԾ,,"+res.msg,
type: 'error'
});
}
});
} else {
this.$message({
message: '请确认信息(ˉ▽ˉ;)...',
type: 'warning'
});
return false;
}
});
},
//注册按钮
registerBut() {
this.$router.push("/register")
},
}
}
</script>
<style scoped>
.contanier {
width: 100%;
height: 100%;
overflow: hidden;
}
.loginArea {
width: 400px;
border-radius: 30px;
background-clip: border-box;
margin: 200px auto;
padding: 15px 35px 15px 35px;
background: #d6e8ee;
border: 3px solid #e6fffc;
box-shadow: 0 0 30px #c5c7ff;
}
</style>
2.注册页面views/RegisterView.vue
<template>
<div class="contanier">
<div class="loginArea">
<h2 style="text-align: center;padding: 10px 0">用户注册</h2>
<el-form :model="registerForm" :rules="rules" ref="ruleForm">
<el-form-item label="用户名:" prop="username">
<el-input v-model.trim="registerForm.username" clearable></el-input>
</el-form-item>
<el-form-item label="密 码:" prop="password">
<el-input type="password" v-model.trim="registerForm.password" show-password clearable></el-input>
</el-form-item>
<el-form-item label="确认密码:" prop="againPassword">
<el-input type="password" v-model.trim="registerForm.againPassword" show-password
clearable></el-input>
</el-form-item>
<el-form-item label="昵 称:" prop="nickname">
<el-input type="text" v-model.trim="registerForm.nickname" clearable></el-input>
</el-form-item>
<el-form-item label="年 龄:" prop="age">
<el-input type="number" v-model.trim="registerForm.age" clearable></el-input>
</el-form-item>
<el-form-item label="性 别:" prop="sex">
<el-checkbox-group v-model="registerForm.sex">
<el-radio label="男" v-model="registerForm.sex"/>男
<el-radio label="女" v-model="registerForm.sex"/>女
<el-radio label="未知" v-model="registerForm.sex"/>未知
</el-checkbox-group>
</el-form-item>
<el-form-item label="地 址:" prop="address">
<el-input v-model.lazy="registerForm.address" type="textarea"></el-input>
</el-form-item>
<el-form-item>
<el-button @click="registerSure('ruleForm')" style="width: 100%" type="primary">确 认</el-button>
</el-form-item>
</el-form>
</div>
</div>
</template>
<script>
import {User, Key, Lock} from '@element-plus/icons-vue'
import request from "../utils/reques";
export default {
name: "RegisterView",
components: {
User, Key, Lock
},
data() {
return {
registerForm: {
username: '',
password: '',
againPassword: '',
nickname: '',
age: '',
sex: '',
address: ''
},
// 表单校验
rules: {
username: [
{required: true, message: '请输入账号', trigger: 'blur'},
{min: 2, max: 11, message: '长度在 3 到 5 个字符', trigger: 'blur'}
],
password: [
{required: true, message: '请输入密码', trigger: 'blur'},
{min: 3, max: 11, message: '长度在 3 到 5 个字符', trigger: 'blur'}
],
againPassword: [
{required: true, message: '请再次输入密码', trigger: 'blur'},
{min: 3, max: 11, message: '长度在 3 到 5 个字符', trigger: 'blur'}
],
nickname: [
{required: true, message: '请输入昵称', trigger: 'blur'},
{min: 2, max: 11, message: '长度在 3 到 5 个字符', trigger: 'blur'}
],
age: [
{required: true, message: '请输入年龄', trigger: 'blur'},
{min: 1, max: 3, message: '长度在 3 到 5 个字符', trigger: 'blur'}
],
sex: [
{required: true, message: '请选择性别', trigger: 'change'}
],
address: [
{required: true, message: '请输入地址', trigger: 'blur'},
{min: 2, message: '长度要大于2个字符', trigger: 'blur'}
]
}
}
},
methods: {
//登录按钮
registerSure(formName) {
if (this.registerForm.password != this.registerForm.againPassword) {
this.$message({
message: '两次密码不一致(ˉ▽ˉ;)..',
type: 'warning'
});
return;
}
/**
* 配置axios请求,请求的url和请求参数
* .then()链式操作,前一步完成后,结果传入
*/
//表单校验
this.$refs[formName].validate((valid) => {
if (valid) {
request.post("/user/register", this.registerForm).then(res => {
if (res.code == "0") {
this.$message({
message: '注册成功o(* ̄▽ ̄*)ブ',
type: 'success'
});
//注册成功,跳转到登陆界面
this.$router.push("/login")
} else {
this.$message({
message: "注册失败,,ԾㅂԾ,," + res.msg,
type: 'error'
});
}
});
} else {
this.$message({
message: '请确认信息(ˉ▽ˉ;)...',
type: 'warning'
});
return false;
}
});
},
}
}
</script>
<style scoped>
.contanier {
width: 100%;
height: 100%;
overflow: hidden;
}
.loginArea {
width: 400px;
border-radius: 30px;
background-clip: border-box;
margin: 200px auto;
padding: 15px 35px 15px 35px;
background: #d6e8ee;
border: 3px solid #e6fffc;
box-shadow: 0 0 30px #c5c7ff;
}
</style>
3.用户管理页面views/UserView.vue
<template>
<div style="width: 100%">
<!-- 操作区域-->
<div style="margin: 10px 5px">
<el-button type="primary" @click="addUser">新增</el-button>
<el-button type="primary" @click="importUser">导入</el-button>
<el-button type="primary" @click="exportUser">导出</el-button>
</div>
<!-- 搜索区域-->
<div style="margin: 10px 5px">
<el-input v-model="search" clearable type="text" placeholder="请输入关键字" style="width: 200px"></el-input>
<el-button @click="load" type="primary" style="margin: 0 5px">
<el-icon>
<search/>
</el-icon>
</el-button>
</div>
<el-table v-model:data="tableData"
stripe
border
style="width: 100%"
>
<el-table-column prop="id" label="id"/>
<el-table-column prop="username" label="用户名"/>
<el-table-column prop="nickname" label="昵称"/>
<el-table-column prop="age" label="年龄"/>
<el-table-column prop="sex" label="性别"/>
<el-table-column prop="address" label="地址"/>
<el-table-column label="操作">
<template #default="scope">
<el-button size="mini" @click="updateUser(scope.row)">编辑</el-button>
<el-popconfirm title="你确定要删除该数据吗?" @confirm="deleteUser(scope.row.id)">
<template #reference>
<el-button size="mini" type="danger">删除</el-button>
</template>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<div class="demo-pagination-block">
<el-pagination
v-model:currentPage="currentPage"
v-model:page-size="pageSize"
:page-sizes="[5, 10, 20]"
:small="small"
:disabled="disabled"
:background="background"
layout="total, sizes, prev, pager, next, jumper"
:total="totals"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
<div>
<el-dialog
v-model="dialogVisible"
title="新增数据"
width="60%">
<el-form :model="form" :rules="rules" ref="ruleForm" label-width="140px">
<el-form-item label="用户名:" prop="username">
<el-input v-model.trim="form.username" style="width: 80%"/>
</el-form-item>
<el-form-item label="昵 称:" prop="nickname">
<el-input v-model.trim="form.nickname" style="width: 80%"/>
</el-form-item>
<el-form-item label="密 码:" prop="password">
<el-input type="password" show-password v-model.trim="form.password" style="width: 80%"/>
</el-form-item>
<el-form-item label="年 龄:" prop="age">
<el-input type="number" v-model.trim="form.age" style="width: 80%"/>
</el-form-item>
<el-form-item label="性 别:" prop="sex">
<el-checkbox-group v-model="form.sex">
<el-radio label="男" v-model="form.sex"/>男
<el-radio label="女" v-model="form.sex"/>女
<el-radio label="未知" v-model="form.sex"/>未知
</el-checkbox-group>
</el-form-item>
<el-form-item label="地址:" prop="address">
<el-input v-model.lazy="form.address" type="textarea" style="width: 80%"></el-input>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="addFormSave('ruleForm')">确定</el-button>
</span>
</template>
</el-dialog>
</div>
</div>
</template>
<script>
import {Search} from '@element-plus/icons-vue'
import request from "../utils/reques";
export default {
name: 'HomeView',
components: {
Search
},
data() {
return {
search: '',
totals: 0,
currentPage: '',
pageSize: 10,
dialogVisible: false,
tableData: [],
form: {
username: '',
password: '',
nickname: '',
age: 0,
sex: '',
address: '',
},
// 表单校验
rules: {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 3, max: 11, message: '长度在 3 到 5 个字符', trigger: 'blur' }
],
nickname: [
{ required: true, message: '请输入昵称', trigger: 'blur' },
{ min: 3, max: 11, message: '长度在 3 到 5 个字符', trigger: 'blur' }
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 3, max: 11, message: '长度在 3 到 5 个字符', trigger: 'blur' }
],
age: [
{ required: true, message: '请输入年龄', trigger: 'blur' }
],
sex: [
{required: true, message: '请选择性别', trigger: 'change' }
],
address: [
{ required: true, message: '请输入地址', trigger: 'blur' },
]
}
}
},
created() {
this.load()
},
methods: {
// 加载初始数据
load(){
request.get("user/",{
params:{
pageNum: this.currentPage,
pageSize: this.pageSize,
search: this.search
}
}).then(res => {
this.tableData = res.data.records;
this.totals = res.data.total;
})
},
//新增数据按钮
addUser() {
this.dialogVisible = true;
this.form = {};
},
// 点击新增按钮后在弹出的表单点击确定按钮
addFormSave(formName) {
/**
* 配置axios请求,请求的url和请求参数
* .then()链式操作,前一步完成后,结果传入
*/
//表单校验
this.$refs[formName].validate((valid) => {
if (valid) {
request.post("/user",this.form).then(res=>{
if (res.code=="0"){
this.$message({
message: '操作成功o(* ̄▽ ̄*)ブ',
type: 'success'
});
this.dialogVisible = false;
this.load();
}else {
this.$message({
message: '操作失败,,ԾㅂԾ,,',
type: 'error'
});
this.dialogVisible = false;
}
});
} else {
this.$message({
message: '请确认表单(ˉ▽ˉ;)...',
type: 'warning'
});
return false;
}
});
},
//删除数据按钮
deleteUser(userId) {
request.delete("user/"+userId,).then(res =>{
if (res.code=="0"){
this.$message({
message: '操作成功o(* ̄▽ ̄*)ブ',
type: 'success'
});
this.load();
}else {
this.$message({
message: '操作失败,,ԾㅂԾ,,',
type: 'error'
});
}
});
},
//编辑信息按钮
updateUser(row) {
this.form = JSON.parse(JSON.stringify(row));
this.dialogVisible = true;
this.load();
},
//导出数据按钮
exportUser() {
this.load();
},
//导入数据按钮
importUser() {
},
// 改变当前每页数据个数触发
handleSizeChange() {
this.load();
},
// 改变当前页码触发
handleCurrentChange() {
this.load();
}
}
}
</script>
五、一些技术点
1.前端解决跨域访问问题 vue.config.js文件
// 解决跨域访问
// 跨域配置
module.exports = {
devServer: { //记住,别写错了devServer//设置本地默认端口 选填
port: 8089,
proxy: { //设置代理,必须填
'/api': { //设置拦截器 拦截器格式 斜杠+拦截器名字,名字可以自己定
target: 'http://localhost:8090', //代理的目标地址
changeOrigin: true, //是否设置同源,输入是的
pathRewrite: { //路径重写
'/api': '' //选择忽略拦截器里面的内容
}
}
}
}
}
2.使用 element-puls icon图标
引入icon:
//{Location, Grid, Document, Setting,User}为所使用的icon图标名称
import {Location, Grid, Document, Setting,User} from '@element-plus/icons-vue' export default { name: "Aside", components: { Location, Grid, Document, Setting, User } }
使用:
<el-icon> <user/> </el-icon>
3.点击导航栏选项跳转视图页面
在导航栏属性加入 router
选项的 index值为配置好的路由
4.前端登录状态拦截 utils/reques.js 文件
六、后端工程
1.SpringBoot工程结构
2.Maven文件/依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.7</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springbootdemo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<!-- web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<!-- MybatisPlus依赖-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
3.application.yml配置文件
server:
port: 8090
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/springboot-vue
username: root
password: 123456
4.实体类User
package com.example.demo.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/**
* 用户实体类
*/
@TableName("user")//与数据库表明对应
@Data//lombok 的Data注解,不用写get/set方法
public class User {
@TableId(type = IdType.AUTO)//主键id自动生成
private Integer id;
private String username;
private String password;
private String nickname;
private Integer age;
private String sex;
private String address;
}
5.封装统一返回对象Result
package com.example.demo.pojo;
/**封装的统一返回对象
* @param <T>
*/
public class Result<T> {
private String code;
private String msg;
private T data;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public Result() {
}
public Result(T data) {
this.data = data;
}
public static Result success() {
Result result = new Result<>();
result.setCode("0");
result.setMsg("成功");
return result;
}
public static <T> Result<T> success(T data) {
Result<T> result = new Result<>(data);
result.setCode("0");
result.setMsg("成功");
return result;
}
public static Result error(String code, String msg) {
Result result = new Result();
result.setCode(code);
result.setMsg(msg);
return result;
}
public static Result error() {
Result result = new Result<>();
result.setCode("1");
result.setMsg("失败");
return result;
}
}
6.UserMapper层
package com.example.demo.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.pojo.User;
import org.springframework.stereotype.Controller;
/**
* User的持久层
*/
@Controller
//继承BaseMapper接口
public interface UserMapper extends BaseMapper<User> {
}
7.UserController控制层
package com.example.demo.controller;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.mapper.UserMapper;
import com.example.demo.pojo.Result;
import com.example.demo.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
/**
* User控制器
*/
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserMapper userMapper;
/**
* 登陆方法
* @param user
* @return
*/
@PostMapping("/login")
public Result login(@RequestBody User user){
//在数据库中查询与传来的用户名和密码系统的数据
User res = userMapper.selectOne(Wrappers.<User>lambdaQuery().eq(User::getUsername,user.getUsername()).eq(User::getPassword,user.getPassword()));
if (res==null){
return Result.error("-1","用户名或密码错误");
}else {
return Result.success(res);
}
}
/**
* 注册方法
* @param user
* @return
*/
@PostMapping("/register")
public Result Register(@RequestBody User user){
//在数据库中查询与传来的用户名和密码系统的数据
User res = userMapper.selectOne(Wrappers.<User>lambdaQuery().eq(User::getUsername,user.getUsername()));
if (res!=null){
return Result.error("-1","用户名重复");
}else {
userMapper.insert(user);
return Result.success(res);
}
}
/**
* 新增数据操作
*
* @param user
* @return
*/
@Transactional
@PostMapping
//@RequestBody注解,将传入的json数据转换为对象
public Result saveUser(@RequestBody User user) {
if (user.getId() != null) {
userMapper.updateById(user);
} else {
userMapper.insert(user);
}
return Result.success();
}
/**
* 根据ID删除数据
* @param
* @return
*/
@Transactional
@DeleteMapping("/{userId}")
public Result deleteUser(@PathVariable Integer userId){
userMapper.deleteById(userId);
return Result.success();
}
/**
* 分页查询User表
* 根据前端传来的搜索值进行模糊擦查询
*
* @param pageNum
* @param pageSize
* @param search
* @return
*/
@GetMapping
public Result findPage(@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize,
@RequestParam(defaultValue = "") String search) {
// Wrappers.<User>lambdaQuery().like(User::getNickname,search) 模糊查询,根据前端传来的search
Page<User> page = userMapper.selectPage(new Page<>(pageNum, pageSize), Wrappers.<User>lambdaQuery().like(User::getNickname, search));
return Result.success(page);
}
}
七、后端技术点
1.MybatisPlus分页插件配置
package com.example.demo.common.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* mybatis-plus 分页插件
*/
@Configuration
//扫描mapper文件包,加入ioc容器,不用在写@Mapper
@MapperScan("com.example.demo.mapper")
public class MybatisPlusConfig {
/**
* 分页插件
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
版权归原作者 白 免 所有, 如有侵权,请联系我们删除。