前后端分离 – 深入浅出Spring Boot + Vue实现员工管理系统 Vue如此简单~
引言
Hello,我是Bug终结者,一名热爱后端Java的风趣且幽默的程序员~ 终于等到幸运的你~
快来发现我的宇宙哦~
本周第一篇博文是一个基于Spring Boot+Vue实现员工管理系统的项目
在此之前,我们先看看什么是Vue
Vue详解
小猿疑问:什么是Vue呢,能干什么,为什么要用呢?
小王回答说:vue是一个渐进式基于JavaScript的框架,使用它,可大大提高前端的灵活性与扩展性,更加方便的开发前端工程
有点官方了这话,简单来说
vue就是一个高级的JavaScript,要想使用vue,前提必须掌握三大技术,HTML, CSS, JavaScript
小猿问,哪为什么要使用它呢
因为用的人多,技术火爆,市场需要,所以使用。
项目简介
开发一个基于Spring Boot + Vue的前后端分离员工管理系统项目,完成增、删、改、列表、多条件、分页的功能
开发环境
后端:Spring Boot + MyBatis + Maven
前端:Vue + ElementUI
工具:前端使用WebStorm,后端使用IDEA
ElementUI为何物?
ElementUI是饿了么出品的一个组件,使用它,可使界面美观,开发效率提升
elementUI是基于vue实现的一套不依赖业务的UI组件库,提供了丰富的PC端组件,减少用户对常用组件的封装,降低了开发的难易程度。
看这么就累了吧,来张图放松下~
解乏了吧~ 😎
言归正传~
广播站
CSDN博客之星参选博主:Bug终结者.
链接:https://blog.csdn.net/weixin_45526437?spm=1001.2101.3001.5343
五星好评,您的每一分对我都贡献巨大,感谢您投的每一票
再次感谢您的投票,谢谢!
项目风格
请求方式统一为Post请求,目的是保证安全性
规范了接口层统一返回格式为ResultBean,详细如:
统一返回格式风格类,ResultBean
packagecom.wanshi.bean;publicclassResultBean<C>{privateInteger code;privateString msg;privateC data;privateResultBean(Integer code,String msg,C data){this.code = code;this.msg = msg;this.data = data;}publicstaticResultBeancreate(Integer code,String msg,Object data){ResultBean res =newResultBean(code, msg, data);return res;}publicIntegergetCode(){return code;}publicvoidsetCode(Integer code){this.code = code;}publicStringgetMsg(){return msg;}publicvoidsetMsg(String msg){this.msg = msg;}publicCgetData(){return data;}publicvoidsetData(C data){this.data = data;}}
数据表
t_employee
CREATETABLE`t_employee`(`noid`char(32)NOTNULL,`emp_name`varchar(32)NOTNULLCOMMENT'员工姓名',`emp_age`intDEFAULTNULLCOMMENT'员工年龄',`emp_sex`tinyintDEFAULTNULLCOMMENT'员工性别,1:男,2:女',`emp_salary`decimal(10,2)DEFAULTNULLCOMMENT'员工工资',`emp_address`varchar(32)DEFAULTNULLCOMMENT'员工住址',`join_time`dateDEFAULTNULLCOMMENT'入职日期',PRIMARYKEY(`noid`))ENGINE=InnoDBDEFAULTCHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
效果图
核心源码
前端源码
新建EmployeeList.vue文件
<template>
<div class="box-main2 box-heigt100">
<div class="box-right1 box-heigt100">
<div class="box-right1-in box-heigt100 scrollbar1">
<div class="box-search" v-if="true">
<div class="box-search">
<div style="width:140px;padding-right:10px;">
<el-input @keydown.enter.native="clkBtnSearch" @clear="clkBtnSearch" clearable
size="mini" v-model="searchInfo.searchKey" placeholder="员工名称"></el-input>
</div>
<div style="width:60px;">
<el-button size="mini" @click="clkBtnSearch" type="primary">搜索</el-button>
</div>
<div>
<el-button size="mini" type="warning" @click="clkBtnAdd">新增</el-button>
</div>
</div>
</div>
<div class="box-table1 box-heigt100 scrollbar1">
<el-table
:data="tbEmployeePage.list"
border
style="width: 100%; text-align: center">
<el-table-column type="index" label="序号" width="50"></el-table-column>
<el-table-column prop="emp_name" label="姓名" width="170"/>
<el-table-column prop="emp_age" label="年龄" width="120"/>
<el-table-column label="性别" width="120">
<template slot-scope="scope">
//显示过滤后的性别
{{scope.row.emp_sex|filterSex}}
</template>
</el-table-column>
<el-table-column prop="emp_salary" label="薪资" width="150"/>
<el-table-column prop="emp_address" label="住址" width="150"/>
<el-table-column prop="str_join_time" label="入职日期"/>
<el-table-column
label="操作"
width="200">
<template slot-scope="scope">
<el-button @click="clkBtnEdit(scope.row)" type="warning" size="small">编辑</el-button>
<el-button type="danger" size="small" @click="clkBtnDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="box-page1">
<el-pagination background :current-page="tbEmployeePage.pageNum" :page-size="tbEmployeePage.pageSize" :total="tbEmployeePage.total"
layout="total,prev,pager,next"
@current-change="chgPageNum">
</el-pagination>
</div>
</div>
<el-dialog title="保存" class="dialog1"
:show-close="false" :close-on-click-modal="false"
:visible.sync="showAddBuzhiZuoyeDialog">
<div>
<div class="box-content2">
<div class="box-table2" >
<el-form size="mini" ref="student" label-width="120px">
<el-form-item label="员工姓名">
<el-input v-model="employee.emp_name"></el-input>
</el-form-item>
<el-form-item label="员工年龄">
<el-input v-model="employee.emp_age" type="number" min="0"></el-input>
</el-form-item>
<el-form-item label="员工性别">
<el-radio-group v-model="employee.emp_sex">
<el-radio :label="1">男</el-radio>
<el-radio :label="2">女</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="员工薪资">
<el-input v-model="employee.emp_salary"></el-input>
</el-form-item>
<el-form-item label="员工住址">
<el-input v-model="employee.emp_address"></el-input>
</el-form-item>
</el-form>
</div>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button size="mini" type="primary" @click="clkBtnSave">确 定</el-button>
<el-button size="mini" @click="showAddBuzhiZuoyeDialog = false">取 消</el-button>
</span>
</el-dialog>
</div>
</div>
</template>
<script>
import request from '@/common/utils/request';
export default {
computed: {
},
data() {
return {
inited: false,
searchInfo:{searchKey:''},
showAddBuzhiZuoyeDialog: false,
tbEmployeePage: {pageNum: 1, pageSize: 12,list: []},
employee:{}
};
},
watch: {
'$route.path': {
handler: function (newVal) {
if (newVal == '/employee-list') {
this._initData();
}
}, immediate: true
}
},
mounted() {
this._initData();
},
methods: {
_initData() {
if (this.inited) {
return;
}
this.inited = true;
this.getEmployeeList();
},
clkBtnAdd() {
this.employee = {};
this.showAddBuzhiZuoyeDialog = true;
},
clkBtnEdit(row) {
console.log(row);
this.employee = row;
this.showAddBuzhiZuoyeDialog = true;
},
//删除记录
clkBtnDelete(row) {
console.log(row);
this.$confirm("您确信要删除此记录吗", "提示").then(() => {
let url1 = this.settings.apiUrl + '/employee/delete';
let data = {noid: row.noid};
request.post(url1, data).then((res) => {
if (res.code === 0) {
this.getEmployeeList();
this.$message("删除成功~");
}
})
})
},
//保存信息,将新增和修改合成一个方法进行处理
clkBtnSave() {
let url1 = this.settings.apiUrl + '/employee/save';
let data = this.employee;
request.post(url1, data).then((res) => {
if (res.code === 0) {
this.$message("保存成功~");
this.getEmployeeList();
this.showAddBuzhiZuoyeDialog = false;
}
})
},
//获取员工集合信息
getEmployeeList() {
let url1 = this.settings.apiUrl + '/employee/page';
let d1 = {};
d1.pageNum = this.tbEmployeePage.pageNum;
d1.pageSize = this.tbEmployeePage.pageSize;
d1.searchKey = this.searchInfo.searchKey;
request.post(url1, d1).then((d1r) => {
console.log(d1r)
if (d1r.code == 0) {
console.log(d1r.data);
this.tbEmployeePage = d1r.data;
}
})
},
//点击分页时重新获取员工信息
chgPageNum(currPageNum) {
this.tbEmployeePage.pageNum = currPageNum;
this.getEmployeeList();
},
//搜索时重新调用获取员工信息
clkBtnSearch() {
this.getEmployeeList();
}
},
//过滤器,将数字转换为文字
filters:{
filterSex(srcVal){
if(srcVal==1){
return '男';
}
if(srcVal==2){
return '女';
}
return '未知';
}
}
};
</script>
<style lang="scss" scoped="scoped">
.box-page1 {
display: flex;
justify-content: flex-end;
}
.box-main2 {
display: flex;
.box-right1 {
flex: 7;
padding: 10px;
.box-right1-in {
display: flex;
flex-direction: column;
.box-search {
display: flex;
padding: 10px 10px 10px 0;
}
}
}
}
</style>
添加EmployeeList.vue路由与左侧列表显示
添加路由index.js
{
path:'/employee-list',
meta:{pageTitle:'员工列表', leftMenuIndex:'employee-list'},component:()=>import('@/views/EmployeeList')},
添加左侧菜单显示LeftMenu.vue
<el-menu-item index="employee-list" @click.native="clkItem('/employee-list')">
<i class="menuitem-icon iconfont icon-user-delete"></i>
<span class="menuitem-text" slot="title">员工列表</span>
</el-menu-item>
至此前端页面完美显示
后端源码
EmployeeController类
packagecn.zhongtie.controller;importcn.zhongtie.bean.ResultBean;importcn.zhongtie.bean.entity.Employee;importcn.zhongtie.service.EmployeeService;importcom.github.pagehelper.PageInfo;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.web.bind.annotation.*;@RestController@CrossOrigin@RequestMapping("/employee")publicclassEmployeeController{@AutowiredprivateEmployeeService employeeService;@PostMapping("/page")publicResultBean<PageInfo<Employee>>page(@RequestBodyEmployee param){ResultBean<PageInfo<Employee>> res = employeeService.page(param);return res;}@PostMapping("/save")publicResultBean<Integer>save(@RequestBodyEmployee param){ResultBean<Integer> res = employeeService.save(param);return res;}@PostMapping("/delete")publicResultBean<Integer>delete(@RequestBodyEmployee param){ResultBean<Integer> res = employeeService.delete(param);return res;}}
EmployeeService类
packagecn.zhongtie.service;importcn.zhongtie.bean.ResultBean;importcn.zhongtie.bean.entity.Employee;importcn.zhongtie.mapper.EmployeeMapper;importcn.zhongtie.utils.PbSecretUtils;importcom.github.pagehelper.PageHelper;importcom.github.pagehelper.PageInfo;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;importjava.text.SimpleDateFormat;importjava.util.Date;importjava.util.List;@ServicepublicclassEmployeeService{@AutowiredprivateEmployeeMapper employeeMapper;privateSimpleDateFormat sdf =newSimpleDateFormat("yyyy-MM-dd");publicResultBean<PageInfo<Employee>>page(Employee param){if(param.getPageNum()==null){
param.setPageNum(1);}PageHelper.startPage(param.getPageNum(), param.getPageSize());List<Employee> employeeList = employeeMapper.page(param);for(Employee employee : employeeList){if(employee !=null){
employee.setStr_join_time(sdf.format(employee.getJoin_time()));}}PageInfo<Employee> pageInfo =newPageInfo<>(employeeList);returnResultBean.create(0,"success", pageInfo);}publicResultBean<Integer>save(Employee param){if(param.getNoid()!=null){
employeeMapper.update(param);}else{
param.setJoin_time(newDate());
param.setNoid(PbSecretUtils.uuid());
employeeMapper.insert(param);}returnResultBean.create(0,"success",null);}publicResultBean<Integer>delete(Employee param){
employeeMapper.delete(param);returnResultBean.create(0,"success",null);}}
博主寄语
至此,系统到此完美结束,该案例通俗易懂,详细一步步带入,通过本案例,可提高你的学习能力以及训练自己的逻辑思维能力,认真学习的你很耀眼,相信你的技术一定会有一个质的飞跃,加油,努力练习,祝你成为你想要成为的人!
若在本项目中遇到技术难题,可在下方评论区留言或私信我,授人以鱼不如授人以渔
如果你觉得博主写的不错的话,不妨给个一键三连,点击下方小拳头即可一键三连。
版权归原作者 Bug终结者. 所有, 如有侵权,请联系我们删除。