当前位置:   article > 正文

前后端分离项目 Vue3+SpringBoot 后台管理系统_vue3 springboot 管理系统模板

vue3 springboot 管理系统模板

更改端口号

Element-Plus 组件库-Vue3

一个 Vue 3 UI 框架 | Element Plus

安装组件

npm install element-plus --save

搭建界面

引入全局组件

引入 Element-UI 组件库

快速开始 | Element Plus

  1. import App from './App.vue'
  2. import router from './router'
  3. import {createApp} from 'vue'
  4. import store from './store'
  5. import '@/assets/css/global.css'
  6. //ElementUI-Plus完整导入
  7. import ElementPlus from 'element-plus'
  8. import 'element-plus/dist/index.css'
  9. createApp(App).use(store).use(router).use(ElementPlus).mount('#app')

搭建后台管理-基本布局

注意:在 Idea 中,设置 CSS 样式,使用双斜杠//注解会报错

请使用/**/注释

  1. <template>
  2. <div class="common-layout">
  3. <el-container>
  4. <!--头部区域Header-->
  5. <el-header>Header</el-header>
  6. <el-container>
  7. <!--左边:侧边栏区域Aside-->
  8. <el-aside width="200px">Aside</el-aside>
  9. <el-container>
  10. <!--右边:主体区域:主体Main+底部Footer-->
  11. <el-main>Main</el-main>
  12. <el-footer>Footer</el-footer>
  13. </el-container>
  14. </el-container>
  15. </el-container>
  16. </div>
  17. </template>
  18. <script lang="ts" setup>
  19. import {defineComponent} from 'vue';
  20. import HelloWorld from '@/components/HelloWorld.vue'; // @ is an alias to /src
  21. </script>
  22. <style lang="css" scoped>
  23. /*重置布局的内外边距*/
  24. .el-header,
  25. .el-aside,
  26. .el-main,
  27. .el-footer {
  28. margin: 0;
  29. padding: 0;
  30. box-sizing: border-box;
  31. }
  32. /*固定整个页面,防止上下滚动*/
  33. .common-layout {
  34. width: 100%;
  35. height: 100%;
  36. position: fixed;
  37. }
  38. /*头部样式Header:高度占页面的20%*/
  39. .el-header {
  40. width: 100%;
  41. height: 20vh;
  42. background-color: pink;
  43. }
  44. /*侧边栏左侧:Aside:宽度200px,高度占页面的80%*/
  45. .el-aside {
  46. width: 200px;
  47. height: 80vh;
  48. background-color: mediumspringgreen;
  49. }
  50. /*主体右侧:main*/
  51. .el-main {
  52. /*宽度占满,默认不需要给*/
  53. /*高度Height =Header头部-底部Footer*/
  54. height: 70vh;
  55. background-color: bisque;
  56. }
  57. /*底部Footer*/
  58. .el-footer {
  59. height: 10vh;
  60. background-color: aqua;
  61. }
  62. </style>

后端 Java(添加家居博客)

使用 Maven 创建项目+JDK8

SpringBoot整合Mybatis-plus及用法_springboot mybatis plus-CSDN博客

SpringBoot整合Mybatis-plus及用法_springboot mybatis plus-CSDN博客

引入依赖

  1. <!--导入springboot父工程-规定写法-->
  2. <parent>
  3. <artifactId>spring-boot-starter-parent</artifactId>
  4. <groupId>org.springframework.boot</groupId>
  5. <version>2.5.3</version>
  6. </parent>
  7. <dependencies>
  8. <!--引入web starter-->
  9. <dependency>
  10. <groupId>org.springframework.boot</groupId>
  11. <artifactId>spring-boot-starter-web</artifactId>
  12. </dependency>
  13. <!--引入mysql驱动: 这里老师使用版本仲裁 8.0.26-->
  14. <dependency>
  15. <groupId>mysql</groupId>
  16. <artifactId>mysql-connector-java</artifactId>
  17. </dependency>
  18. <!--引入配置处理器 -->
  19. <dependency>
  20. <groupId>org.springframework.boot</groupId>
  21. <artifactId>spring-boot-configuration-processor</artifactId>
  22. </dependency>
  23. <!--引入lombok-->
  24. <dependency>
  25. <groupId>org.projectlombok</groupId>
  26. <artifactId>lombok</artifactId>
  27. </dependency>
  28. <!--引入test starter-->
  29. <dependency>
  30. <groupId>org.springframework.boot</groupId>
  31. <artifactId>spring-boot-starter-test</artifactId>
  32. </dependency>
  33. <!--引入druid依赖-->
  34. <dependency>
  35. <groupId>com.alibaba</groupId>
  36. <artifactId>druid</artifactId>
  37. <version>1.1.17</version>
  38. </dependency>
  39. <!--引入mybatis-plus starter-->
  40. <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
  41. <dependency>
  42. <groupId>com.baomidou</groupId>
  43. <artifactId>mybatis-plus-boot-starter</artifactId>
  44. <version>3.4.3</version>
  45. </dependency>
  46. <!--引入hibernate-validator - 支持了JSR303的数据校验
  47. 老师提醒: 如果小伙伴没有提示6.1.0.Final
  48. 请手动填写
  49. -->
  50. <dependency>
  51. <groupId>org.hibernate</groupId>
  52. <artifactId>hibernate-validator</artifactId>
  53. <version>6.1.0.Final</version>
  54. </dependency>
  55. </dependencies>

新建 application.yml

  1. server:
  2. port: 10100 # 配置启动端口号
  3. spring: #springboot的配置
  4. datasource: #定义数据源
  5. #127.0.0.1为本机测试的ip,3306是mysql的端口号。serverTimezone是定义时区,照抄就好,mysql高版本需要定义这些东西
  6. #useSSL也是某些高版本mysql需要问有没有用SSL连接
  7. url: jdbc:mysql://127.0.0.1:3306/furns_ssm?serverTimezone=GMT%2B8&useSSL=FALSE
  8. username: root #数据库用户名,root为管理员
  9. password: abc123 #该数据库用户的密码
  10. # 使用druid数据源
  11. type: com.alibaba.druid.pool.DruidDataSource
  12. # mybatis-plus相关配置
  13. mybatis-plus:
  14. # xml扫描,多个目录用逗号或者分号分隔(告诉 Mapper 所对应的 XML 文件位置)
  15. mapper-locations: classpath:mapper/*.xml
  16. # 以下配置均有默认值,可以不设置
  17. global-config:
  18. db-config:
  19. #主键类型 AUTO:"数据库ID自增" INPUT:"用户输入ID",ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID";
  20. id-type: auto
  21. #字段策略 IGNORED:"忽略判断" NOT_NULL:"非 NULL 判断") NOT_EMPTY:"非空判断"
  22. field-strategy: NOT_EMPTY
  23. #数据库类型
  24. db-type: MYSQL
  25. configuration:
  26. # 是否开启自动驼峰命名规则映射:从数据库列名到Java属性驼峰命名的类似映射
  27. map-underscore-to-camel-case: true
  28. # 如果查询结果中包含空值的列,则 MyBatis 在映射的时候,不会映射这个字段
  29. call-setters-on-nulls: true
  30. # 这个配置会将执行的sql打印出来,在开发或测试的时候可以用
  31. log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

新建 JavaBean 对象

  1. package com.wwf.entity;
  2. import com.baomidou.mybatisplus.annotation.TableField;
  3. import com.baomidou.mybatisplus.annotation.TableName;
  4. import lombok.AllArgsConstructor;
  5. import lombok.Data;
  6. import lombok.NoArgsConstructor;
  7. import java.math.BigDecimal;
  8. /**
  9. * @author 卒迹
  10. * @version 1.0
  11. */
  12. @Data
  13. @NoArgsConstructor
  14. @AllArgsConstructor
  15. @TableName("furn")
  16. public class Furn {
  17. private Integer id;
  18. private String name;
  19. private String maker;
  20. private BigDecimal price;
  21. private Integer sales;
  22. private Integer stock;
  23. @TableField(value = "img_path")
  24. private String imgPath;
  25. }

新建启动类 MainApplication

并启动测试-查看 MyBatis-Plus 是否成功加载

  1. package com.wwf;
  2. import javafx.beans.property.SetPropertyBase;
  3. import org.mybatis.spring.annotation.MapperScan;
  4. import org.springframework.boot.SpringApplication;
  5. import org.springframework.boot.autoconfigure.SpringBootApplication;
  6. /**
  7. * @author 卒迹
  8. * @version 1.0
  9. */
  10. //指定包扫描路径(Service/Controller...)
  11. @SpringBootApplication(scanBasePackages = {"com.wwf"})
  12. //指定Mapping包扫描路径
  13. @MapperScan(basePackages = {"com.wwf.dao"})
  14. public class MainApplication {
  15. public static void main(String[] args) {
  16. //启动SpringBoot
  17. SpringApplication.run(MainApplication.class, args);
  18. }
  19. }

新建 DAO/Mapper 接口(持久层)

  1. package com.wwf.dao;
  2. import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  3. import com.wwf.entity.Furn;
  4. import org.apache.ibatis.annotations.Mapper;
  5. /**
  6. * @author 卒迹
  7. * @version 1.0
  8. */
  9. @Mapper
  10. public interface FurnMapper extends BaseMapper<Furn> {
  11. // 新建测试类进行测试-内部封装了简单的CRUD
  12. }
新建测试类-MapperTest

Src 文件夹下-新建 test 文件夹以及 resource 文件夹

注意:test 文件夹下的包路径要与 java 的源代码路径要一致

  1. package com.wwf.dao;
  2. import com.wwf.dao.FurnMapper;
  3. import com.wwf.entity.Furn;
  4. import org.junit.jupiter.api.Test;
  5. import org.springframework.boot.test.context.SpringBootTest;
  6. import javax.annotation.Resource;
  7. /**
  8. * @author 卒迹
  9. * @version 1.0
  10. */
  11. @SpringBootTest
  12. public class MapperTest {
  13. // 测试实现了Mapper接口的代理对象的方法CURD
  14. @Resource
  15. private FurnMapper furnMapper;
  16. @Test
  17. public void queryByFurnID() {
  18. System.out.println("furnMapper=" + furnMapper.getClass());
  19. Furn furn = furnMapper.selectById(1);
  20. System.out.println(furn);
  21. }
  22. }
测试-成功如图

新建 Service 接口(业务层)

  1. package com.wwf.service;
  2. import com.baomidou.mybatisplus.extension.service.IService;
  3. import com.wwf.entity.Furn;
  4. /**
  5. * @author 卒迹
  6. * @version 1.0
  7. */
  8. public interface FurnService extends IService<Furn> {
  9. }
新建实现类 ServiceImpl
  1. package com.wwf.service.impl;
  2. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  3. import com.wwf.dao.FurnMapper;
  4. import com.wwf.entity.Furn;
  5. import com.wwf.service.FurnService;
  6. import org.springframework.stereotype.Service;
  7. /**
  8. * @author 卒迹
  9. * @version 1.0
  10. */
  11. @Service
  12. public class FurnServiceImpl extends ServiceImpl<FurnMapper, Furn>
  13. implements FurnService {
  14. }
测试实现类
  1. package com.wwf.service;
  2. import com.wwf.entity.Furn;
  3. import org.junit.jupiter.api.Test;
  4. import org.springframework.boot.test.context.SpringBootTest;
  5. import org.springframework.stereotype.Service;
  6. import javax.annotation.Resource;
  7. /**
  8. * @author 卒迹
  9. * @version 1.0
  10. */
  11. @SpringBootTest
  12. public class FurnServiceImplTest {
  13. @Resource
  14. private FurnService furnService;
  15. @Test
  16. public void queryFurnByID() {
  17. //通过id,查询返回对象
  18. Furn furn = furnService.getById(1);
  19. System.out.println(furn);
  20. }
  21. }
测试-成功如图

Controller(控制层)

后端(查找家居)

1.查询所有的数据

2.根据条件进行查询

家居名 或 厂家 或 供应商

实现思路:如果搜索框为空,则查询所有

否则根据条件进行查询

3.增删改完成后,重新查询家居消息,完成实时刷新

  1. /**
  2. * @author 卒迹
  3. * @version 1.0
  4. */
  5. // 注解:@RestController=@ResponseBody+ @Controller
  6. @RestController
  7. public class FurnController {
  8. // 调用业务层Service的方法
  9. @Resource
  10. private FurnService furnService;
  11. // 这里让ResultResponse继承BizException
  12. // 就可以返回它的父类
  13. @GetMapping("/getAllFurn")
  14. public BizException getAllFurn() {
  15. // 查询所有家居
  16. List<Furn> list = furnService.list();
  17. // 判断当前集合是否为空
  18. if (!list.isEmpty()) {
  19. // 返回请求成功的提示信息,并将该所有家居信息返回
  20. return ResultResponse.success(list);
  21. } else {
  22. //抛出异常,并自定义JSON数据
  23. // errorCode:-1 errorMessage:家居列表为空
  24. return new BizException("-1", "家居列表为空");
  25. }
  26. }
  27. }

前端查找家居

  1. //保存表格的数据: 每一行是一个对象
  2. let tableData = reactive(<any>[]);
  3. //查询所有家居-Axios
  4. function getAllFurn() {
  5. // api/addFurn
  6. request.get("/api/getAllFurn").then((res: any) => {
  7. //console.log("res=", res.data.result)
  8. // 这里根据后端返回的状态码进行判断,并且是数组
  9. if (res.data.code == 2000 && Array.isArray(res.data.result)) {
  10. //先清空列表中的数据,防止重复查询
  11. tableData.length = 0;
  12. //得到该家居数组
  13. const furnList = res.data.result;
  14. //遍历该数组-得到的家居数组
  15. for (const item of furnList) {
  16. tableData.push(item)
  17. }
  18. //提示Message
  19. ElMessage({
  20. message: '查询成功.',
  21. type: 'success',
  22. })
  23. } else if (res.data.errorCode == -1) {
  24. ElMessage({
  25. message: res.data.errorMsg,//根据后端-返回的错误提示信息进行显示
  26. type: 'error',
  27. })
  28. }
  29. })
  30. }
  31. //发送Axios请求-查询家居信息
  32. onMounted(()=>{
  33. getAllFurn();
  34. })
添加家居(后端)

如果在添加过程中,发生了异常,如提交的数据格式不对,

则直接走全局异常处理器

后台直接将该异常进行了捕获

而且不会添加数据成功,并向客户端返回 1 条自定义异常 JSON 数据

  1. package com.wwf.controller;
  2. import com.alibaba.fastjson.JSON;
  3. import com.wwf.entity.Furn;
  4. import com.wwf.exception.BizException;
  5. import com.wwf.exception.ResultResponse;
  6. import com.wwf.service.FurnService;
  7. import org.junit.jupiter.api.Test;
  8. import org.springframework.stereotype.Controller;
  9. import org.springframework.web.bind.annotation.*;
  10. import javax.annotation.Resource;
  11. import javax.websocket.server.PathParam;
  12. import java.awt.print.Book;
  13. import java.math.BigDecimal;
  14. /**
  15. * @author 卒迹
  16. * @version 1.0
  17. */
  18. // 注解:@RestController=@ResponseBody+ @Controller
  19. @RestController
  20. public class FurnController {
  21. // 调用业务层Service的方法
  22. @Resource
  23. private FurnService furnService;
  24. @PostMapping("/addFurn")
  25. public ResultResponse addFurn(@RequestBody Furn furn) {
  26. if (furn.getImgPath() == null) {
  27. // 设置保存的默认图片
  28. furn.setImgPath("assets/images/product-image/1.jpg");
  29. }
  30. boolean isSave = furnService.save(furn);
  31. if (isSave) {// 添加成功
  32. // 这里返回自定义请求响应数据-给到浏览器JSON格式
  33. // throw new BizException("200", "添加成功!");
  34. return ResultResponse.success();
  35. } else {// 添加失败
  36. // throw new BizException("-1", "添加失败!");
  37. return ResultResponse.error("-1","添加失败");
  38. }
  39. }
  40. // 对象→JSON
  41. @Test
  42. public void objcetParseJson() {
  43. // JavaBean → Json
  44. Furn furn = new Furn(null, "小白", "小浣熊", new BigDecimal(150.00), 99, 99, "assets/images/product-image/1.jpg");
  45. String furnJSON = JSON.toJSONString(furn);
  46. System.out.println(furnJSON);
  47. }
  48. }
使用 PostMan 进行测试

提交 JSON 格式的数据

添加 数据到数据库 成功后-返回自定义 JSON 格式的数据

查看数据库

前端(添加家居)

指定发送 JSON 格式的数据给到前端

提交表单 form

前端-弹出框 Dialog+表单 Form

  1. <template>
  2. <el-button type="primary" plain @click="dialogFormVisible = true">
  3. 新增家居
  4. </el-button>
  5. <el-dialog v-model="dialogFormVisible" title="添加家居" width="500">
  6. <el-form :model="form">
  7. <el-form-item label="家居名" :label-width="formLabelWidth">
  8. <el-input v-model="form.name" autocomplete="off"/>
  9. </el-form-item>
  10. <el-form-item label="厂商" :label-width="formLabelWidth">
  11. <el-input v-model="form.name" autocomplete="off"/>
  12. </el-form-item>
  13. <el-form-item label="价格" :label-width="formLabelWidth">
  14. <el-input v-model="form.name" autocomplete="off"/>
  15. </el-form-item>
  16. <el-form-item label="销量" :label-width="formLabelWidth">
  17. <el-input v-model="form.name" autocomplete="off"/>
  18. </el-form-item>
  19. <el-form-item label="库存" :label-width="formLabelWidth">
  20. <el-input v-model="form.name" autocomplete="off"/>
  21. </el-form-item>
  22. </el-form>
  23. <template #footer>
  24. <div class="dialog-footer">
  25. <el-button type="primary" @click="dialogFormVisible = false">
  26. 提交
  27. </el-button>
  28. <el-button @click="dialogFormVisible = false">取消</el-button>
  29. </div>
  30. </template>
  31. </el-dialog>
  32. </template>
  33. <script lang="ts" setup>
  34. import {reactive, ref} from 'vue'
  35. //控制表单:显示true/隐藏false
  36. const dialogFormVisible = ref(false)
  37. const formLabelWidth = '140px'
  38. const form = reactive({
  39. name: '',
  40. region: '',
  41. date1: '',
  42. date2: '',
  43. delivery: false,
  44. type: [],
  45. resource: '',
  46. desc: '',
  47. })
  48. </script>

新增 reuqest.js-路径 Src/utils/request.ts

  1. import axios from 'axios' // 通过 axios 创建对象
  2. const request = axios.create({
  3. timeout: 5000
  4. })
  5. // request 拦截器
  6. // 1. 可以对请求做一些处理
  7. // 2. 比如统一加 token,Content-Type 等
  8. request.interceptors.request.use(config => {
  9. //提交的是JSON格式的数据
  10. config.headers['Content-Type'] = 'application/json;charset=utf-8';
  11. return config
  12. }, error => {
  13. return Promise.reject(error)
  14. });
  15. //导出
  16. export default request

解决跨域问题

  1. const {defineConfig} = require('@vue/cli-service')
  2. module.exports = defineConfig({
  3. transpileDependencies: true,
  4. devServer: {
  5. port: 8080, //设置vue项目本地默认端口, 选填
  6. proxy: { //设置代理,必须填
  7. '/api': { //设置拦截器 拦截器格式 斜杠+拦截器名字,名字可以自己定
  8. target: 'http://域名:端口/Java项目名称', // 代 理 的 目 标 地 址 , 就 是 /api 代 替http: //localhost:10000/
  9. changeOrigin: true, //是否设置同源,输入是的
  10. pathRewrite: { //路径重写
  11. '/api': '' //选择忽略拦截器里面的单词
  12. }
  13. }
  14. }
  15. }
  16. })

当点击按钮新增用户后,触发 add 方法,进行 Axios 请求

  1. //导入request.js
  2. import request from "@/utils/request";
  3. //发送Axios请求-绑定点击事件
  4. function add() {
  5. request.post("/api/save", form).then(res => {
  6. console.log(res)
  7. //发送Axios请求
  8. dialogFormVisible.value = false;//提交后,隐藏弹窗
  9. })
  10. }
  1. /*新增家居-Axios请求*/
  2. //导入request.js
  3. import request from "@/assets/uitls/request";
  4. import {ElMessage} from "element-plus";
  5. //发送Axios请求-绑定点击事件
  6. function add() {
  7. // api/addFurn
  8. request.post("/api/addFurn", form).then((res: any) => {
  9. console.log("res=", res.data.code)
  10. // 判断当前状态码是否等2000,这里根据后端返回的状态码进行判断
  11. if (res.data.code == 2000) {
  12. //提示Message
  13. ElMessage({
  14. message: '添加成功.',
  15. type: 'success',
  16. })
  17. //添加成功后,重新查询
  18. getAllFurn();
  19. //服务器内部发送了错误
  20. } else if (res.data.code == 5000) {
  21. ElMessage({
  22. message: '添加失败.',
  23. type: 'error',
  24. })
  25. }
  26. //发送Axios请求
  27. dialogFormVisible.value = false;//提交后,隐藏表单弹窗
  28. })
  29. }

后端(修改家居-根据 id)

  1. // 修改家居
  2. @PutMapping("/updateFurn")
  3. public BizException updateFurn(@RequestBody Furn furn) {
  4. // System.out.println(furn);
  5. boolean affect = furnService.updateById(furn);
  6. if (affect) {// 修改成功
  7. return ResultResponse.success();
  8. } else {
  9. return new BizException("-1", "修改失败");
  10. }
  11. }

前端(修改家居)

点击编辑按钮,得到当前行的信息

  1. /*点击修改:确定后,触发该方法*/
  2. function update() {
  3. //如果该id,存在则发起修改的请求
  4. if(formupdate.id){
  5. // api/addFurn
  6. request.put("/api/updateFurn", formupdate).then((res: any) => {
  7. //修改成功后,查询查询家居-刷新页面
  8. if(res.data.code==2000){
  9. ElMessage({
  10. message: '修改成功.',
  11. type: 'success',
  12. })
  13. //刷新页面-重新查询家居信息
  14. getAllFurn();
  15. }
  16. if(res.data.errorCode==-1){
  17. ElMessage({
  18. message: res.data.errorMessage,
  19. type: 'error',
  20. })
  21. }
  22. dialogFormVisible2.value = false;//提交后,隐藏弹窗
  23. })
  24. }
  25. }

后端删除家居(根据 id)

@PathVariable与@PathParam区别 - 掘金

  1. // 删除家居
  2. @DeleteMapping("/deleteFurn/{id}")
  3. public BizException deleteFurn(@PathVariable("id") Integer id) {
  4. //先测试id
  5. // System.out.println("id="+id);
  6. boolean isDelete = furnService.removeById(id);
  7. if (isDelete) {
  8. return ResultResponse.success();
  9. } else {
  10. throw new BizException("-1", "删除失败");
  11. }
  12. }

前端删除家居(根据 id)

当用户点击,删除按钮后,提示用户是否需要删除

1.当点击删除按钮后触发 open 函数,

将当前所在行 row 的家居信息当作实参传递

2.当点击按钮后,控制台打印该 row 的值

formDelete 对象

deleteFurn 方法-

注意删除成功,调用查询家居,重新刷新页面

消息弹框组件

MessageBox 消息弹框 | Element Plus

  1. <el-button plain type="danger" @click="open"
  2. >删除
  3. </el-button
  4. >
  1. /*删除按钮*/
  2. import { ElMessageBox } from 'element-plus'
  3. const open = () => {
  4. //弹窗
  5. ElMessageBox.confirm(
  6. '您确认是否删除?',
  7. '警告',
  8. {
  9. confirmButtonText: '确定',
  10. cancelButtonText: '取消',
  11. type: 'warning',
  12. }
  13. )
  14. //点击确认按钮后,触发
  15. .then(() => {
  16. })
  17. //点击取消按钮后,触发
  18. .catch(() => {
  19. ElMessage({
  20. type: 'info',
  21. message: '取消删除',
  22. })
  23. })
  24. }

前端-搜索指定家居

1.点击按钮,得到搜索框的内容

搜索不允许有空格

如果输入了内容,或者输入的内容为不为空.等等.....

才进行查询

2.将该内容发送给后台

  1. //点击搜索按钮,弹出搜索的内容
  2. const getSearchContent = () => {
  3. //搜索的内容不为空
  4. if (search.value != null && search.value != "") {
  5. //发起Axios请求-查询指定家居
  6. queryAppointFurn();
  7. }
  8. }
  9. //Axios查询家居方法
  10. const queryAppointFurn=()=>{
  11. // 根据id进行删除
  12. request.get(`/api/queryAppointFurn/${search.value}`).then((res: any) => {
  13. //修改成功后,查询查询家居-刷新页面
  14. if (res.data.code == 2000) {
  15. ElMessage({
  16. message: '查询成功.',
  17. type: 'success',
  18. })
  19. //将tableData数组清空-将查询的内容重新覆盖
  20. tableData.length=0;
  21. //得到查询的家居信息[数组]
  22. const furnList = res.data.result;
  23. //遍历该家居对象,将当前家居信息逐个添加到tableData数组中
  24. for (const furn of furnList) {
  25. tableData.push(furn)
  26. }
  27. }
  28. if (res.data.code == -1) {
  29. //将tableData数组清空-将查询的内容重新覆盖
  30. tableData.length=0;
  31. console.log("res",res)
  32. ElMessage({
  33. message: res.data.localizedMessage,
  34. type: 'error',
  35. })
  36. }
  37. })
  38. }

后端-搜索指定家居

根据家居名查询,如果没有找到在通过厂商字段maker字段进行查询

1.测试访问地址,查看是否能够得到前端发送的数据

2.根据该数据,进行查询,打印查询的结果

根据家居名或者厂商进行查询

  1. //访问地址:http://localhost:10100/queryAppointFurn/小白
  2. @GetMapping("/queryAppointFurn/{name}")
  3. //这里是通过set方法反射赋值setName
  4. public BizException queryAppointFurn(@PathVariable("name") String furnName) {
  5. // System.out.println(furnName);
  6. //1.根据家居名Name字段-进行查询
  7. QueryWrapper<Furn> furnQueryWrapper = new QueryWrapper<>();
  8. //查询该家居名name的所有家居的信息
  9. furnQueryWrapper.lambda().eq(Furn::getName, furnName);
  10. List<Furn> furnList = furnService.list(furnQueryWrapper);
  11. if (!furnList.isEmpty()) {//结果不为空,则返回该家居名的家居信息
  12. //将结果返回给浏览器JSON
  13. return ResultResponse.success(furnList);
  14. } else if (furnList.isEmpty()) {//如果为空,根据厂商maker字段-进行查询
  15. //注意这里使用或者or
  16. furnQueryWrapper.lambda().or().eq(Furn::getMaker, furnName);
  17. furnList = furnService.list(furnQueryWrapper);
  18. if(!furnList.isEmpty()){
  19. return ResultResponse.success(furnList);
  20. }
  21. }
  22. //都没有找到
  23. throw new BizException("-1","查询结果为空");
  24. }

分页显示-前端

需要将全部查询接口-修改为分页查询接口进行访问

将查询所有家居的方法,修改成调用分页查询的方法

  1. <!-- 分页组件-->
  2. <el-pagination
  3. v-model:current-page="currentPage4"
  4. v-model:page-size="pageSize4"
  5. :page-sizes="[5,10]"
  6. :small="small"
  7. :disabled="disabled"
  8. :background="background"
  9. layout="total, sizes, prev, pager, next, jumper"
  10. :total="total"
  11. @size-change="handleSizeChange"
  12. @current-change="handleCurrentChange"
  13. />
  1. /*底部分页导航*/
  2. // 当前所在页
  3. const currentPage4 = ref(1)
  4. // 默认:每页显示多少条记录
  5. const pageSize4 = ref(5)
  6. // 一共有多少条记录
  7. const total = ref(0)
  8. const small = ref(false)
  9. const background = ref(false)
  10. const disabled = ref(false)
  11. const handleSizeChange = (val: number) => {
  12. console.log(`${val} items per page`)
  13. console.log("当前需修改每页显示几条记录触发")
  14. //每页显示多少条记录
  15. pageSize4.value=val;
  16. queryByPage();//分页显示
  17. }
  18. const handleCurrentChange = (val: number) => {
  19. console.log("点击分页触发")
  20. console.log(`current page: ${val}`)
  21. currentPage4.value=val;
  22. queryByPage();//分页显示
  23. }
  24. /*分页查询*/
  25. const queryByPage=()=>{
  26. // 根据id进行删除
  27. request.get(`/api/furnsByPage`,{
  28. params:{
  29. // pageNum pageSize 与后台请求的参数一致
  30. pageNum:currentPage4.value,
  31. pageSize:pageSize4.value
  32. }
  33. }).then((res: any) => {
  34. //修改成功后,查询查询家居-刷新页面
  35. if (res.data.code == 2000) {
  36. console.log(res.data)
  37. ElMessage({
  38. message: '查询成功.',
  39. type: 'success',
  40. })
  41. //显示一共有多少条记录total
  42. total.value=res.data.result.total
  43. //将tableData数组清空-将查询的内容重新覆盖
  44. tableData.length=0;
  45. //得到查询的家居信息[数组]
  46. const furnList = res.data.result.records;
  47. //遍历该家居对象,将当前家居信息逐个添加到tableData数组中
  48. //这一步是为了能渲染数据
  49. for (const furn of furnList) {
  50. tableData.push(furn)
  51. }
  52. }
  53. if (res.data.code == -1) {
  54. //将tableData数组清空-将之前查询的内容清空
  55. tableData.length=0;
  56. //清空查询的记录数
  57. total.value = 0//将之前查询的记录数,清空
  58. console.log("res",res)
  59. ElMessage({
  60. message: res.data.localizedMessage,
  61. type: 'error',
  62. })
  63. }
  64. })
  65. }

分页显示-后端

  1. /**
  2. * mybatis-plus 分页插件,引入参考 mybatis-plus 官网
  3. */
  4. @Configuration
  5. public class MybatisPlusConfig {
  6. /**
  7. * 分页插件
  8. */
  9. @Bean
  10. public MybatisPlusInterceptor mybatisPlusInterceptor() {
  11. MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
  12. /**
  13. * DbType.MYSQL: 这里根据你的实际情况来指定是什么 DbTye*/
  14. interceptor.addInnerInterceptor
  15. (new PaginationInnerInterceptor(DbType.MYSQL));
  16. return interceptor;
  17. }
  18. }

  1. /**
  2. * 分页查询
  3. * @param pageNum 默认显示第 1
  4. * @param pageSize 默认每页显示 5 条记录*/
  5. @ResponseBody
  6. @RequestMapping("/furnsByPage")
  7. public BizException listFurnsByPage(@RequestParam(defaultValue = "1") Integer pageNum,
  8. @RequestParam(defaultValue = "5") Integer pageSize) {
  9. Page<Furn> furnPage = furnService.page(new Page<>(pageNum, pageSize));
  10. return ResultResponse.success(furnPage);
  11. }

3. 为 方 便 观 察 SQL, 配 置 MyBatis-Plus 日 志 输 出 ,

4. 使 用 Postman 进 行 测 试 , 看 看 分 页 查 询 是 否 OK , 浏 览 器

http://localhost:10100/furnsByPage

分页显示-带检索条件

后端

将之前全局带条件queryAppointFurn

修改该的接口代码,

  1. /** 带检索条件的查询
  2. * @param furnName:
  3. * @return BizException
  4. * @author "卒迹"
  5. * @description TODO
  6. * @date 20:56
  7. */
  8. //访问地址:http://localhost:10100/queryAppointFurn?name=小白
  9. @GetMapping("/queryAppointFurn")
  10. //这里是通过set方法反射赋值setName
  11. // 默认不传pageNum pageSize 则按默认值分页
  12. public BizException queryAppointFurn(@RequestParam(defaultValue = "1") Integer pageNum,
  13. @RequestParam(defaultValue = "5") Integer pageSize,
  14. @RequestParam("name") String furnName) {
  15. // System.out.println(furnName);
  16. //1.根据家居名Name字段-进行查询
  17. QueryWrapper<Furn> furnQueryWrapper = new QueryWrapper<>();
  18. //查询该家居名name的所有家居的信息
  19. furnQueryWrapper.lambda().eq(Furn::getName, furnName);
  20. //并且分页显示
  21. Page<Furn> page =
  22. furnService.page(new Page<>(pageNum, pageSize), furnQueryWrapper);
  23. //测试得到的数据
  24. // System.out.println("page="+page);
  25. if (!page.getRecords().isEmpty()) {//结果不为空,则返回该家居名的家居信息
  26. //将结果返回给浏览器JSON
  27. return ResultResponse.success(page);
  28. } else if (page.getRecords().isEmpty()) {//如果为空,根据厂商maker字段-进行查询
  29. //注意这里使用或者or
  30. furnQueryWrapper.lambda().or().eq(Furn::getMaker, furnName);
  31. page =
  32. furnService.page(new Page<>(pageNum, pageSize), furnQueryWrapper);
  33. if(!page.getRecords().isEmpty()){
  34. return ResultResponse.success(page);
  35. }
  36. }
  37. //都没有找到
  38. throw new BizException("-1","查询结果为空");
  39. }

使用 PostMan 进行测试

前端

http://localhost:10100/queryAppointFurn?name=小白

根据接口文档-来进行发起 Axios

将之前的检索条件查询-增加分页查询的功能

  1. export interface pageAppointRequest {
  2. /**
  3. * 检索条件
  4. */
  5. name: any;
  6. /**
  7. * 从第几页开始显示,默认从第1页显示
  8. */
  9. pageNum?: number;
  10. /**
  11. * 每页显示多少条,默认显示5条数据
  12. */
  13. PageSize?: number;
  14. [property: string]: any;
  15. }
  16. /*pageAppointRequest 规范了传输的数据类型格式*/
  17. const queryAppointFurn: pageAppointRequest = () => {
  18. // 根据id进行删除
  19. request.get(`/api/queryAppointFurn`, {
  20. params: {
  21. name: search.value,
  22. pageNum: currentPage4.value,
  23. pageSize: pageSize4.value
  24. },
  25. }).then((res: any) => {
  26. //修改成功后,查询查询家居-刷新页面
  27. if (res.data.code == 2000) {
  28. ElMessage({
  29. message: '查询成功.',
  30. type: 'success',
  31. })
  32. //显示一共有多少条查询记录total
  33. total.value = res.data.result.total
  34. //将tableData数组清空-将查询的内容重新覆盖
  35. tableData.length = 0;
  36. //得到查询的家居信息[数组]
  37. const furnList = res.data.result.records;
  38. //遍历该家居对象,将当前家居信息逐个添加到tableData数组中
  39. for (const furn of furnList) {
  40. tableData.push(furn)
  41. }
  42. }//没有查询到
  43. if (res.data.code == -1) {
  44. //将tableData数组清空-将查询的内容重新覆盖
  45. tableData.length = 0;
  46. //显示一共有多少条查询记录total
  47. total.value = 0//将之前查询的记录数,清空
  48. console.log("res", res)
  49. ElMessage({
  50. message: res.data.localizedMessage,
  51. type: 'error',
  52. })
  53. }
  54. })
  55. }

解决:点击分页按钮后,不按检索内容进行分页

handlerSiezChange/handleCurrnetChange 方法

在点击分页按钮后触发

表单校验(前端)

  1. rules: {
  2. name: [
  3. {required: true, message: '请输入称家居名', trigger: 'blur'}
  4. ],maker: [
  5. {required: true, message: '请输入称制造商', trigger: 'blur'}
  6. ],price: [
  7. {required: true, message: '请输入价格', trigger: 'blur'}, {pattern: /^(([1-9]\d*)|(0))(\.\d+)?$/, message: '请输入数字', trigger: 'blur'}
  8. ],sales: [
  9. {required: true, message: '请输入销量', trigger: 'blur'}, {pattern: /^(([1-9]\d*)|(0))$/, message: '请输入数字', trigger: 'blur'}
  10. ],stock: [
  11. {required: true, message: '请输入库存', trigger: 'blur'}, {pattern: /^(([1-9]\d*)|(0))$/, message: '请输入数字', trigger: 'blur'}
  12. ]
  13. }

表格校验(后端)

NotNull: 基本数据类型

NotEmpty: 数组或者集合

NotBlank: 字符串 String

常用的校验注解之 @NotNull、@NotBlank、@NotEmpty 的区别-CSDN博客

@NotEmpty、@NotBlank、@NotNull的区别_notblank和notempty-CSDN博客

简单做了非空校验

  1. /**
  2. * @author 卒迹
  3. * @version 1.0
  4. */
  5. public class ErrorUtils {
  6. /**
  7. * 错误信息验证 如果返回的容器为空,则表示验证通过,否则验证不通过
  8. *
  9. * @param errors:
  10. * @return Map<String, String>
  11. * @author "卒迹"
  12. * @description TODO
  13. * @date 1:53
  14. */
  15. public static Map<String, String> errorMessageVerification(Errors errors) {
  16. // 定义1个保存错误信息的容器:key:字段名 value:错误提示信息
  17. ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>();
  18. List<FieldError> fieldErrors = errors.getFieldErrors();// 得到所有的错误信息的字段
  19. for (FieldError fieldError : fieldErrors) {// 遍历该容器
  20. String field = fieldError.getField();// 字段
  21. String defaultMessage = fieldError.getDefaultMessage();// 错误默认提示信息
  22. map.put(field, defaultMessage);// 将字段与错误信息保存到容器中
  23. }
  24. return map;///返回该容器
  25. }
  26. /**
  27. * 用于判断校验是否成功
  28. *
  29. * @param errors:
  30. * @return boolean
  31. * @author "卒迹"
  32. * @description TODO
  33. * @date 2:05
  34. */
  35. public static boolean isEmptyErrorMessage(Errors errors) {
  36. // 判断得到的容器是否为空,如果为空,则校验成功,否则校验失败
  37. Map<String, String> map = errorMessageVerification(errors);
  38. if (map.isEmpty()) {
  39. return true;
  40. }
  41. return false;
  42. }
  43. }

调用该工具类,返回保存错误信息的容器

使用 PostMan 进行验证

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/504911
推荐阅读
相关标签
  

闽ICP备14008679号