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、新建员工实体

```js
package 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接口

```js
UserMapper接口需要继承 BaseMapper,继承BaseMapper的好处是我们可以直接使用Mybatis -Plus提供的通用CRUD方法
```

```js
package com.itmk.web.user.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itmk.web.user.entity.User;

/**
 * 员工数据访问层
 */
public interface UserMapper extends BaseMapper<User> {
}
```

###### 3、新建员工mapper层映射文件 

 在web模块的resources资源文件夹下新建mapper文件目录,然后新建UserMapper.xml,如下所示

```js
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.itmk.web.user.mapper.UserMapper">

</mapper>
```

###### 4、新建员工service层

4.1.在itmk-base-web模块新建com.itmk.web.user.service包,然后新建UserService接口,并继承IService接口

```js
package com.itmk.web.user.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.itmk.web.user.entity.User;

public interface UserService extends IService<User> {
    //查询用户列表
    IPage<User> list(UserParm parm);
}

```

4.2在itmk-base-web模块新建com.itmk.web.user.service.impl包,然后新建UserServiceImpl类

```js
package 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 进行管理,我们就可以在其他类里面直接注入使用
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Override
    public IPage<User> list(UserParm parm) {
        //构建分页对象
        IPage<User> page = new Page<>();
        page.setSize(parm.getPageSize());
        page.setCurrent(parm.getCurrentPage());
        //构造前端查询条件
        QueryWrapper<User> 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控制器

```js
package 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<User> list = userService.list(parm);
        return ResultUtils.success("查询成功",list);
    }
}

```

```js
package com.itmk.web.user.entity;

import lombok.Data;

@Data
public class UserParm {
    //页容量
    private Long pageSize;
    //当前页
    private Long curentPage;
    //姓名
    private String userName;
    //电话
    private String phone;
}

```



###### 6、新建启动类

在itmk-base-web模块的com.itmk包下新建 WyglApplication启动类

```js
package com.itmk;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class WyglApplication {
    public static void main(String[] args) {
        SpringApplication.run(WyglApplication.class,args);
    }
}
```



#### 第8讲 员工管理列表制作

element ui官网

```js
https://element.eleme.cn/#/zh-CN/component/installation
```



###### 1、页面完整代码

```js
<template>
  <el-main>
    <!-- 搜索框 -->
    <el-form
      :model="parms"
      ref="searchform"
      label-width="80px"
      :inline="true"
      size="small"
    >
      <el-form-item label="姓名">
        <el-input v-model="parms.userName"></el-input>
      </el-form-item>
      <el-form-item label="电话">
        <el-input v-model="parms.phone"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button icon="el-icon-search">查询</el-button>
        <el-button type="primary" icon="el-icon-plus">新增</el-button>
      </el-form-item>
    </el-form>
    <!-- 员工表格 -->
    <el-table :height="tableHeight" :data="tableList" empty-text="暂无数据" border stripe>
      <el-table-column prop="userName" label="姓名"></el-table-column>
      <el-table-column prop="phone" label="电话"></el-table-column>
      <el-table-column prop="idCard" label="身份证"></el-table-column>
      <el-table-column prop="sex" label="性别"></el-table-column>
      <el-table-column prop="status" label="是否在职"></el-table-column>
      <el-table-column prop="isUsed" label="账户状态"></el-table-column>
    </el-table>
    <el-pagination
      @size-change="sizeChange"
      @current-change="currentChange"
      :current-page.sync="parms.curentPage"
      :page-sizes="[10, 20, 40, 80, 100]"
      :page-size="parms.pageSize"
      :total="parms.total"
      background
    >
    </el-pagination>
  </el-main>
</template>

<script>
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);
    },
  },
};
</script>

<style lang="scss" scoped>
</style>
```

###### 2、新建http.js

```js
import 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

添加获取用户列表的方法

```js
import 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 flag
ENV = 'development'

# base api
VUE_APP_BASE_API = '/dev-api'
VUE_APP_BASE_API_PRO = 'http://localhost:8089/'

```

.env.production

```js
# just a flag
ENV = 'production'

# base api
VUE_APP_BASE_API = '/prod-api'
VUE_APP_BASE_API_PRO = 'http://localhost:8089/'

```



###### 5、后端跨域配置

```js
Access 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配置类

```js
package 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;

@Configuration
public 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
```

改为

三、项目效果演示

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值