1. 前端框架  23

1.1 vue-element-admin

vue-element-admin是基于element-ui 的一套后台管理系统集成方案。

功能:https://panjiachen.github.io/vue-element-admin-site/zh/guide/#功能

GitHub地址:https://github.com/PanJiaChen/vue-element-admin

项目在线预览:https://panjiachen.gitee.io/vue-element-admin

1.2  vue-admin-template   23

1.2.1 简介   23

vue-admin-template是基于vue-element-admin的一套后台管理系统基础模板(最少精简版),可作为模板进行二次开发。

GitHub地址:https://github.com/PanJiaChen/vue-admin-template

建议:你可以在 `vue-admin-template` 的基础上进行二次开发,把 `vue-element-admin`当做工具箱,想要什么功能或者组件就去 `vue-element-admin` 那里复制过来。

1.2.2 安装    23

角色管理前端_数据

解压 资料在E:\java学习\云尚办公\资料\资料\4-vue模板中

并且重命名为guigu-oa-admin

角色管理前端_数据_02

将解压后的文件复制到工作区中(复制到E:\java学习\云尚办公\vscode\guigu-oa)

角色管理前端_ico_03

根据配置文件下载相关依赖packagejson

在guigu-oa-admin终端输入命令: npm install

角色管理前端_数据_04

依赖下载成功后启动项目 

在guigu-oa-admin终端输入命令: npm run dev

角色管理前端_数据_05

启动成功

角色管理前端_ico_06

浏览器输入http://localhost:9528/进行访问

角色管理前端_spring_07

角色管理前端_spring_08

1.3源码目录结构  23

角色管理前端_数据_09

了解即可

|-dist 生产环境打包生成的打包项目
|-mock 使用mockjs来mock接口
|-public 包含会被自动打包到项目根路径的文件夹
	|-index.html 唯一的页面
|-src
	|-api 包含接口请求函数模块
		|-table.js  表格列表mock数据接口的请求函数
		|-user.js  用户登陆相关mock数据接口的请求函数
	|-assets 组件中需要使用的公用资源
		|-404_images 404页面的图片
	|-components 非路由组件
		|-SvgIcon svg图标组件
		|-Breadcrumb 面包屑组件(头部水平方向的层级组件)
		|-Hamburger 用来点击切换左侧菜单导航的图标组件
	|-icons
		|-svg 包含一些svg图片文件
		|-index.js 全局注册SvgIcon组件,加载所有svg图片并暴露所有svg文件名的数组
	|-layout
		|-components 组成整体布局的一些子组件
		|-mixin 组件中可复用的代码
		|-index.vue 后台管理的整体界面布局组件
	|-router
		|-index.js 路由器
	|-store
		|-modules
			|-app.js 管理应用相关数据
			|-settings.js 管理设置相关数据
			|-user.js 管理后台登陆用户相关数据
		|-getters.js 提供子模块相关数据的getters计算属性
		|-index.js vuex的store
	|-styles
		|-xxx.scss 项目组件需要使用的一些样式(使用scss)
	|-utils 一些工具函数
		|-auth.js 操作登陆用户的token cookie
		|-get-page-title.js 得到要显示的网页title
		|-request.js axios二次封装的模块
		|-validate.js 检验相关工具函数
		|-index.js 日期和请求参数处理相关工具函数
	|-views 路由组件文件夹
		|-dashboard 首页
		|-login 登陆
	|-App.vue 应用根组件
	|-main.js 入口js
	|-permission.js 使用全局守卫实现路由权限控制的模块
	|-settings.js 包含应用设置信息的模块
|-.env.development 指定了开发环境的代理服务器前缀路径
|-.env.production 指定了生产环境的代理服务器前缀路径
|-.eslintignore eslint的忽略配置
|-.eslintrc.js eslint的检查配置
|-.gitignore git的忽略配置
|-.npmrc 指定npm的淘宝镜像和sass的下载地址
|-babel.config.js babel的配置
|-jsconfig.json 用于vscode引入路径提示的配置
|-package.json 当前项目包信息
|-package-lock.json 当前项目依赖的第三方包的精确信息
|-vue.config.js webpack相关配置(如: 代理服务器)

2. 实现登录&退出登录   24

角色管理前端_数据_10

登录

角色管理前端_ico_11

角色管理前端_ico_12

角色管理前端_数据_13

获取用户信息

角色管理前端_ico_14

角色管理前端_ico_15

角色管理前端_spring_16

2.1 修改访问路径   24

2.1.1 修改方式一

修改前端项目的.env.development

角色管理前端_数据_17

角色管理前端_spring_18

2.1.2 修改方式二 修改vue.config.js    24

修改vue.config.js文件

角色管理前端_spring_19

注释掉mock接口配置

配置代理转发请求到目标接口

// before: require('./mock/mock-server.js')
proxy: {
  '/dev-api': { // 匹配所有以 '/dev-api'开头的请求路径
    target: 'http://localhost:8800',
    changeOrigin: true, // 支持跨域
    pathRewrite: { // 重写路径: 去掉路径中开头的'/dev-api'
      '^/dev-api': ''
    }
  }
}

角色管理前端_spring_20

解释图解

角色管理前端_spring_21

2.2 在后端创建登录相关接口返回mock相同数据   24

这里做个解释,我们这个登陆呢是为了调试借楼写的,并不是真正的登录实现,这个登录仅仅是根据前端需要返回什么样的数据,我们就返回什么样的数据的假登录,因为我们根本没有做验证,只是为了方便测试

在service-oa模块

IndexController

package com.atguigu.auth.controller;

import com.atguigu.common.result.Result;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

// 实现登录&退出登录   24
@Api(tags = "后台登录管理")
@RestController
@RequestMapping("/admin/system/index")
public class IndexController {
    /**
     * 登录   24
     * @return
     */
    @PostMapping("login")
    public Result login() {
        Map<String, Object> map = new HashMap<>();
        map.put("token","admin-token");
        return Result.ok(map);
    }

    /**
     * 获取用户信息   24
     * @return
     */
    @GetMapping("info")
    public Result info() {
        Map<String, Object> map = new HashMap<>();
        map.put("roles","[admin]");
        map.put("name","admin");
        map.put("avatar","https://oss.aliyuncs.com/aliyun_id_photo_bucket/default_handsome.jpg");
        return Result.ok(map);
    }

    /**
     * 退出
     * @return
     */
    @PostMapping("logout")
    public Result logout(){
        return Result.ok();
    }
}

2.3 修改前端   24

2.3.1 修改接口名称  24

可以看到前端中的接口名称和我们后端写的不一样,需要修改

角色管理前端_spring_22

找到前端,将user.js中的接口路径做修改为本地路径

角色管理前端_数据_23

修改后

角色管理前端_数据_24

2.3.2 修改状态码  24

可以看到前端的状态码是20000,而后端我们定义的是200

角色管理前端_spring_25

找到request.js

角色管理前端_spring_26

修改

角色管理前端_数据_27

2.4 测试   24

重新启动前端

角色管理前端_ico_28

启动后端

角色管理前端_数据_29

登录成功

角色管理前端_数据_30

3.  角色列表   25

3.1 修改路由  25

(这个路由的意思就是侧边的类似菜单的选项)

角色管理前端_spring_31

在前端router.js中添加路由

{
    path: '/system',
    component: Layout,
    meta: {
      title: '系统管理',
      icon: 'el-icon-s-tools'
    },
    alwaysShow: true,
    children: [
      {
        path: 'sysRole',
        component: () => import('@/views/system/sysRole/list'),
        meta: {
          title: '角色管理',
          icon: 'el-icon-s-help'
        },
      }
    ]
  },

角色管理前端_spring_32

根据角色路由创建页面

角色管理前端_数据_33

3.2 定义api   25

在api文件夹中创建js文件,定义接口信息

创建文件 src/api/system/sysRole.js

角色管理前端_数据_34

sysRole.js

import request from '@/utils/request'

const api_name = '/admin/system/sysRole'

export default {
    //角色列表-条件分页查询    25
    getPageList(current,limit,searchObj) {
        return request({
            url: `${api_name}/${current}/${limit}`,
            method: 'get',
            //如果普通对象参数写法 params:对象参数名称
            //如果使用json格式传递,data:对象参数名称
            params:searchObj
        })
    }

}

在api接口定义完成后,我们接下来在页面引入定义接口的js文件,调用接口通过axios实现功能

3.3 初始化vue组件  25

角色管理前端_spring_35

在views文件夹中创建页面,在页面引入定义接口的js文件,调用接口通过axios实现功能

list.vue

<template>
    <div class="app-container">

    <!--查询表单    26-->
    <div class="search-div">
        <el-form label-width="70px" size="small">
        <el-row>
            <el-col :span="24">
            <el-form-item label="角色名称">
                <el-input style="width: 100%" v-model="searchObj.roleName" placeholder="角色名称"></el-input>
            </el-form-item>
            </el-col>
        </el-row>
        <el-row style="display:flex">
            <el-button type="primary" icon="el-icon-search" size="mini" :loading="loading" @click="fetchData()">搜索</el-button>
            <el-button icon="el-icon-refresh" size="mini" @click="resetData">重置</el-button>
        </el-row>
        </el-form>
    </div>

    <!-- 表格   26-->
    <el-table
      v-loading="listLoading"
      :data="list"
      stripe
      border
      style="width: 100%;margin-top: 10px;"
      @selection-change="handleSelectionChange">

      <el-table-column type="selection"/>

      <el-table-column
        label="序号"
        width="70"
        align="center">
        <template slot-scope="scope">
          {{ (page - 1) * limit + scope.$index + 1 }}
        </template>
      </el-table-column>

      <el-table-column prop="roleName" label="角色名称" />
      <el-table-column prop="roleCode" label="角色编码" />
      <el-table-column prop="createTime" label="创建时间" width="160"/>
      <el-table-column label="操作" width="200" align="center">
        <template slot-scope="scope">
          <el-button type="primary" icon="el-icon-edit" size="mini" @click="edit(scope.row.id)" title="修改"/>
          <el-button type="danger" icon="el-icon-delete" size="mini" @click="removeDataById(scope.row.id)" title="删除"/>
        </template>
      </el-table-column>
    </el-table>

    <!-- 分页组件   26-->
    <el-pagination
        :current-page="page"
        :total="total"
        :page-size="limit"
        style="padding: 30px 0; text-align: center;"
        layout="total, prev, pager, next, jumper"
        @current-change="fetchData"
    />

  </div>

</template>

<script>
import api from '@/api/system/sysRole'
export default {
  // 定义数据模型    26
  //初始值  26
  data() {
    return {
        list:[],//角色列表
        page:1,//当前页
        limit:1,//每页显示记录数
        total:0,//总记录数
        searchObj:{},//条件对象

    }
  },
  // 页面渲染成功后获取数据
  created() {
    this.fetchData()
  },
  // 定义方法
  methods: {//操作方法  26
    fetchData(current=1) {
        //条件分页查询  26
        this.page = current
        api.getPageList(this.page,this.limit,this.searchObj)
            .then(response => {
                this.list = response.data.records
                this.total = response.data.total
            })
    }
  }
}
</script>


3.4 测试  26

浏览器输入 http://localhost:9529/,成功

角色管理前端_ico_36

4. 删除角色  27

4.1定义api   27

角色管理前端_ico_37

sysRole.js

//角色删除   27
     removeById(id) {
        return request({
            url: `${api_name}/remove/${id}`,
            method: 'delete'
        })
    }

4.2 实现功能  27

角色管理前端_ico_38

list.vue

//删除    27
    removeDataById(id) {
        this.$confirm('此操作将永久删除该记录, 是否继续?', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
        }).then(() => {
            //调用
            return api.removeById(id)
        }).then(response => {
            //刷新页面
            this.fetchData()
            //提示信息
                this.$message.success(response.message || '删除成功')
        })
    }

4.3 测试  27

角色管理前端_ico_39

角色管理前端_spring_40

角色管理前端_spring_41

5. 角色添加  28

5.1 添加按钮   28

角色管理前端_数据_42

src/views/system/sysRole

list.vue

<!-- 工具条 -->
<div class="tools-div">
  <el-button type="success" icon="el-icon-plus" size="mini" @click="add">添 加</el-button>
</div>


5.2 定义api   28

src/api/system/sysRole.js

sysRole.js

//角色添加  28
    saveRole(role) {
        return request({
            url: `${api_name}/save`,
            method: 'post',
            data:role
        })
    }

5.3 实现功能   28

5.3.1  定义弹出层

src/views/system/sysRole/list.vue

表格最下面添加弹出层

list.vue
<el-dialog title="添加/修改" :visible.sync="dialogVisible" width="40%" >
      <el-form ref="dataForm" :model="sysRole" label-width="150px" size="small" style="padding-right: 40px;">
        <el-form-item label="角色名称">
          <el-input v-model="sysRole.roleName"/>
        </el-form-item>
        <el-form-item label="角色编码">
          <el-input v-model="sysRole.roleCode"/>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false" size="small" icon="el-icon-refresh-right">取 消</el-button>
        <el-button type="primary" icon="el-icon-check" @click="saveOrUpdate()" size="small">确 定</el-button>
      </span>
    </el-dialog>

角色管理前端_数据_43

5.3.2 功能实现   28

src/views/system/sysRole/list.vue

list.vue
//添加或者修改   28
        saveOrUpdate() {
            //根据id判断
            if (!this.sysRole.id) {//添加
                this.save()
            } else {//修改
                this.update()
            }
        },
        save() { //添加   28
            api.saveRole(this.sysRole)
                .then(response => {
                    //提示
                    this.$message.success(response.message || '操作成功')
                    //关闭弹框
                    this.dialogVisible = false
                    //刷新页面
                    this.fetchData()
                })
        },

5.4 测试

浏览去输入http://localhost:9529/

角色管理前端_ico_44

角色管理前端_spring_45

角色管理前端_spring_46

6. 修改角色  29

6.1 定义api

 src/api/system/sysRole.js

sysRole.js

//根据id查询数据  29
    getById(id) {
        return request({
          url: `${api_name}/get/${id}`,
          method: 'get'
        })
      },
      //修改   29
      updateById(role) {
        return request({
          url: `${api_name}/update`,
          method: 'put',
          data: role
        })
      }

6.2 功能实现   29

src/views/system/sysRole/list.vue

list.vue

//点击修改,弹出框,根据id查询数据显示  29
        edit(id) {
            //弹出框
            this.dialogVisible = true
            //根据id查询
            this.fetchDataById(id)
        },
        //根据id查询   29
        fetchDataById(id) {
            api.getById(id)
                .then(response => {
                    this.sysRole = response.data
                })
        },
        update() { //修改   29
            api.updateById(this.sysRole)
                .then(response => {
                    //提示
                    this.$message.success(response.message || '操作成功')
                    //关闭弹框
                    this.dialogVisible = false
                    //刷新页面
                    this.fetchData()
                })
        }

6.3 测试 29

角色管理前端_数据_47

角色管理前端_spring_48

角色管理前端_ico_49

7. 角色批量删除  30

7.1 定义api   30

src/api/system/sysRole.js

sysRole.js

//批量删除  30
    batchRemove(idList) {
        return request({
            url: `${api_name}/batchRemove`,
            method: 'delete',
            data: idList
        })
    }

7.2 功能实现  30

src/views/system/sysRole/list.vue

7.2.1 在table组件上添加 批量删除 按钮   30

list.vue

<!-- 工具条 -->
<div class="tools-div">
  <el-button type="success" icon="el-icon-plus" size="mini" @click="add">添 加</el-button>
  <el-button class="btn-add" size="mini" @click="batchRemove()" >批量删除</el-button>
</div>

角色管理前端_spring_50

7.2.2 功能实现  30

src/views/system/sysRole/list.vue

list.vue

角色管理前端_ico_51

//选择复选框,把复选框所在行内容传递  30
        handleSelectionChange(selection) {
            this.selections = selection
            console.log(this.selections)
        },
        //批量删除   30
        batchRemove() {
            //判断
            if(this.selections.length == 0) {
                this.$message.warning('请选择要删除的记录!')
                return
            }
            this.$confirm('此操作将永久删除该记录, 是否继续?', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                // [1,2,3]
                var idList = []
                //选择复选框数据在数组里面 this.selections
                this.selections.forEach(item => {
                    var id = item.id
                    idList.push(id)
                });
                return api.batchRemove(idList)
            }).then(response => {
                this.$message.success(response.message)
                this.fetchData()
            })
        }

7.3 测试  30

浏览器输入http://localhost:9529/

角色管理前端_spring_52

角色管理前端_spring_53