springboot+vue物业管理系统
一、课程技术
1、前端基于vue-admin-template开发,学会使用vue的动态菜单、动态路由、按钮权限的开发;
2、后端基于springboot、spring security开发,学会spring security在前后端分离项目中的开发;
3、课程从0开始手把手搭建项目,vue-admin-template动态菜单、动态路由、按钮权限判断;spring boot、spring security、token在前后端分离项目中的使用;
二、代码演示
package com.itmk.utils;import com.itmk.status.StatusCode;/ * 数据返回工具类 */public class ResultUtils { / * 无参数返回 * @return */ public static ResultVo succcess() { return Vo(null, StatusCode.SUCCESS_CODE, null); } public static ResultVo success(String msg){ return Vo(msg,StatusCode.SUCCESS_CODE,null); } / * 返回带参数 * @param msg * @param data * @return */ public static ResultVo success(String msg,Object data){ return Vo(msg,StatusCode.SUCCESS_CODE,data); } public static ResultVo success(String msg,int code,Object data){ return Vo(msg,code,data); } public static ResultVo Vo(String msg, int code, Object data) { return new ResultVo(msg, code, data); } / * 错误返回 * @return */ public static ResultVo error(){ return Vo(null,StatusCode.ERROR_CODE,null); } public static ResultVo error(String msg){ return Vo(msg,StatusCode.ERROR_CODE,null); } public static ResultVo error(String msg,int code,Object data){ return Vo(msg,code,data); } public static ResultVo error(String msg,int code){ return Vo(msg,code,null); } public static ResultVo error(String msg,Object data){ return Vo(msg, StatusCode.ERROR_CODE,data); }}
1、新建员工实体```jspackage com.itmk.web.user.entity;import com.baomidou.mybatisplus.annotation.IdType;import com.baomidou.mybatisplus.annotation.TableId;import com.baomidou.mybatisplus.annotation.TableName;import java.io.Serializable;/ * 员工表 */@Data@TableName("sys_user")public class User implements Serializable { //设置主键自增 @TableId(type= IdType.AUTO) private Long userId; //登录名 private String loginName; //登录密码 private String password; //姓名 private String userName; //电话 private String phone; //性别 0:女 1:男 private String sex; //身份证 private String idCard; //是否是管理员 0:不是 1:是 private String isAdmin; //0:在职 1:离职 private String status; //0:启用 1:禁用 private String isUsed;}``` 2、新建员工mapper层在web模块下新建com.itmk.web.user.mapper包,然后新建 UserMapper接口```jsUserMapper接口需要继承 BaseMapper,继承BaseMapper的好处是我们可以直接使用Mybatis -Plus提供的通用CRUD方法``````jspackage com.itmk.web.user.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;import com.itmk.web.user.entity.User;/ * 员工数据访问层 */public interface UserMapper extends BaseMapper {}``` 3、新建员工mapper层映射文件 在web模块的resources资源文件夹下新建mapper文件目录,然后新建UserMapper.xml,如下所示```js``` 4、新建员工service层4.1.在itmk-base-web模块新建com.itmk.web.user.service包,然后新建UserService接口,并继承IService接口```jspackage com.itmk.web.user.service;import com.baomidou.mybatisplus.extension.service.IService;import com.itmk.web.user.entity.User;public interface UserService extends IService { //查询用户列表 IPage list(UserParm parm);}```4.2在itmk-base-web模块新建com.itmk.web.user.service.impl包,然后新建UserServiceImpl类```jspackage com.itmk.web.user.service.impl;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;import com.itmk.web.user.entity.User;import com.itmk.web.user.mapper.UserMapper;import com.itmk.web.user.service.UserService;import org.springframework.stereotype.Service;/ * 继承 ServiceImpl 的好处是 可以使用 Mybatis-Plus的通用CRUD方法, * implements UserService的原因,是如果 Mybatis-Plus的通用CRUD方法不够用,或者不符合开发需求的 * 时候,需要扩展我们自己定义的方法 * @Service 表示把该类交给spring 进行管理,我们就可以在其他类里面直接注入使用 */@Servicepublic class UserServiceImpl extends ServiceImpl implements UserService { @Override public IPage list(UserParm parm) { //构建分页对象 IPage page = new Page(); page.setSize(parm.getPageSize()); page.setCurrent(parm.getCurrentPage()); //构造前端查询条件 QueryWrapper query = new QueryWrapper(); if(StringUtils.isNotEmpty(parm.getPhone())){ query.lambda().like(User::getPhone,parm.getPhone()); } if(StringUtils.isNotEmpty(parm.getUserName())){ query.lambda().like(User::getUserName,parm.getUserName()); } return this.page(page,query); }}``` 5、新建员工controller控制器在itmk-base-web模块新建com.itmk.web.user.controller包,然后新建 UserController控制器```jspackage com.itmk.web.user.controller;import com.baomidou.mybatisplus.core.metadata.IPage;import com.itmk.utils.ResultUtils;import com.itmk.utils.ResultVo;import com.itmk.web.user.entity.User;import com.itmk.web.user.entity.UserParm;import com.itmk.web.user.service.UserService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;/ * 员工管理控制器 */@RestController@RequestMapping("/api/user")public class UserController { @Autowired private UserService userService; / * 新增用户 * @param user * @return */ @PostMapping public ResultVo addUser(@RequestBody User user){ boolean save = userService.save(user); if(save){ return ResultUtils.success("新增用户成功"); } return ResultUtils.error("新增用户失败"); } / * 编辑用户 * @param user * @return */ @PutMapping public ResultVo editUser(@RequestBody User user){ boolean b = userService.updateById(user); if(b){ return ResultUtils.success("编辑用户成功"); } return ResultUtils.error("编辑用户失败"); } / * 删除用户 * @param userId * @return */ @DeleteMapping public ResultVo deleteUser(@RequestParam("userId") Long userId){ boolean b = userService.removeById(userId); if(b){ return ResultUtils.success("删除用户成功"); } return ResultUtils.error("删除用户失败"); } / * 获取用户列表 * @param parm * @return */ @GetMapping("/list") public ResultVo list(UserParm parm){ IPage list = userService.list(parm); return ResultUtils.success("查询成功",list); }}``````jspackage com.itmk.web.user.entity;import lombok.Data;@Datapublic class UserParm { //页容量 private Long pageSize; //当前页 private Long curentPage; //姓名 private String userName; //电话 private String phone;}``` 6、新建启动类在itmk-base-web模块的com.itmk包下新建 WyglApplication启动类```jspackage com.itmk;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class WyglApplication { public static void main(String[] args) { SpringApplication.run(WyglApplication.class,args); }}```# 第8讲 员工管理列表制作element ui官网```jshttps://element.eleme.cn/#/zh-CN/component/installation``` 1、页面完整代码```js 查询 新增 import { getUserListApi } from "@/api/user";export default { //所有需要在页面上展示的数据,都需要显示的在data里面进行定义 data() { return { //表格的高度 tableHeight: 0, //搜索框数据绑定 parms: { phone: "", userName: "", pageSize: 10, curentPage: 1, total: 0, }, //表格数据 tableList: [], }; }, created() { this.getUserList(); }, mounted() { this.$nextTick(() => { this.tableHeight = window.innerHeight - 210; }); }, methods: { async getUserList() { let res = await getUserListApi(this.parms); if (res.code == 200) { this.tableList = res.data.records; } console.log(res); }, //页容量改变的时候触发 sizeChange(val) { console.log(val); }, //页数改变的时候触发 currentChange(val) { console.log(val); }, },};``` 2、新建http.js```jsimport axios from 'axios'import { MessageBox, Message } from 'element-ui'import store from '@/store'import { getToken } from '@/utils/auth'import qs from 'qs'// create an axios instance//创建一个axios实例const service = axios.create({ baseURL: process.env.VUE_APP_BASE_API_PRO, // url = base url + request url // withCredentials: true, // send cookies when cross-domain requests timeout: 5000 // request timeout})// request interceptor//请求发送之前的拦截器service.interceptors.request.use( config => { // do something before request is sent //如果token存在,把token添加到请求的头部 if (store.getters.token) { // let each request carry token // ['X-Token'] is a custom headers key // please modify it according to the actual situation config.headers['X-Token'] = getToken() } return config }, error => { // do something with request error console.log(error) // for debug return Promise.reject(error) })// response interceptor//请求返回之后的处理service.interceptors.response.use( / * If you want to get http information such as headers or status * Please return response => response */ / * Determine the request status by custom code * Here is just an example * You can also judge the status by HTTP Status Code */ response => { const res = response.data // if the custom code is not 20000, it is judged as an error. if (res.code !== 200) { Message({ message: res.msg || '服务器出错', type: 'error', duration: 5 * 1000 }) // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired; if (res.code === 50008 || res.code === 50012 || res.code === 50014) { // to re-login MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', { confirmButtonText: 'Re-Login', cancelButtonText: 'Cancel', type: 'warning' }).then(() => { store.dispatch('user/resetToken').then(() => { location.reload() }) }) } return Promise.reject(new Error(res.msg || '服务器出错')) } else { return res } }, error => { console.log('err' + error) // for debug Message({ message: error.msg || '服务器出错!', type: 'error', duration: 5 * 1000 }) return Promise.reject(error) })//请求方法const http = { post(url, params) { return service.post(url, params, { transformRequest: [(params) => { return JSON.stringify(params) }], headers: { 'Content-Type': 'application/json' } }) }, put(url, params) { return service.put(url, params, { transformRequest: [(params) => { return JSON.stringify(params) }], headers: { 'Content-Type': 'application/json' } }) }, //parm => {id:10} // http://localhost:8089/api/user?id=10 get(url, params) { return service.get(url, { params: params, paramsSerializer: (params) => { return qs.stringify(params) } }) }, //parm => {id:10} // http://localhost:8089/api/user/10 getRestApi(url, params) { let _params if (Object.is(params, undefined || null)) { _params = '' } else { _params = '/' for (const key in params) { console.log(key) console.log(params[key]) // eslint-disable-next-line no-prototype-builtins if (params.hasOwnProperty(key) && params[key] !== null && params[key] !== '') { _params += `${params[key]}/` } } //去掉参数最后一位? _params = _params.substr(0, _params.length - 1) } console.log(_params) if (_params) { return service.get(`${url}${_params}`) } else { return service.get(url) } }, //parm => {id:10} // http://localhost:8089/api/user/10 delete(url, params) { let _params if (Object.is(params, undefined || null)) { _params = '' } else { _params = '/' for (const key in params) { // eslint-disable-next-line no-prototype-builtins if (params.hasOwnProperty(key) && params[key] !== null && params[key] !== '') { _params += `${params[key]}/` } } //去掉参数最后一位? _params = _params.substr(0, _params.length - 1) } if (_params) { return service.delete(`${url}${_params}`).catch(err => { // message.error(err.msg) return Promise.reject(err) }) } else { return service.delete(url).catch(err => { // message.error(err.msg) return Promise.reject(err) }) } }, upload(url, params) { return service.post(url, params, { headers: { 'Content-Type': 'multipart/form-data' } }) } } export default http``` 3、修改src/api下的user.js添加获取用户列表的方法```jsimport request from '@/utils/request'import http from '@/utils/http'//获取用户列表export async function getUserListApi(parm){ return await http.get("/api/user/list",parm)}export function login(data) { return request({ url: '/vue-admin-template/user/login', method: 'post', data })}export function getInfo(token) { return request({ url: '/vue-admin-template/user/info', method: 'get', params: { token } })}export function logout() { return request({ url: '/vue-admin-template/user/logout', method: 'post' })}``` 4、添加获取接口的地址.env.development```js# just a flagENV = 'development'# base apiVUE_APP_BASE_API = '/dev-api'VUE_APP_BASE_API_PRO = 'http://localhost:8089/'```.env.production```js# just a flagENV = 'production'# base apiVUE_APP_BASE_API = '/prod-api'VUE_APP_BASE_API_PRO = 'http://localhost:8089/'``` 5、后端跨域配置```jsAccess to XMLHttpRequest at 'http://localhost:8089/api/user/list?phone=&userName=&pageSize=10&curentPage=1' from origin 'http://localhost:9528' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.```跨域配置在itmk-base-web模块新建com.itmk.config.web包,然后新建WebMvcConfig配置类```jspackage com.itmk.config.web;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.CorsRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configurationpublic class WebMvcConfig implements WebMvcConfigurer { / * 跨域配置 * @param registry */ @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/") .allowedOriginPatterns("*") .allowedMethods("*") .allowedHeaders("*") .maxAge(3600) .allowCredentials(true); }}``` 6、分页组件英文改中文找到main.js文件```js//英文import locale from 'element-ui/lib/locale/lang/en' // lang i18n```改为
三、项目效果演示
创作打卡挑战赛
赢取流量/现金/CSDN周边激励大奖