谷粒学院-第五天-讲师管理前端开发

目录

一、第五天内容介绍

二、把系统登录功能改造本地

 三、框架使用过程


一、第五天内容介绍

讲师管理前端开发

1、讲师列表(分页条件查询)

2、讲师添加

3、讲师删除功能

4、讲师修改功能

vue-admin-template模块进行前端开发

基于 vue + element-ui

首先,把后台管理系统登录改造工地(临时)后面把登录添加权限框架spring secuitry

二、把系统登录功能改造本地

1、系统登录默认使用这个地址

把登录请求地址改造本地 http://localhost:8001

2、修改配置文件请求地址

在config文件夹里面有dev.env.js

// 登录
    Login({ commit }, userInfo) {
      const username = userInfo.username.trim()
      return new Promise((resolve, reject) => {
        login(username, userInfo.password).then(response => {
          const data = response.data
          setToken(data.token)
          commit('SET_TOKEN', data.token)
          resolve()
        }).catch(error => {
          reject(error)
        })
      })
    },

注意 :是http不是https

http和https区别

https个人使用没有权限,需要找相关部门认证才行

3、进行登录调用两个方法:

        login登录操作方法

        info登录之后获取用户信息的方法,

        所以,创建接口两个方法实现登录

(1)login 返回 token值

// 登录
    Login({ commit }, userInfo) {
      const username = userInfo.username.trim()
      return new Promise((resolve, reject) => {
        login(username, userInfo.password).then(response => {
          const data = response.data
          setToken(data.token)
          commit('SET_TOKEN', data.token)
          resolve()
        }).catch(error => {
          reject(error)
        })
      })
    },

 (2)info返回 roles name avatar(头像)

// 获取用户信息
    GetInfo({ commit, state }) {
      return new Promise((resolve, reject) => {
        getInfo(state.token).then(response => {
          const data = response.data
          if (data.roles && data.roles.length > 0) { // 验证返回的roles是否是一个非空数组
            commit('SET_ROLES', data.roles)
          } else {
            reject('getInfo: roles must be a non-null array !')
          }
          commit('SET_NAME', data.name)
          commit('SET_AVATAR', data.avatar)
          resolve(response)
        }).catch(error => {
          reject(error)
        })
      })
    },

 这两个方法在user.js中

 4、开发接口

(1)先创建

(2)写接口中的方法

package com.atguigu.eduservice.controller;

import com.atguigu.commonutils.R;
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;

@RestController
@RequestMapping("/eduservice/user")
public class EduLoginController {

    //login
    @PostMapping("login")
    public R login(){
        return R.ok().data("token","admin");
    }

    //info
    @GetMapping("info")
    public R info(){
        return R.ok().data("roles","[admin]").data("name","admin").data("avatar","https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
    }

}

5、修改api文件login.js修改本地接口路径

(1)修改login地址

(2)修改info地址

 6、最终测试,出现问题

 

跨域问题:通过一个地址去访问另外一个地址,这个过程中有三个地方有任何一个不一样

        访问协议   http https

        ip地址        192.168.1.1  172.11.11.11

        端口号        9258 8001

前端端口: http://localhost:9528/

后端端口:http://localhost:8001/

端口不一样,产生跨域问题

7、跨域解决方式

(1)在后端接口controller添加注解(常用)

 (2)使用网关解决(后面讲到)

8、测试

注意:如果发现成功但没跳转页面,记得看一common中的状态码

 将code改为20000

package com.atguigu.commonutils;

public interface ResultCode {
    public static Integer SUCCESS = 20000;//成功

    public static Integer ERROR = 20001;//操作失败
}

 成功页面

两次 第一次测连通 第二次发请求

 

 三、框架使用过程

第一步 添加路由

 第二步  点击某个路由,显示路由对应页面内容

跳到对应页面

 第三步 在api文件夹创建js文件,定义接口地址和参数

 第四步 在创建vue页面引入js文件,调用方法实现功能

引入 import user from '...'

data:{

},
created(){

},
methods:{

}

最后使用element-ui显示数据内容

3.1 讲师列表前端实现

第一步 添加路由

第二步 创建路由对应的页面

 

 路径不要写错 我的宝们

list.vue

<template>
  <div class="app-container">
    讲师列表
  </div>
</template>

效果展示

 save.vue

<template>
  <div class="app-container">
    讲师添加
  </div>
</template>

效果展示

第三步 在api文件创建teacher.js定义访问的接口地址 

 teacher.js代码如下

/* eslint-disable no-undef */
import request from '@/utils/request'

export default {

  // 1 讲师列表(条件查询分页)
  // current当前页 limit分页 teacherQuery条件对象
  getTeacherListPage(current, limit, teacherQuery) {
    return request({
      //url: '/table/list/'+current+"/"+limit,
      url: `/eduservice/teacher/pageTeacherCondition/${current}/${limit}`,
      method: 'post',
      //teacherQuery条件对象,后端使用RequestBody获取数据
      //data 表示把对象转换为json进行传递到接口里面
      data: teacherQuery
    })
  }
}

 第四步 在讲师列表页面 list.vue页面调用定义的接口方法,得到接口返回数据

<template>
  <div class="app-container">
    讲师列表
  </div>
</template>
<script>
//引入调用teacher.js文件
import teacher from '@/api/edu/teacher'

export default {
  //写核心代码位置
  // data:{

  // },
  data() { //定义边和和初始值
    return {
      list:null,//查询之后接口返回集合
      page:1,//当前页
      limit:10,//每页记录数
      total:0,//总记录数
      teacherQuery:{} //条件封装对象
    };
  },
  created() { // 在页面渲染之前执行,一般调用methods定义的方法
    //调用
    this.getList()
  },
  methods: { // 创建具体的方法,调用teacher.js定义的方法
    //讲师列表的方法
    getList(){
      teacher.getTeacherListPage(this.page,this.limit,this.teacherQuery)
        .then(response =>{//请求成功
          //response 接口返回的数据
          this.list = response.data.rows
          this.total = response.data.total
          console.log(this.list) 
          console.log(this.total)
        })
        .catch(error =>{
          console.log(error)
        })//请求失败
    }
  }

}
</script>

浏览器输出效果

 第五步 把请求接口获取数据在页面进行显示

使用组件 Element-ui 网址 Element - The world's most popular Vue UI framework

5.1 点开Table表格

5.2 点开隐藏代码

表格的代码如下

    <el-table
      :data="list"
      border
      fit
      highlight-current-row>

      <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="name" label="名称" width="80" />

      <el-table-column label="头衔" width="80">
        <template slot-scope="scope">
          {{ scope.row.level===1?'高级讲师':'首席讲师' }}
        </template>
      </el-table-column>

      <el-table-column prop="intro" label="资历" />

      <el-table-column prop="gmtCreate" label="添加时间" width="160"/>

      <el-table-column prop="sort" label="排序" width="60" />

      <el-table-column label="操作" width="200" align="center">
        <template slot-scope="scope">
          <router-link :to="'/teacher/edit/'+scope.row.id">
            <el-button type="primary" size="mini" icon="el-icon-edit">修改</el-button>
          </router-link>
          <el-button type="danger" size="mini" icon="el-icon-delete" @click="removeDataById(scope.row.id)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

5.3效果展示

第六步 分页组件

6.1原始代码

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

修改后的代码

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

修改getList方法

    getList(page = 1){
      this.page= page
      teacher.getTeacherListPage(this.page,this.limit,this.teacherQuery)
        .then(response =>{//请求成功
          //response 接口返回的数据
          this.list = response.data.rows
          this.total = response.data.total
          console.log(this.list) 
          console.log(this.total)
        })
        .catch(error =>{
          console.log(error)
        })//请求失败
    }

效果展示

 6.2 添加条件查询

注意:element-ui的 date-picker组件默认绑定的时间值是默认世界标准时间,和中国时间差8小时

原始代码

    <!--查询表单-->
    <el-form :inline="true" class="demo-form-inline">
      <el-form-item>
        <el-input v-model="searchObj.name" placeholder="讲师名" />
      </el-form-item>
      <el-form-item>
        <el-select v-model="searchObj.level" clearable placeholder="讲师头衔">
          <el-option :value="1" label="高级讲师" />
          <el-option :value="2" label="首席讲师" />
        </el-select>
      </el-form-item>
      <el-form-item label="添加时间">
        <el-date-picker
          v-model="searchObj.begin"
          type="datetime"
          placeholder="选择开始时间"
          value-format="yyyy-MM-dd HH:mm:ss"
          default-time="00:00:00"
        />
      </el-form-item>
      <el-form-item>
        <el-date-picker
          v-model="searchObj.end"
          type="datetime"
          placeholder="选择截止时间"
          value-format="yyyy-MM-dd HH:mm:ss"
          default-time="00:00:00"
        />
      </el-form-item>
      <el-button type="primary" icon="el-icon-search" @click="fetchData()">查 询</el-button>
      <el-button type="default" @click="resetData()">清空</el-button>
    </el-form>

 情况功能

(1)清空表单输入条件数据

(2)查询所有的数据

     resetData(){// 清空的方法
      //表单输入项数据清空
      this.teacherQuery = {}

      //查询所有讲师数据
      this.getList
    }

6.3 讲师删除功能

1、在每条记录后添加 删除按键

2、在按键绑定事件

 3、在绑定事件的方法传递删除讲师id值

 4、在api文件夹teacher.js定义删除接口的地址

//删除讲师
  deleteTeacherId(id){
    return request({
      url: `/eduservice/teacher/${id}`,
      method: 'delete',
    })
  }

5、页面调用,实现方法

从用户体验来看 应该加个提示框

Element-ui代码

// debugger
      // console.log(memberId)
      this.$confirm("此操作将永久删除该记录, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          return teacher.removeById(id);
        })
        .then(() => {
          this.fetchData();
          this.$message({
            type: "success",
            message: "删除成功!",
          });
        })
        .catch((response) => {
          // 失败
          if (response === "cancel") {
            this.$message({
              type: "info",
              message: "已取消删除",
            });
          } else {
            this.$message({
              type: "error",
              message: "删除失败",
            });
          }
        });

修改后的代码

     this.$confirm("此操作将永久删除讲师记录, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      }).then(() => { // 点击确定,执行then方法
        teacher.deleteTeacherId(id)
          .then(response => {//删除成功
          //提示消息
          this.$message({
            type: "success",
            message: "删除成功!",
          });
          //回到列表页面
          this.getList()
          })
        })
    }

效果展示

 我们删除王刚

 数据王刚的is_deleted变为1 逻辑删除成功

6.4 添加讲师功能

1.点击添加讲师按钮 进入表单页面,输入讲师信息

Element-ui 代码

<el-form label-width="120px">
      <el-form-item label="讲师名称">
        <el-input v-model="teacher.name" />
      </el-form-item>
      <el-form-item label="讲师排序">
        <el-input-number v-model="teacher.sort" controls-position="right" :min="0"/>
      </el-form-item>
      <el-form-item label="讲师头衔">
        <el-select v-model="teacher.level" clearable placeholder="请选择">
          <!--
          数据类型一定要和取出的json中的一致,否则没法回填
          因此,这里value使用动态绑定的值,保证其数据类型是number
          -->
          <el-option :value="1" label="高级讲师" />
          <el-option :value="2" label="首席讲师" />
        </el-select>
      </el-form-item>
      <el-form-item label="讲师资历">
        <el-input v-model="teacher.career" />
      </el-form-item>
      <el-form-item label="讲师简介">
        <el-input v-model="teacher.intro" :rows="10" type="textarea" />
      </el-form-item>
      <!-- 讲师头像:TODO -->
      <el-form-item>
        <el-button :disabled="saveBtnDisabled" type="primary" @click="saveOrUpdate">保存</el-button>
      </el-form-item>
    </el-form>

 在表单页面点击保存,提交接口,添加数据

(1)定义接口地址,修改api下teaher.js

//添加讲师
  addTeacher(teacher){
    return request({
      url: `/eduservice/teacher/addTeacher`,
      method: 'post',
      data:teacher
    })
  }

(2)在页面实现调用

先进行引入 

 代码

    //添加讲师的方法
    SaveTeacher(){
        teacherApi.addTeacher(this.teacher)
        .then(response => {// 添加成功
        //提示信息
         //提示消息
          this.$message({
            type: "success",
            message: "添加成功!",
          });

        //回到列表页面 路由跳转
        this.$router.push({path:'/teacher/table'})
        
        })
    }

测试

 6.4 讲师修改功能

1、每条几率后面添加 修改 按钮

2、点击修改按钮,进入表单页面,进行数据库回显

        根据讲师id查询数据显示

3、通过路由跳转进入数据回显页面,在路由index页面添加路由

      {
        path: 'edit/:id',
        name: 'EduTeacherEdit',
        component: () => import('@/views/edu/teacher/save'),
        meta: { title: '编辑讲师', noCache: 'tree' },
        hidden: true
      }

页面显示

 4、在表单页面实现数据回显

(1)在teacher.js定义根据id查询接口

 getTeacherInfo(id){
    return request({
      url: `/eduservice/teacher/getTeacher/${id}`,
      method: 'get'
    })
  }

(2)在页面调用接口实现回显

 //根据讲师id查询的方法
    getInfo(id){
      teacherApi.getTeacherInfo(id)
        .then(response => {
          this.teacher = response.data.teacher;
        })
    },

(3)调用 根据id查询的方法

因为添加和修改使用save页面 区别添加还是修改,只有修改时查询数据回显

区别添加还是修改,只有修改时候查询数据回显

判断路径里面是否含有讲师id值,如果有id值为修改,没有id值则为添加

    if (this.$route.params && this.$route.params.id) {
      //从路径获取id值
      const id = this.$route.params.id;
      //调用根据id查询的方法
      this.getInfo(id);
    }

5、最终修改实现

1、在api的teacher.js定义接口

  //修改讲师
  updateTeacherInfo(teacher) {
    return request({
      url: `/eduservice/teacher/updateTeacher`,
      method: 'post',
      data: teacher
    })
  },

2、在页面调用

判断为修改还是添加 根据id判断

    saveOrUpdate() {
      //判断修改还是添加
      //根据teacher是否有id 有id为修改 否则就是添加
      if(!this.teacher.id){
        //添加
        this.saveTeacher()
      }else{
        //修改
        this.updateTeacher()
      }
    },

修改讲师的方法

    //修改讲师的方法
    updateTeacher(){
      teacherApi.updateTeacherInfo(this.teacher)
        .then(response => {
        //提示信息
        this.$message({
          type: "success",
          message: "修改成功!",
        });
        //回到列表页面 路由跳转
        this.$router.push({ path: "/teacher/table" });
        })
    },

测试

 

 四、存在的问题

1、第一次点击修改 进行数据回显

第二次再去点击 添加讲师,进入表单页面,遇到问题:表单页面还是显示修改回显的数据,正确效果应该是表单数据清空

解决方式:

做添加讲师的时候,表单数据清空就可以了

 created() {
    //页面渲染之前执行
    //判断路径是否有id值
    if (this.$route.params && this.$route.params.id) {
      //从路径获取id值
      const id = this.$route.params.id;
      //调用根据id查询的方法
      this.getInfo(id);
    }else{ //路径没有id值,做添加
      //清空表单代码
      this.teacher = {}

    }
  },

上面代码没有解决问题,为什么?

多次路由跳转到同一个页面,在页面中created方法只会执行一次,后面再进行跳转不会执行的

最终解决:使用vue监听

 watch:{ // 监听
    $route(to,from) { //路由变化方式,路由发生变化方法执行
      this.init()
    }
  },

抽取init方法

    init(){
      //判断路径是否有id值
      if (this.$route.params && this.$route.params.id) {
      //从路径获取id值
      const id = this.$route.params.id;
      //调用根据id查询的方法
      this.getInfo(id);
    }else{ //路径没有id值,做添加
      //清空表单代码
      this.teacher = {}
    }

测试通过


版权声明:本文为m0_56054652原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。