spring cloud+vue在线视频网站 6.章节编辑删除功能、前端优化和校验模块

8 篇文章 0 订阅
6 篇文章 0 订阅

这一节增加了大章的编辑和删除功能,这样大章的增删改查功能就都有了,但是在增加和修改时应该还要有校验功能。

编辑功能

这一节主要对大章模块增加编辑功能,其次还删除一些多余组件。首先,我们将多余对按钮进行了删除,并且对剩余按钮绑定函数;接着我们将修改功能和增加功能合并,修改了前端的 save 方法和后端对应的类。

修改页面

删除了部分按钮,并把编辑按钮和删除按钮绑定对应函数。

 <tbody>
 <tr v-for="chapter in chapters" v-bind:key="chapter">
     <td>{{chapter.id}}</td>
     <td>{{chapter.name}}</td>
     <td>{{chapter.courseId}}</td>
     <td>
         <div class="hidden-sm hidden-xs btn-group">
             <button class="btn btn-xs btn-info">
                 <i v-on:click="edit(chapter)" class="ace-icon fa fa-pencil bigger-120"></i>
             </button>
             <button class="btn btn-xs btn-danger">
                 <i v-on:click="del(chapter.id)" class="ace-icon fa fa-trash-o bigger-120"></i>
             </button>
         </div>
     </td>
 </tr>
 </tbody>

修改后页面如下:
在这里插入图片描述

前端修改

下面新增对应函数:

            edit(chapter) {
                let _this = this;
                _this.chapter = $.extend({},chapter);
                $("#form-modal").modal("show");
            },
            del(chapter.id) {
            
            }

这里也是点击编辑按钮先弹出修改框,在修改完之后点击 save 按钮后将数据传到后端处理。
这里需要注意的是用到了 extend 关键字,这样可以将当前的 chapter 信息传给 {} ,再绑定到弹出框,这样修改弹出框中的信息时不会把页面中的 chapter 改变。

后端修改

Controller 层没有改变,主要是修改 Service 层的 save 方法。首先判断传入的 chapter 是否有 Id 属性,然后对其进行修改或者新增操作。

    public void save(ChapterDto chapterDto){
        Chapter chapter = CopyUtil.copy(chapterDto,Chapter.class);
        if(StringUtils.isEmpty(chapter.getId())){
            this.insert(chapter);
        }else{
            this.update(chapter);
        }
    }

    private void insert(Chapter chapter){
        chapter.setId(UuidUtil.getShortUuid());
        chapterMapper.insert(chapter);
    }

    private void update(Chapter chapter){
        chapterMapper.updateByPrimaryKey(chapter);
    }

删除功能

上节已经将删除按钮和 del 函数绑定在一起,这节首先修改前端删除函数,然后在后端新增删除操作。

前端修改

前端删除功能用 delete 请求,将需要删除的章节 id 传给后端。

            del(id) {
                let _this = this;
                console.log(id);             
                _this.$ajax.delete('http://127.0.0.1:9000/business/admin/chapter/delete/'+id).then((response)=>{
                      console.log("删除大章结果",response);
                      let res = response.data;
                      if(res.success){
                          _this.list(1);
                      }
                })

            }

后端控制层先增加 delete 方法 ,id 用 @PathVariable 接收。

    @DeleteMapping("/delete/{id}")
    public ResponseDto delete(@PathVariable String id){
        chapterService.delete(id);
        ResponseDto responseDto = new ResponseDto();
        return responseDto;
    }

然后增加服务层对应方法。

    public void delete(String id){
        chapterMapper.deleteByPrimaryKey(id);
    }

前端界面优化

这里页面点击删除就直接删除了,一般应该会有提示是否删除,再确认后才会删除。这里确认框和操作结果提示使用的是 sweetalter2 ;界面的等待框使用的是 blockui。

添加 js

这里采用的方式是在 vue 项目的 public/static 包中添加 js 包,用来存放一些前端组件。
在 js 包中新建一个 toast.js 文件,这个文件存放的是前端操作后提示的 js 组件。
新建一个 confirm.js 文件,这个文件存放的是前端确认提示的 js 组件。
新建一个 loading.js 文件,这个文件存放的是前端等待提示的 js 组件。

toast.js

Toast = {
  success: function (message) {
    Swal.fire({
      position: 'top-end',
      icon: 'success',
      title: message,
      showConfirmButton: false,
      timer: 3000
    })
  },

  error: function (message) {
    Swal.fire({
      position: 'top-end',
      icon: 'error',
      title: message,
      showConfirmButton: false,
      timer: 3000
    })
  },

  warning: function (message) {
    Swal.fire({
      position: 'top-end',
      icon: 'warning',
      title: message,
      showConfirmButton: false,
      timer: 3000
    })
  }
};

confirm.js

Confirm = {
  show: function (message, callback) {
    Swal.fire({
      title: 'Are you sure?',
      text: message,
      icon: 'warning',
      showCancelButton: true,
      confirmButtonColor: '#3085d6',
      cancelButtonColor: '#d33',
      confirmButtonText: 'sure!'
    }).then((result) => {
      if (result.value) {
        if (callback) {
          callback()
        }
      }
    })
  }
}

loading.js

Loading = {
  show: function () {
    $.blockUI({
      message: '<img src="/static/image/loading.gif" />',
      css: {
        zIndex: "10011",
        padding: "10px",
        left: "50%",
        width: "80px",
        marginLeft: "-40px",
      }
    });
  },
  hide: function () {
    // 本地查询速度太快,loading显示一瞬间,故意做个延迟
    setTimeout(function () {
      $.unblockUI();
    }, 500)
  }
};

这里的 loading.gif 就是一张动图,在网上找一下就有类似的了
在这里插入图片描述

index.html

<!--  确认框和提示框  -->
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@9"></script>
<script src="<%= BASE_URL %>static/js/toast.js"></script>
<script src="<%= BASE_URL %>static/js/confirm.js"></script>

<!--  loading等待框  -->
<script src="https://cdn.bootcdn.net/ajax/libs/jquery.blockUI/2.70.0-2014.11.23/jquery.blockUI.min.js"></script>
<script src="<%= BASE_URL %>static/js/loading.js"></script>
修改方法

前端组件添加后就应该在各个操作中调用这些提示。
1.在查询之前会显示 Loading 图标,然后查询完后会关闭 Loading 图标。
2.在保存编辑时,会先显示 Loading 图标,发送请求后关闭 Loading 图标,如果成功还会显示保存成功提示。
3.在删除时,先弹出确认提示,如果确认删除会先显示 Loading 图标,接着关闭 Loading 图标。
修改后的方法如下:

list(page) {
    let _this = this;
    Loading.show();
    console.log(page, _this.$refs.pagination.size);
    _this.$ajax.post('http://127.0.0.1:9000/business/admin/chapter/list',{
        page: page,
        size: _this.$refs.pagination.size
    }).then((response)=>{
        console.log(response);
        Loading.hide();
        let res = response.data;
        _this.chapters = res.content.list;
        _this.$refs.pagination.render(page, res.content.total);
    })
},
save(page) {
    let _this = this;
    Loading.show();
    console.log(page);
    _this.$ajax.post('http://127.0.0.1:9000/business/admin/chapter/save',_this.chapter).then((response)=>{
        console.log("保存大章结果",response);
        let res = response.data;
        Loading.hide();
        if(res.success){
            $("#form-modal").modal("hide");
            _this.list(1);
            Toast.success("保存成功");
        }
    })
},
del(id) {
    let _this = this;
    console.log(id);
    Confirm.show("删除后不能还原,是否确认删除?",function() {
        Loading.show();
        _this.$ajax.delete('http://127.0.0.1:9000/business/admin/chapter/delete/'+id).then((response)=>{
                        console.log("删除大章结果",response);
                        let res = response.data;
                        Loading.hide();
                        if(res.success){
                            Toast.success("删除成功");
                            _this.list(1);
                        }
                    })
    });
}

校验模块

前端校验

首先在 js 包中添加 tool.js 和 validator.js ,分别是分离出来的处理流程和校验流程,接着在 save 中添加校验。
Validator.js

Validator = {
  require: function (value, text) {
    if (Tool.isEmpty(value)) {
      Toast.warning(text + "不能为空");
      return false;
    } else {
      return true
    }
  },

  length: function (value, text, min, max) {
    if (Tool.isEmpty(value)) {
      return true;
    }
    if (!Tool.isLength(value, min, max)) {
      Toast.warning(text + "长度" + min + "~" + max + "位");
      return false;
    } else {
      return true
    }
  }
};

tool.js

Tool = {
  /**
   * 空校验 null或""都返回true
   */
  isEmpty: function (obj) {
    if ((typeof obj == 'string')) {
      return !obj || obj.replace(/\s+/g, "") == ""
    } else {
      return (!obj || JSON.stringify(obj) === "{}" || obj.length === 0);
    }
  },

  /**
   * 非空校验
   */
  isNotEmpty: function (obj) {
    return !this.isEmpty(obj);
  },

  /**
   * 长度校验
   */
  isLength: function (str, min, max) {
    return $.trim(str).length >= min && $.trim(str).length <= max;
  }
}

index.html

<!--  通用工具类  -->
<script src="<%= BASE_URL %>static/js/tool.js"></script>
<!--  校验类  -->
<script src="<%= BASE_URL %>static/js/validator.js"></script>
后端校验

首先新增了 validatorException 类,然后在工具类中增加了校验的方法,接着新增了一个处理 validator 异常的类,最后在 save 方法中添加了校验。

validatorException 类继承 RuntimeException,这样可以不用写 try catch。

package com.course.server.exception;

public class ValidatorException extends RuntimeException{

    public ValidatorException(String message) {
        super(message);
    }
}

接着在工具类中添加了校验的方法

package com.course.server.util;

import com.course.server.exception.ValidatorException;
import org.springframework.util.StringUtils;

public class ValidatorUtil {

    /**
     * 空校验(null or "")
     */
    public static void require(Object str, String fieldName) {
        if (StringUtils.isEmpty(str)) {
            throw new ValidatorException(fieldName + "不能为空");
        }
    }

    /**
     * 长度校验
     */
    public static void length(String str, String fieldName, int min, int max) {
        if (StringUtils.isEmpty(str)) {
            return;
        }
        int length = 0;
        if (!StringUtils.isEmpty(str)) {
            length = str.length();
        }
        if (length < min || length > max) {
            throw new ValidatorException(fieldName + "长度" + min + "~" + max + "位");
        }
    }
}

Controller 层中保存方法在最开始添加校验

// 保存校验
ValidatorUtil.require(chapterDto.getName(), "名称");
ValidatorUtil.require(chapterDto.getCourseId(), "课程ID");
ValidatorUtil.length(chapterDto.getCourseId(), "课程ID", 1, 8);

这时如果校验后不满足会抛出异常,所以添加一个处理 validatorException 异常的方法。

package com.course.business.controller;

import com.course.server.dto.ResponseDto;
import com.course.server.exception.ValidatorException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

@ControllerAdvice
public class ControllerExceptionHandler {

    @ExceptionHandler(value = ValidatorException.class)
    @ResponseBody
    public ResponseDto validatorExceptionHandler(ValidatorException e){
        ResponseDto responseDto = new ResponseDto();
        responseDto.setMessage(e.getMessage());
        responseDto.setSuccess(false);
        return responseDto;
    }
}

这时把前端校验方法注释后可以看到后端的校验正常。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值