SpringBoot2+Vue2实战(十)权限管理

news2025/2/22 17:54:09

一、父子菜单实现

新建数据库表

sys_menu

 sys_role

 实体类

Role

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

import java.io.Serializable;

import lombok.Getter;
import lombok.Setter;

/**
 * <p>
 *
 * </p>
 *
 */
@Getter
@Setter
@TableName("sys_role")
public class Role implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * id
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    /**
     * 名称
     */
    private String name;

    /**
     * 描述
     */
    private String description;


}

Menu 


import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

import java.io.Serializable;
import java.util.List;

import lombok.Getter;
import lombok.Setter;

/**
 * <p>
 *
 * </p>
 *
 * 
 */
@Getter
@Setter
@TableName("sys_menu")
public class Menu implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * id
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    /**
     * 名称
     */
    private String name;

    /**
     * 路径
     */
    private String path;

    /**
     * 图片
     */
    private String icon;

    /**
     * 描述
     */
    private String description;


    @TableField(exist = false)
    private List<Menu> children;


    private Integer pid;


}

RoleController

package com.example.springboot.controller;

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.example.springboot.common.Result;
import com.example.springboot.entity.Role;
import com.example.springboot.service.RoleService;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

@RestController
@RequestMapping("/role")
public class RoleController {

    @Resource
    private RoleService roleService;


    //修改或增加
    @PostMapping("/saveRole")
    public Result saveRole(@RequestBody Role role) {
        //新增或修改
        return Result.success(roleService.saveOrUpdate(role));
    }

    @GetMapping("/findAll")
    public Result findAll() {
        return Result.success(roleService.list());
    }

    @DeleteMapping("/{id}")
    public Result delete(@PathVariable("id") Integer id) {
        return Result.success(roleService.removeById(id));
    }

    //批量删除
    @PostMapping("/del/batch")
    public Result deleteBatch(@RequestBody List<Integer> ids) {
        return Result.success(roleService.removeBatchByIds(ids));
    }

    //分页查询 mybatis-plus方式
    @GetMapping("/selectPage")
    public Result selectPage(@RequestParam(defaultValue = "") String name,
                             @RequestParam Integer pageSize,
                             @RequestParam Integer pageNum) {

        IPage<Role> page = new Page<>(pageNum, pageSize);
        QueryWrapper<Role> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("id");
        if (!"".equals(name)) {
            queryWrapper.like("name", name);
        }
        return Result.success(roleService.page(page, queryWrapper));
    }

}

MneuController


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.example.springboot.common.Result;
import com.example.springboot.entity.Menu;
import com.example.springboot.service.MenuService;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 */
@RestController
@RequestMapping("/menu")
public class MenuController {

    @Resource
    private MenuService menuService;


    //修改或增加
    @PostMapping("/saveMenu")
    public Result saveRole(@RequestBody Menu menu) {
        //新增或修改
        return Result.success(menuService.saveOrUpdate(menu));
    }

    @GetMapping("/findAll")
    public Result findAll(@RequestParam(defaultValue = "") String name) {
        QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("id");
        if (!"".equals(name)) {
            queryWrapper.like("name", name);
        }
        //查询所有数据
        List<Menu> list = menuService.list(queryWrapper);
        List<Menu> parentNode = list.stream().filter(menu -> menu.getPid() == null).collect(Collectors.toList());
        //找出一级菜单的子菜单
        for (Menu menu:parentNode){
            //筛选所有数据中pid等于父级id的数据就是二级菜单
            menu.setChildren(list.stream().filter(m -> menu.getId().equals(m.getPid())).collect(Collectors.toList()));
        }
        return Result.success(parentNode);
    }

    @DeleteMapping("/{id}")
    public Result delete(@PathVariable("id") Integer id) {
        return Result.success(menuService.removeById(id));
    }

    //批量删除
    @PostMapping("/del/batch")
    public Result deleteBatch(@RequestBody List<Integer> ids) {
        return Result.success(menuService.removeBatchByIds(ids));
    }

    //分页查询 mybatis-plus方式
    @GetMapping("/selectPage")
    public Result selectPage(@RequestParam(defaultValue = "") String name,
                             @RequestParam Integer pageSize,
                             @RequestParam Integer pageNum) {

        IPage<Menu> page = new Page<>(pageNum, pageSize);
        QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("id");
        if (!"".equals(name)) {
            queryWrapper.like("name", name);
        }
        return Result.success(menuService.page(page, queryWrapper));
    }
}

router/index.js

{
        path: '/',
        component: () => import('../views/Manage.vue'),
        redirect: "/home",
        children: [
            {path: 'user', name: '用户管理', component: () => import('../views/User.vue'),},
            {path: 'home', name: '首页', component: () => import('../views/Home.vue'),},
            {path: 'role', name: '角色管理', component: () => import('../views/Role.vue'),},
            {path: 'menu', name: '菜单管理', component: () => import('../views/Menu.vue'),},
            {path: 'person', name: '个人信息', component: () => import('../views/Person.vue'),},
            {path: 'file', name: '文件管理', component: () => import('../views/Files.vue'),}
        ]
    },

Role.vue

<template>
  <div>
    <div style="margin: 10px 0">
      <el-input style="width: 200px" placeholder="请输入名称" suffix-icon="el-icon-search"
                v-model="name"></el-input>
      <el-button class="ml-5" type="primary" @click="load">搜索</el-button>
      <el-button type="warning" @click="reset">重置</el-button>
    </div>

    <div style="margin: 10px 0">
      <el-button type="primary" @click="handleAdd">新增 <i class="el-icon-circle-plus-outline"></i></el-button>
      <el-popconfirm
          class="ml-5"
          confirm-button-text='确定'
          cancel-button-text='我再想想'
          icon="el-icon-info"
          icon-color="red"
          title="您确定批量删除这些数据吗?"
          @confirm="delBatch"
      >
        <el-button type="danger" slot="reference">批量删除 <i class="el-icon-remove-outline"></i></el-button>
      </el-popconfirm>
    </div>

    <el-table :data="tableData" border stripe :header-cell-class-name="'headerBg'"
              @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55"></el-table-column>
      <el-table-column prop="id" label="ID" width="80"></el-table-column>
      <el-table-column prop="name" label="名称"></el-table-column>
      <el-table-column prop="description" label="描述"></el-table-column>
      <el-table-column label="操作" width="280" align="center">
        <template slot-scope="scope">
          <el-button type="info" @click="selectMenu(scope.row.id)">分配菜单<i class="el-icon-menu"></i></el-button>
          <el-button type="success" @click="handleEdit(scope.row)">编辑 <i class="el-icon-edit"></i></el-button>
          <el-popconfirm
              class="ml-5"
              confirm-button-text='确定'
              cancel-button-text='我再想想'
              icon="el-icon-info"
              icon-color="red"
              title="您确定删除吗?"
              @confirm="del(scope.row.id)"
          >
            <el-button type="danger" slot="reference">删除<i class="el-icon-remove-outline"></i></el-button>
          </el-popconfirm>
        </template>
      </el-table-column>
    </el-table>
    <div style="padding: 10px 0">
      <el-pagination
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          :current-page="pageNum"
          :page-sizes="[2, 5, 10, 20]"
          :page-size="pageSize"
          layout="total, sizes, prev, pager, next, jumper"
          :total="total">
      </el-pagination>
    </div>

    <el-dialog title="菜单信息" :visible.sync="dialogFormVisible" width="30%">
      <el-form label-width="80px" size="small">
        <el-form-item label="用户名">
          <el-input v-model="form.name" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="描述">
          <el-input v-model="form.description" autocomplete="off"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="save">确 定</el-button>
      </div>
    </el-dialog>


    <el-dialog title="菜单分配" :visible.sync="menuDialogVis" width="30%" style="padding: 0 50px">
      <el-tree
          //使用props进行数据绑定
          :props="props"
          :data="menuData"
          :default-expanded-keys="[1]"
          :default-checked-keys="[4]"
          node-key="id"
          show-checkbox
          @check-change="handleCheckChange">
      </el-tree>
      <div slot="footer" class="dialog-footer">
        <el-button @click="menuDialogVis = false">取 消</el-button>
        <el-button type="primary" @click="save">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
export default {
  name: "Role",
  data() {
    return {
      tableData: [],
      total: 0,
      pageNum: 1,
      pageSize: 2,
      name: "",
      form: {},
      dialogFormVisible: false,
      menuDialogVis: false,
      multipleSelection: [],
      menuData: [],
      props:{
        label:'name'
      }
    }
  },
  created() {
    this.load()
  },
  methods: {
    load() {
      this.request.get("/role/selectPage", {
        params: {
          pageNum: this.pageNum,
          pageSize: this.pageSize,
          name: this.name,
        }
      }).then(res => {
        //注意data
        this.tableData = res.data.records
        this.total = res.data.total
      })

    },


    save() {
      this.request.post("/role/saveRole", this.form).then(res => {
        if (res.code === '200') {
          this.$message.success("保存成功")
          this.dialogFormVisible = false
          this.load()
        } else {
          this.$message.error("保存失败")
        }
      })
    },
    handleAdd() {
      this.dialogFormVisible = true
      this.form = {}
    },
    handleEdit(row) {
      this.form = JSON.parse(JSON.stringify(row))
      this.dialogFormVisible = true
    },
    del(id) {
      this.request.delete("/role/" + id).then(res => {
        if (res.code === '200') {
          this.$message.success("删除成功")
          this.load()
        } else {
          this.$message.error("删除失败")
        }
      })
    },
    handleSelectionChange(val) {
      console.log(val)
      this.multipleSelection = val
    },
    delBatch() {
      let ids = this.multipleSelection.map(v => v.id)  // [{}, {}, {}] => [1,2,3]
      this.request.post("/role/del/batch", ids).then(res => {
        if (res.code === '200') {
          this.$message.success("批量删除成功")
          this.load()
        } else {
          this.$message.error("批量删除失败")
        }
      })
    },
    reset() {
      this.name = ""
      this.load()
    },
    handleSizeChange(pageSize) {
      console.log(pageSize)
      this.pageSize = pageSize
      this.load()
    },
    handleCurrentChange(pageNum) {
      console.log(pageNum)
      this.pageNum = pageNum
      this.load()
    },
    //分配菜单
    selectMenu(roleId) {
      this.menuDialogVis = true

      //请求菜单数据
      this.request.get("/menu/findAll").then(res => {
        //注意data
        this.menuData = res.data
      })

    },
    handleCheckChange(data, checked, indeterminate) {
      console.log(data, checked, indeterminate);
    },
  },

}
</script>


<style>
.headerBg {
  background: #eee !important;
}
</style>

Mneu.vue

<template>
  <div>
    <div style="margin: 10px 0">
      <el-input style="width: 200px" placeholder="请输入名称" suffix-icon="el-icon-search"
                v-model="name"></el-input>
      <el-button class="ml-5" type="primary" @click="load">搜索</el-button>
      <el-button type="warning" @click="reset">重置</el-button>
    </div>

    <div style="margin: 10px 0">
      <el-button type="primary" @click="handleAdd()">新增<i class="el-icon-circle-plus-outline"></i></el-button>
      <el-popconfirm
          class="ml-5"
          confirm-button-text='确定'
          cancel-button-text='我再想想'
          icon="el-icon-info"
          icon-color="red"
          title="您确定批量删除这些数据吗?"
          @confirm="delBatch"
      >
        <el-button type="danger" slot="reference">批量删除 <i class="el-icon-remove-outline"></i></el-button>
      </el-popconfirm>
    </div>

    <el-table :data="tableData" row-key="id" default-expand-all border stripe :header-cell-class-name="'headerBg'"
              @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55"></el-table-column>
      <el-table-column prop="id" label="ID" width="80"></el-table-column>
      <el-table-column prop="name" label="名称"></el-table-column>
      <el-table-column prop="path" label="路径"></el-table-column>
      <el-table-column prop="icon" label="图片"></el-table-column>
      <el-table-column prop="description" label="描述"></el-table-column>
      <el-table-column label="操作" width="280" align="center">
        <template slot-scope="scope">
          <el-button type="primary" @click="handleAdd(scope.row.id)" v-if="!scope.row.pid && !scope.row.path">新增子菜单<i class="el-icon-plus"></i></el-button>
          <el-button type="success" @click="handleEdit(scope.row)">编辑 <i class="el-icon-edit"></i></el-button>
          <el-popconfirm
              class="ml-5"
              confirm-button-text='确定'
              cancel-button-text='我再想想'
              icon="el-icon-info"
              icon-color="red"
              title="您确定删除吗?"
              @confirm="del(scope.row.id)"
          >
            <el-button type="danger" slot="reference">删除<i class="el-icon-remove-outline"></i></el-button>
          </el-popconfirm>
        </template>
      </el-table-column>
    </el-table>

    <el-dialog title="角色信息" :visible.sync="dialogFormVisible" width="30%">
      <el-form label-width="80px" size="small">
        <el-form-item label="菜单名">
          <el-input v-model="form.name" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="路径">
          <el-input v-model="form.path" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="图片">
          <el-input v-model="form.icon" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="描述">
          <el-input v-model="form.description" autocomplete="off"></el-input>
        </el-form-item>

      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="save">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
export default {
  name: "Menu",
  data() {
    return {
      tableData: [],
      total: 0,
      pageNum: 1,
      pageSize: 2,
      name: "",
      form: {},
      dialogFormVisible: false,
      multipleSelection: []
    }
  },
  created() {
    this.load()
  },
  methods: {
    load() {
      this.request.get("/menu/findAll", {
        params: {
          name: this.name,
        }
      }).then(res => {
        //注意data
        this.tableData = res.data
      })
    },


    save() {
      this.request.post("/menu/saveMenu", this.form).then(res => {
        if (res.code === '200') {
          this.$message.success("保存成功")
          this.dialogFormVisible = false
          this.load()
        } else {
          this.$message.error("保存失败")
        }
      })
    },
    handleAdd(pid) {
      this.dialogFormVisible = true
      this.form = {}
      if (pid) {
        this.form.pid = pid
      }
    },
    handleEdit(row) {
      this.form = JSON.parse(JSON.stringify(row))
      this.dialogFormVisible = true
    },
    del(id) {
      this.request.delete("/menu/" + id).then(res => {
        if (res.code === '200') {
          this.$message.success("删除成功")
          this.load()
        } else {
          this.$message.error("删除失败")
        }
      })
    },
    handleSelectionChange(val) {
      console.log(val)
      this.multipleSelection = val
    },
    delBatch() {
      let ids = this.multipleSelection.map(v => v.id)  // [{}, {}, {}] => [1,2,3]
      this.request.post("/menu/del/batch", ids).then(res => {
        if (res.code === '200') {
          this.$message.success("批量删除成功")
          this.load()
        } else {
          this.$message.error("批量删除失败")
        }
      })
    },
    reset() {
      this.name = ""
      this.load()
    },
    handleSizeChange(pageSize) {
      console.log(pageSize)
      this.pageSize = pageSize
      this.load()
    },
    handleCurrentChange(pageNum) {
      console.log(pageNum)
      this.pageNum = pageNum
      this.load()
    }
  }
}
</script>


<style>
.headerBg {
  background: #eee !important;
}
</style>

 

 

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

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

相关文章

分析入手新项目后前后端的接口调用位置以及sql情况

文章目录 查看前端查看后端sql分析数据库分析作者的话 查看前端 比如我们的userList的一个功能&#xff0c;我们刷新页面后会发现当前页面有很多请求&#xff0c;我们根据请求header和param来分析&#xff0c;当前的“用户列表”接口是哪个请求&#xff0c; 我们填入一个参数…

C++ PCL三维点云物体目标识别

程序示例精选 C PCL三维点云物体目标识别 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对<<C PCL三维点云物体目标识别>>编写代码&#xff0c;代码整洁&#xff0c;规则&#xff…

web学习--maven--项目管理工具

写在前面&#xff1a; 这学期搞主攻算法去了&#xff0c;web的知识都快忘了。开始复习学习了。 文章目录 maven介绍功能介绍maven安装jar包搜索仓库 pom文件项目介绍父工程依赖管理属性控制可选依赖构建 依赖管理依赖的传递排除依赖可选依赖 maven生命周期分模块开发模块聚合…

《安全软件开发框架(SSDF) 1.1:降低软件漏洞风险的建议》解读(三)

安全软件开发框架SSDF是由美国国家标准与技术研究院发布的关于安全软件开发的一组实践&#xff0c;帮助开发组织减少发布的软件中的漏洞数量&#xff0c;减少利用未检测到或未解决的漏洞的潜在影响&#xff0c;从根本上解决漏洞防止再次发生。本文根据《Secure Software Develo…

【Nginx05】Nginx学习:HTTP核心模块(二)Server

Nginx学习&#xff1a;HTTP核心模块&#xff08;二&#xff09;Server 第一个重要的子模块就是这个 Server 相关的模块。Server 代表服务的意思&#xff0c;其实就是这个 Nginx 的 HTTP 服务端所能提供的服务。或者更直白点说&#xff0c;就是虚拟主机的配置。通过 Server &…

SpringBoot操作Excel实现导入和导出功能(详细讲解+Gitee源码)

前言&#xff1a;在日常的开发中&#xff0c;避免不了操作Excel&#xff0c;比如从系统当中导出一个报表&#xff0c;或者通过解析客户上传的Excel文件进行批量解析数据入库等等&#xff0c;本篇博客主要汇总日常开发中如何使用开源的Apache提供的POI流操作Excel进行导入导出功…

el-dialog 层级问题混乱

使用 element -UI 的弹窗时&#xff0c;一般来说弹窗的层级应该比较高&#xff0c;背景置灰。 下边这个弹窗是正常情况下的&#xff1a; 有时候出现这样的情况&#xff1a; 解决问题&#xff1a; 只需要 在标签里边添加 append-to-body 属性问题就解决了。

WPF TextBox 添加范围验证

WPF TextBox 添加范围验证 添加范围验证&#xff0c;若出现范围错误添加信息捕捉 使用到技术&#xff1a;使用ValidationRules实现范围验证&#xff0c;当范围出现错误时&#xff0c;可以通过触发器Validation.HasErrorTrue设置自定义错误样式。 使用Behavior技术捕捉所有验证…

1-Nginx介绍及安装(源码安装)

1.Nginx介绍 Nginx&#xff08;engine x&#xff09;是一个轻量级、高性能的HTTP和反向代理服务器&#xff0c;也是一个IMAP/POP3/SMTP服务器。 Nginx特点&#xff1a; ->占用内存少 ->并发能力强(3W/S) 2.Nginx安装 2.1.环境 [rootcentos79-3 ~]# cat /etc/redha…

未来网站开发必备:14个让你惊艳的JavaScript Web API!

微信搜索 【大迁世界】, 我会第一时间和你分享前端行业趋势&#xff0c;学习途径等等。 本文 GitHub https://github.com/qq449245884/xiaozhi 已收录&#xff0c;有一线大厂面试完整考点、资料以及我的系列文章。 快来免费体验ChatGpt plus版本的&#xff0c;我们出的钱 体验地…

进制(数制)及进制之间的转换汇总(超详细)

进制是一种表示数字的方法&#xff0c;它决定了数字在数值系统中的位置和权值。常见的进制包括十进制、二进制、八进制和十六进制。 1. 十进制&#xff08;decimal&#xff09;&#xff1a; 十进制是我们日常生活中最常用的进制&#xff0c;使用0-9这10个数字来表示。每一位的…

小研报 - 神奇的 SD 图(InsCode Stable Diffusion 美图活动一期)

一、 Stable Diffusion 模型 在线使用地址&#xff1a;https://inscode.csdn.net/inscode/Stable-Diffusion 二、模型版本及相关配置 Steps: 20, Sampler: Euler a, CFG scale: 7, Seed: 2391134711, Size: 512x512, Model hash: 74c61c3a52, Model: GuoFeng3, Version: v1.2…

【应用笔记】CW32 电容式触摸按键设计指南

前言 CW32 电容式触摸按键设计指南向客户提供一种利用 CW32 内部资源结合软件编程实现电容式触摸按键有效 触摸检测的方法。本指南的内容重点在于工作原理、软件检测过程以及调试指引。 利用芯源半导体的 CW32 系列小规模 MCU 的 IO、比较器、定时器、高速高精度内置 RC 时钟…

C++ 实现跳表

目录 1.什么是跳表-skiplist 2.skiplist的效率如何保证&#xff1f; 3.skiplist的实现 4.skiplist跟平衡搜索树和哈希表的对比 1.什么是跳表-skiplist skiplist 本质上也是一种查找结构&#xff0c;用于解决算法中的查找问题&#xff0c;跟平衡搜索树和哈希表的价值是一样…

计算机毕业论文内容参考|基于C的空中战机游戏设计与实现

文章目录 导文文章重点摘要前言绪论1课题背景2国内外现状与趋势3课题内容相关技术与方法介绍系统分析系统设计系统实现系统测试总结与展望1本文总结2后续工作展望导文 计算机毕业论文内容参考|基于C的空中战机游戏设计与实现 文章重点 摘要 本文将介绍基于C编程语言的空中战机…

【电影推荐系统】数据加载

目录 数据集 解释 movie.csv ratings.csv tag.csv 数据预处理 mongodb 将数据按照csv文件里的分割符进行分割&#xff0c;转换为DF Moive Rating Tag es 将mongo集合tag 根据mid tag > mid tags(tag1|tag2|tag3...) moive 添加一列 tags 导入后数据库信息 mong…

python爬虫_正则表达式获取天气预报并用echarts折线图显示

文章目录 ⭐前言⭐python re库&#x1f496; re.match函数&#x1f496; re.search函数&#x1f496; re.compile 函数 ⭐正则获取天气预报&#x1f496; 正则实现页面内容提取&#x1f496; echarts的天气折现图 ⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分…

SpringBoot使用EasyExcel批量导出500万数据

SpringBoot使用EasyExcel批量导出500万数据 说明excel版本比较EasyExcel介绍项目目录mysql对应表建表语句pom.xmlapplication.yml配置类启动类代码OrderInfo 实体类OrderInfoExcel excel模版标题类(EasyExcel需要使用这个)TestController控制层接口层TestServiceTestServiceImp…

L298N模块驱动2项4线步进电机的多种方法及其优缺点

摘要&#xff1a;本文将详细介绍L298N模块驱动2项4线步进电机的多种方法&#xff0c;并分析各种方法的优缺点。在实例程序中&#xff0c;将展示不同方法的代码示例&#xff0c;帮助读者理解并实际应用。 引言&#xff1a; 步进电机作为一种常用的电机类型&#xff0c;在许多嵌入…

估值 2 个月从 11 亿美元降到 3 亿美元,投资人清仓跑路,国产大模型创业遇冷...

图片来源&#xff1a;由无界 AI生成 创业未半&#xff0c;而中道崩殂。 6 月 29 日&#xff0c;美团发布公告以 20.65 亿元全资收购光年之外全部权益&#xff0c;距离光年之外正式营业刚过去 84 天。 这是目前中国大模型创业领域最大的收购案&#xff0c;光年之外也在 4 个月时…