Springboot快速整合bootstrap-table使用,接口对接

news2024/7/6 19:03:03

这个表格加持还是不错了,自带了全局搜索,分页,数据导出,卡片视图,等,本次整合添加了数据添加弹窗和编辑数据回显弹窗,附完整页面代码,只需要拿过来替换自己实际的接口即可。

效果图

image-20240325192345466

接口案例

数据列表:

{
  "code": 200,
  "msg": "ok",
  "data": [
    {
      "categoryId": 52,
      "categoryName": "哈哈哈"
    },
    {
      "categoryId": 53,
      "categoryName": "哈哈哈地方"
    },
    {
      "categoryId": 7,
      "categoryName": "悬疑灵异"
    },
    {
      "categoryId": 4,
      "categoryName": "武侠仙侠"
    },
    {
      "categoryId": 3,
      "categoryName": "玄幻奇幻"
    }
  ]
}

增:/novel-category/add

删:/novel-category/delete/{id}

改:/novel-category/update

查:/novel-category/list

批量删:/novel-category/deleteBatch

对应后端实现

package com.xxx.readverse.controller;


import cn.dev33.satoken.util.SaResult;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xxx.readverse.entity.Category;
import com.xxx.readverse.service.CategoryService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;

@Controller
@RequestMapping("/novel-category")
@Api(tags = "小说分类")
@CrossOrigin
public class CategoryController {

    @Autowired
    private CategoryService novelCategoryService;


    @GetMapping("/list")
    @ApiOperation("分类列表")
    @ResponseBody
    public SaResult getNovelCategories() {
        List<Category> categoryList = novelCategoryService.list(new QueryWrapper<Category>().last("limit 12"));
        return SaResult.data(categoryList);
    }

    @PostMapping("/add")
    @ApiOperation("新增分类")
    @ResponseBody
    public SaResult add(Category novelCategory) {
        try {
            novelCategoryService.save(novelCategory);
        } catch (DuplicateKeyException e) {
            return SaResult.error("操作未成功,可能是因为数据重复导致的");
        }
        return SaResult.data(novelCategory.getCategoryId());
    }

    @GetMapping("/deleteBatch")
    @ApiOperation("批量删除")
    @ResponseBody
    public SaResult deleteBatch(@RequestParam("ids") Integer[] ids) {
        novelCategoryService.removeByIds(Arrays.asList(ids));
        return SaResult.ok();
    }

    @GetMapping("/delete/{id}")
    @ApiOperation("删除分类")
    @ResponseBody
    public SaResult delete(@PathVariable Integer id) {
        novelCategoryService.removeById(id);
        return SaResult.ok();
    }

    @PostMapping("/update")
    @ApiOperation("修改分类")
    @ResponseBody
    public SaResult update(Category novelCategory) {
        novelCategoryService.updateById(novelCategory);
        return SaResult.ok();
    }

    @GetMapping("/{id}")
    @ApiOperation("获取某个分类信息")
    @ResponseBody
    public SaResult getById(@PathVariable Integer id) {
        Category category = novelCategoryService.getById(id);
        return  SaResult.data(category);
    }
    
}

页面完整代码

需要注意的问题

  1. 注意依赖引进

  2. 方法异步操作,特别是弹窗组件

  3. 数据项的ID,并不是每个都是id,根据实体数据来确认。

  4. 新增,编辑使用弹窗,控制弹窗的显示和关闭,$(‘xxx’).modal(‘show’), $(‘xxx’).modal(‘hide’)

  5. 基本通用,直接换接口名称就行。

<!doctype html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport"
    content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>表格演示</title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
  <link href="https://cdn.jsdelivr.net/npm/bootstrap-table@1.22.3/dist/bootstrap-table.min.css" rel="stylesheet">

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/bootstrap-table@1.22.3/dist/bootstrap-table.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/bootstrap-table@1.22.3/dist/locale/bootstrap-table-zh-CN.min.js"></script>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.css" rel="stylesheet">
  <script src="https://cdn.jsdelivr.net/npm/tableexport.jquery.plugin@1.28.0/tableExport.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>

  <style>
    .select,
    #locale {
      width: 100%;
    }

    .edit {
      margin-right: 10px;
    }
  </style>
</head>

<body>
  <!-- 新增弹窗 -->
  <!-- Modal Body -->
  <!-- if you want to close by clicking outside the modal, delete the last endpoint:data-bs-backdrop and data-bs-keyboard -->
  <div class="modal fade" id="addModal" tabindex="-1" data-bs-backdrop="static" data-bs-keyboard="false" role="dialog"
    aria-labelledby="modalTitleId" aria-hidden="true">
    <div class="modal-dialog modal-dialog-scrollable modal-dialog-centered modal-md" role="document">
      <form id="addForm">
        <div class="modal-content">
          <div class="modal-header">
            <h5 class="modal-title" id="modalTitleId">
              新增
            </h5>
            <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
          </div>
          <div class="modal-body">
            <div class="form-floating mb-3">
              <input type="text" class="form-control" name="categoryName" id="categoryName" placeholder="" />
              <label for="categoryName">Name</label>
            </div>

          </div>
          <div class="modal-footer">
            <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
              关闭
            </button>
            <button type="reset" class="btn btn-outline-danger">清空</button>
            <button type="submit" class="btn btn-primary">保存</button>
          </div>
        </div>
      </form>
    </div>
  </div>

  <!-- 编辑弹窗 -->
  <!-- Modal Body -->
  <!-- if you want to close by clicking outside the modal, delete the last endpoint:data-bs-backdrop and data-bs-keyboard -->
  <div class="modal fade" id="editModal" tabindex="-1" data-bs-backdrop="static" data-bs-keyboard="false" role="dialog"
    aria-labelledby="modalTitleId" aria-hidden="true">
    <div class="modal-dialog modal-dialog-scrollable modal-dialog-centered modal-md" role="document">
      <form id="editForm">
        <div class="modal-content">
          <div class="modal-header">
            <h5 class="modal-title" id="modalTitleId">
              编辑
            </h5>
            <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
          </div>
          <div class="modal-body">
            <input type="hidden" name="categoryId">
            <div class="form-floating mb-3">
              <input type="text" class="form-control" name="categoryName" id="categoryName" placeholder="" />
              <label for="categoryName">Name</label>
            </div>
          </div>
          <div class="modal-footer">
            <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
              关闭
            </button>
            <button type="reset" class="btn btn-outline-danger">清空</button>
            <button type="submit" class="btn btn-primary">保存</button>
          </div>
        </div>
      </form>
    </div>
  </div>



  <div class="container">
    <!-- 自定义工具栏 -->
    <div id="toolbar">
      <button id="add" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addModal">
        <i class="bi bi-plus-square"></i> 新增
      </button>
      <button id="export" class="btn btn-success">
        <i class="bi bi-file-earmark-spreadsheet"></i> 导出
      </button>
      <button id="remove" class="btn btn-danger" disabled>
        <i class="bi bi-trash"></i> 批量删除
      </button>
    </div>
    <!-- 表格初始化 -->
    <table id="table" data-toolbar="#toolbar" data-search="true" data-show-refresh="true" data-show-toggle="true"
      data-show-fullscreen="true" data-show-columns="true" data-show-columns-toggle-all="true" data-detail-view="true"
      data-show-export="true" data-click-to-select="true" data-detail-formatter="detailFormatter"
      data-minimum-count-columns="2" data-show-pagination-switch="true" data-pagination="true" data-id-field="id"
      data-page-list="[5,10, 25, 50, 100, all]" data-show-footer="true" data-side-pagination="client"
      data-url="/novel-category/list" data-response-handler="responseHandler">
    </table>
  </div>


</body>
<script>
  // 获取组件
  var $table = $('#table')
  var $remove = $('#remove')
  var selections = []

  // 获取被选中行的ID
  function getIdSelections() {
    return $.map($table.bootstrapTable('getSelections'), function (row) {
      return row.categoryId
    })
  }

  // 处理远程响应的数据,可以指定要在表格显示的数据
  function responseHandler(res) {
    return res.data;
  }

  // 自定义显示样式
  function detailFormatter(index, row) {
    var html = []
    $.each(row, function (key, value) {
      html.push('<p><b>' + key + ':</b> ' + value + '</p>')
    })
    return html.join('')
  }

  function operateFormatter(value, row, index) {
    return [
      '<button type="button" class="btn btn-outline-primary edit btn-sm" title="编辑">',
      '<i class="bi bi-pencil"></i> 编辑',
      '</button> ',
      '<button type="button" class="btn btn-outline-danger remove btn-sm" title="删除">',
      '<i class="bi bi-trash"></i> 删除',
      '</button>'
    ].join('');
  }

  // 按钮点击事件
  window.operateEvents = {

    'click .edit': function (e, value, row, index) {
      // 弹窗编辑回显
      $.each(row, function (key, value) {
        $('#editForm input[name="' + key + '"]').val(value);
        // 如果表单字段是<input>标签之外的其他类型,也可以使用类似的方式进行赋值
      });
      $editModal.modal('show');
      // alert('You click edit action, row: ' + JSON.stringify(row))
    },

    // 移除
    'click .remove': async function (e, value, row, index) {
      if (await askDelete()) {
        // 从表格中移除选中的行
        remove(row.categoryId);
      }
    }
  }

  // 表格初始化
  function initTable() {

    $table.bootstrapTable('destroy').bootstrapTable({
      exportDataType: 'all',
      height: 550,
      locale: $('#locale').val(),
      columns: [
        [
          {
            field: 'state',
            checkbox: true,
            align: 'center',
            valign: 'middle'
          },
          {
            title: 'ID编号',
            field: 'categoryId',
            align: 'center',
            valign: 'middle',
            sortable: true,

          },
          {
            title: '分类名',
            field: 'categoryName',
            sortable: true,
            align: 'center'
          },
          {
            field: 'operate',
            title: '操作',
            align: 'center',
            clickToSelect: false,
            events: window.operateEvents,
            formatter: operateFormatter
          }
        ]
      ]
    })
    // 监听表格的选择事件,当表格中的行被选中或取消选中时触发
    $table.on('check.bs.table uncheck.bs.table ' +
      'check-all.bs.table uncheck-all.bs.table',
      function () {
        // 根据当前选中的行的数量来启用或禁用删除按钮
        $remove.prop('disabled', !$table.bootstrapTable('getSelections').length)

        // 保存你的数据,这里只保存当前页的数据
        selections = getIdSelections()
        console.log("当前选中:" + selections)
        // 如果你想要保存所有选中的数据,可以在这里使用 push 或 splice 方法
      })

    // 监听表格的所有事件,用于调试目的
    $table.on('all.bs.table', function (e, name, args) {
      // console.log(name, args)
    })

    // 点击删除按钮时执行的操作
    $remove.click(async function () {
      // 获取所有选中行的 ID
      var ids = getIdSelections()

      if (await askDelete()) {
        // 从表格中移除选中的行
        console.log("要删除的ids:" + ids)
        removeBatch(ids);
        // 禁用删除按钮
        $remove.prop('disabled', true)
      }
    })

  }

  // 绑定导出按钮点击事件
  $('#export').click(function () {
    $table.tableExport({
      type: 'excel', // 导出文件类型,可选 'csv', 'txt', 'sql', 'json', 'xml', 'excel', 'doc', 'png', 'pdf'
      escape: 'false' // 是否使用转义,默认为 true
    });
  });

  $(function () {
    initTable();
    $('#locale').change(initTable)
  })

  // 删除确认弹窗
  async function askDelete() {
    const result = await Swal.fire({
      title: "确定要删除它吗?",
      text: "删除后无法恢复!",
      icon: "warning",
      showCancelButton: true,
      confirmButtonColor: "#3085d6",
      cancelButtonColor: "#d33",
      confirmButtonText: "确定!"
    });

    return result.isConfirmed;
  }

  // 操作提示
  function mess() {
    Swal.fire({
      position: "top-end",
      icon: "success",
      title: "操作OK",
      showConfirmButton: false,
      timer: 1500
    });
  }

  var $addModal = $('#addModal');
  var $editModal = $('#editModal');

  // 新增
  $('#addForm').submit(function (event) {
    event.preventDefault();
    var data = $('#addForm').serialize();
    console.log(data);
    save(data)
    $addModal.modal('hide');
  })




  // 保存编辑
  $('#editForm').submit(function (event) {
    event.preventDefault();
    var data = $('#editForm').serialize();
    console.log(data);
    update(data);
    $editModal.modal('hide');
  })


  function save(data) {
    $.post("/novel-category/add", data, function (data) {
      if (data.code === 200) {
        mess();
        refresh();
      }
    })
  }

  function update(data) {
    $.post("/novel-category/update", data, function (data) {
      if (data.code === 200) {
        mess();
        refresh();
      }
    })
  }

  function remove(id) {
    $.get("/novel-category/delete/" + id, function (data) {
      if (data.code === 200) {
        refresh();
        mess();
      }
    })
  }

  function removeBatch(data) {
    $.get("/novel-category/deleteBatch?ids=" + data.join(','), function (data) {
      if (data.code === 200) {
        mess();
        refresh();
      }
    })
  }


  function refresh() {
    $table.bootstrapTable('refresh');
  }


</script>

</html>

注意数据的对接,特别是每行数据的id项,根据实际数据调整。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1546900.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

轻松掌握C语言中的sqrt函数,快速计算平方根的魔法秘诀

C语言文章更新目录 C语言学习资源汇总&#xff0c;史上最全面总结&#xff0c;没有之一 C/C学习资源&#xff08;百度云盘链接&#xff09; 计算机二级资料&#xff08;过级专用&#xff09; C语言学习路线&#xff08;从入门到实战&#xff09; 编写C语言程序的7个步骤和编程…

ES6 字符串/数组/对象/函数扩展

文章目录 1. 模板字符串1.1 ${} 使用1.2 字符串扩展(1) ! includes() / startsWith() / endsWith()(2) repeat() 2. 数值扩展2.1 二进制 八进制写法2.2 ! Number.isFinite() / Number.isNaN()2.3 inInteger()2.4 ! 极小常量值Number.EPSILON2.5 Math.trunc()2.6 Math.sign() 3.…

力扣hot100:207. 课程表

这是一道拓扑排序问题&#xff0c;也可以使用DFS判断图中是否存在环。详情请见&#xff1a;官方的BFS算法请忽略&#xff0c;BFS将问题的实际意义给模糊了&#xff0c;不如用普通拓扑排序思想。 数据结构&#xff1a;图的拓扑排序与关键路径 拓扑排序&#xff1a; class Sol…

详解:写作和赚钱的 4 个关系!看完你一定会忍不住想开始写!

飞书文档的加密很强&#xff0c;也没有和自家的豆包大模型融合&#xff0c;所以只能通过其他方式获取文档的内容。 &#xff08;1&#xff09;将飞书文档转换为PDF&#xff0c;要用到浏览器插件&#xff1a; GoFullPage - Full Page Screen Capture - Microsoft Edge Addons …

ElasticSearch启动报错:Exception in thread “main“ SettingsException

Exception in thread "main" SettingsException[Failed to load settings from [elasticsearch.yml]]; nested: ParsingException[Failed to parse object: expecting token of type [START_OBJECT] but found [VALUE_STRING]]; 这个报错说明elasticsearch.yml这个配…

垃圾回收:垃圾回收器

目录 垃圾回收器 评估GC的性能指标 7种典型的垃圾回收器 Serial回收器&#xff1a;串行回收 ParNew回收器&#xff1a;并行回收 Parallel回收器&#xff1a;吞吐量优先 CMS回收器&#xff1a;低延迟 G1回收器&#xff1a;区域化分代式 G1回收过程1-年轻代GC G1回收过程…

Java代码基础算法练习-报数问题-2024.03.26

任务描述&#xff1a; 有n个人围成一个圆圈分别编号1~n,从第1个到m循环报数&#xff0c;凡是报到m者离开&#xff0c;求n个 人离开圆圈的次序。 任务要求&#xff1a; 代码示例&#xff1a; package M0317_0331;import java.util.ArrayList; import java.util.List; import j…

档案室升级改造基建方面需要考虑哪些问题

升级和改造档案室可能需要以下材料&#xff1a; 1. 墙壁和地板材料&#xff1a;选择耐用、易于清洁的材料&#xff0c;如瓷砖、大理石、地板、木材或维护低的地毯等。 2. 墙体材料&#xff1a;可能需要新的墙壁材料来分隔出更多的空间&#xff0c;例如石膏板、砖块或玻璃隔断等…

基于RAG的大模型知识库搭建

什么是RAG RAG(Retrieval Augmented Generation)&#xff0c;即检索增强生成技术。 RAG优势 部分解决了幻觉问题。由于我们可以控制检索内容的可靠性&#xff0c;也算是部分解决了幻觉问题。可以更实时。同理&#xff0c;可以控制输入给大模型上下文内容的时效性&#xff0c…

【Java程序设计】【C00369】基于(JavaWeb)Springboot的笔记记录分享平台(有论文)

[TOC]() 博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;已经做了六年的毕业设计程序开发&#xff0c;开发过上千套毕业设计程序&#xff0c;博客中有上百套程序可供参考&#xff0c;欢迎共同交流学习。 项目简介 项目获取 &#x1f345;文末点击…

PTA L2-034 口罩发放

为了抗击来势汹汹的 COVID19 新型冠状病毒&#xff0c;全国各地均启动了各项措施控制疫情发展&#xff0c;其中一个重要的环节是口罩的发放。 某市出于给市民发放口罩的需要&#xff0c;推出了一款小程序让市民填写信息&#xff0c;方便工作的开展。小程序收集了各种信息&…

【MySQL】数据库--库操作

目录 一、创建数据库 二、打开数据库 三、修改数据库 四、显示数据库 五、删除数据库 六、备份与恢复数据库 1.备份&#xff1a; 2.恢复&#xff1a; 一、创建数据库 CREATE DATABASE [IF NOT EXISTS] db_name [create_specification [,create_specification] …] [DEF…

基于springboot的交通管理在线服务系统的开发

传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装交通管理在线服务系统软件来发挥其高效地信息处理的作用&#xff0…

私域必看:让多微信管理事半功倍的妙招!

微信作为中国最大的社交平台之一&#xff0c;是成为私域流量的重要入口。然而&#xff0c;随着私域流量管理的需求增加&#xff0c;如何高效管理多个微信号成为许多企业或是个人的烦恼。 下面就教大家几招&#xff0c;让大家在管理多个微信号时都能事半功倍&#xff0c;轻松把…

xxl-job 适配人大金仓数据库 V8R6

前言 由于一些众所周知的原因&#xff0c;项目需要需要进行改造使其适配人大金仓的数据库。 xxl-job适配人大金仓 特此说明&#xff1a; 当前修改的xxl-job版本 为 2.4.1-SNAPSHOT mysql上的xxl-job库 迁移到 人大金仓数据库上pom中新增依赖 kingbase8 驱动 注意版本<!-…

分布式系统CAP理论

1、什么是CAP理论 C是Consistency(强一致性)、A是Availability(可用性)、P是Partition Tolerance(分区容错性)&#xff0c;一个分布式系统不可能同时很好的满足—致性、可用性和分区容错性这三个需求&#xff0c;不能同时成立&#xff0c;最多只能同时满足其中的两项&#xff…

Vue3使用v-if指令进行条件渲染

Vue3使用v-if指令进行条件渲染 条件渲染是根据条件的真假来有条件地渲染元素。在Vue.js 3.x中&#xff0c;常见的条件渲染包括使用v-if指令和v-show指令。本文讲解使用v-if指令进行条件渲染。 2.3.1 v-if/v-else-if/v-else 在Vue中使用v-if、v-else-if和v-else指令实现条件…

虚拟机VMware分屏操作

虚拟机VMware分屏操作 打开虚拟机设置&#xff0c;选择监视器设置&#xff0c;监视器数量就是要分屏的数量&#xff0c;因为我使用的是两个显示器&#xff0c;所以选择二&#xff0c;下面的分辨率选择自己使用分屏显示器的最大分辨率。 启动虚拟机&#xff0c;打开后选择循环…

为什么建议你尽快入局鸿蒙?

鸿蒙生态的迅速崛起&#xff0c;为广大开发者带来了前所未有的机遇和挑战。尤其是 2024 年&#xff0c;这个被称为“鸿蒙元年”的关键时刻&#xff0c;程序员一定要抓紧机遇&#xff0c;尽早入局鸿蒙&#xff01; 1、市场需求激增 截至 2023 年四季度&#xff0c;HarmonyOS 在…

CAPL - 如何实现弹窗提示和弹窗操作(续)

目录 函数介绍 openPanel closePanel 代码示例 1、简单的打开关闭panel面板