day07_分類管理EasyExcel品牌管理

文章目錄

  • 1 分類管理
    • 1.1 菜單添加
    • 1.2 表結構介紹
    • 1.3 頁面制作
    • 1.4 列表查詢
      • 1.4.1 需求分析
      • 1.4.2 后端接口
        • Category
        • CategoryController
        • CategoryService
        • CategoryMapper
        • CategoryMapper.xml
      • 1.4.3 前端對接
        • category.js
        • category.vue
  • 2 EasyExcel
    • 2.1 數據導入導出意義
    • 2.2 EasyExcel簡介
    • 2.3 入門案例
      • 2.3.1 解析Excel數據
      • 2.3.2 存儲數據到Excel
    • 2.4 導出功能
      • 2.4.1 需求說明
      • 2.4.2 后端接口
        • CategoryController
        • CategoryService
        • CategoryMapper
        • CategoryMapper.xml
      • 2.4.3 前端對接
        • category.js
        • category.vue
    • 2.5 導入功能
      • 2.5.1 需求說明
      • 2.5.2 后端接口
        • CategoryController
        • CategoryService
        • CategoryMapper
        • CategoryMapper.xml
      • 2.5.3 前端對接
  • 3 品牌管理
    • 3.1 菜單添加
    • 3.2 表結構介紹
    • 3.3 頁面制作
    • 3.4 列表查詢
      • 3.4.1 后端接口
        • Brand
        • BrandController
        • BrandService
        • BrandMapper
        • BrandMapper.xml
      • 3.4.2 前端對接
        • brand.js
        • brand.vue
    • 3.5 品牌添加
      • 3.5.1 需求說明
      • 3.5.2 頁面制作
      • 3.5.3 后端接口
        • BrandController
        • BrandService
        • BrandMapper
        • BrandMapper.xml
      • 3.5.4 前端對接
        • brand.js
        • brand.vue
    • 3.6 修改品牌
      • 3.6.1 需求說明
      • 3.6.2 數據回顯
      • 3.6.3 提交修改
        • 后端接口
          • BrandController
          • BrandService
          • BrandMapper
          • BrandMapper.xml
        • 前端對接
          • brand.js
          • brand.vue
    • 3.7 刪除品牌
      • 3.7.1 需求說明
      • 3.7.2 后端接口
        • BrandController
        • BrandService
        • BrandMapper
        • BrandMapper.xml
      • 3.7.3 前端對接
        • brand.js
        • brand.vue

1 分類管理

分類管理就是對商品的分類數據進行維護。常見的分類數據:電腦辦公、手機、家居家裝、汽車用品…

1.1 菜單添加

首先在系統中添加分類管理的菜單,具體步驟如下所示:

1、在后臺管理系統中通過系統管理的菜單管理添加分類管理的相關菜單,如下所示:

在這里插入圖片描述

2、給系統管理員角色分配分類管理菜單訪問權限:

在這里插入圖片描述

3、在前端項目中創建對應的頁面,以及配置對應的異步路由

在src/views/product的文件夾,在該文件夾中加入分類管理頁面文件,如下所示

在這里插入圖片描述

在src/router/modules文件夾下創建product.js路由文件,文件內容如下所示:

const Layout = () => import('@/layout/index.vue')
const category = () => import('@/views/product/category.vue')export default [{path: '/product',component: Layout,name: 'product',meta: {title: '商品管理',},icon: 'Histogram',children: [{path: '/category',name: 'category',component: category,meta: {title: '分類管理',},},],},
]

在src/router/index.js中添加異步路由,如下所示:

import product from './modules/product'// 動態菜單
export const asyncRoutes = [...system,...base,...product]

1.2 表結構介紹

分類數據所對應的表結構如下所示:

CREATE TABLE `category` (`id` bigint NOT NULL AUTO_INCREMENT COMMENT '分類id',`name` varchar(50) DEFAULT NULL COMMENT '分類名稱',`image_url` varchar(200) DEFAULT NULL,`parent_id` bigint DEFAULT NULL COMMENT '父分類id',`status` tinyint DEFAULT NULL COMMENT '是否顯示[0-不顯示,1顯示]',`order_num` int DEFAULT NULL COMMENT '排序',`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創建時間',`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',`is_deleted` tinyint NOT NULL DEFAULT '0' COMMENT '刪除標記(0:不可用 1:可用)',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=704 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='商品分類';

注意:分類數據是具有層級結構的,因此在進行數據展示的時候可以考慮使用樹形表格進行展示。在咱們的尚品甄選項目中關于分類的數據只支持三級。

1.3 頁面制作

對比如下頁面結構,使用Element Plus制作出對應的頁面,數據可以暫時使用假數據。

在這里插入圖片描述

該頁面可以將其分為2部分:

1、導入導出按鈕

2、分類列表展示【樹形表格】

代碼實現如下所示:

<template><div class="tools-div"><el-button type="success" size="small" >導出</el-button><el-button type="primary" size="small" >導入</el-button></div><!---懶加載的樹形表格--><el-table:data="list"style="width: 100%"row-key="id"borderlazy:load="fetchData":tree-props="{ children: 'children', hasChildren: 'hasChildren' }"><el-table-column prop="name" label="分類名稱" /><el-table-column prop="imageUrl" label="圖標" #default="scope"><img :src="scope.row.imageUrl" width="50" /></el-table-column><el-table-column prop="orderNum" label="排序" /><el-table-column prop="status" label="狀態" #default="scope">{{ scope.row.status == 1 ? '正常' : '停用' }}</el-table-column><el-table-column prop="createTime" label="創建時間" /></el-table></template><script setup>
import { ref } from 'vue';// 定義list屬性模型
const list = ref([{"id":1 , "name":"數碼" , "orderNum":"1" , "status":1 , "createTime":"2023-05-22" , "hasChildren": true},{"id":2 , "name":"手機" , "orderNum":"1", "status":1, "createTime":"2023-05-22"},
])// 加載數據的方法
const fetchData = (row, treeNode, resolve) => {// 向后端發送請求獲取數據const data = [{"id":3 , "name":"智能設備" , "orderNum":"1" , "status":1 , "createTime":"2023-05-22" },{"id":4 , "name":"電子教育" , "orderNum":"2" , "status":1 , "createTime":"2023-05-22" },]// 返回數據resolve(data)}</script><style scoped>
.search-div {margin-bottom: 10px;padding: 10px;border: 1px solid #ebeef5;border-radius: 3px;background-color: #fff;
}
.tools-div {margin: 10px 0;padding: 10px;border: 1px solid #ebeef5;border-radius: 3px;background-color: #fff;
}
</style>

1.4 列表查詢

1.4.1 需求分析

當頁面初始化完畢以后,此時就需要從請求后端接口查詢所有的一級分類數據,一級分類數據的parent_id為0。當用戶點擊某一個分類前的小箭頭,那么此時就需要查詢該分類下所對應的所有的子分類數據。對應的sql語句如下所示:

select * from category where parent_id = 0 ;

1.4.2 后端接口

Category

定義一個與數據庫表相對應的實體類:

// com.atguigu.spzx.model.entity.product
@Data
public class Category extends BaseEntity {private String name;private String imageUrl;private Long parentId;private Integer status;private Integer orderNum;private Boolean hasChildren;private List<Category> children;}
CategoryController

表現層代碼實現:

// com.atguigu.spzx.manager.controller
@RestController
@RequestMapping(value="/admin/product/category")
public class CategoryController {@Autowiredprivate CategoryService categoryService;@Operation(summary = "根據parentId獲取下級節點")@GetMapping(value = "/findByParentId/{parentId}")public Result<List<Category>> findByParentId(@PathVariable Long parentId) {List<Category> list = categoryService.findByParentId(parentId);return Result.build(list , ResultCodeEnum.SUCCESS) ;}
}
CategoryService

業務層代碼實現:

// com.atguigu.spzx.manager.service.impl
@Service
public class CategoryServiceImpl implements CategoryService {@Autowiredprivate CategoryMapper categoryMapper ;@Overridepublic List<Category> findByParentId(Long parentId) {// 根據分類id查詢它下面的所有的子分類數據List<Category> categoryList = categoryMapper.selectByParentId(parentId);if(!CollectionUtils.isEmpty(categoryList)) {// 遍歷分類的集合,獲取每一個分類數據categoryList.forEach(item -> {// 查詢該分類下子分類的數量int count = categoryMapper.countByParentId(item.getId());if(count > 0) {item.setHasChildren(true);} else {item.setHasChildren(false);}});}return categoryList;}}
CategoryMapper

持久層代碼實現:

@Mapper
public interface CategoryMapper {public abstract List<Category> selectByParentId(Long parentId);public abstract int countByParentId(Long id);
}
CategoryMapper.xml

映射文件中添加如下的sql語句:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.spzx.manager.mapper.CategoryMapper"><resultMap id="categoryMap" type="com.atguigu.spzx.model.entity.product.Category" autoMapping="true"></resultMap><!-- 用于select查詢公用抽取的列 --><sql id="columns">id,name,image_url,parent_id,status,order_num,create_time,update_time,is_deleted</sql><select id="selectByParentId" resultMap="categoryMap">select <include refid="columns" />from categorywhere parent_id = #{parentId}and is_deleted = 0order by id desc</select><select id="countByParentId" resultType="Integer">select count(id)from categorywhere parent_id = #{parentId}and is_deleted = 0</select></mapper>

1.4.3 前端對接

category.js

在src/api文件夾下創建一個category.js文件,文件的內容如下所示:

import request from '@/utils/request'const api_name = '/admin/product/category'// 根據parentId獲取下級節點
export const FindCategoryByParentId = parentId => {return request({url: `${api_name}/findByParentId/${parentId}`,method: 'get',})
}
category.vue

修改category.vue文件,內容如下所示:

<script setup>
import { ref , onMounted} from 'vue';
import { FindCategoryByParentId } from '@/api/category.js'// 定義list屬性模型
const list = ref([])// 頁面初始化完畢以后請求后端接口查詢數據
onMounted(async () => {const {code , data , message} = await FindCategoryByParentId(0)list.value = data ; 
})// 加載數據的方法
const fetchData = async (row, treeNode, resolve) => {// 向后端發送請求獲取數據const {code , data , message} = await FindCategoryByParentId(row.id)// 返回數據resolve(data)}</script>

2 EasyExcel

2.1 數據導入導出意義

后臺管理系統是管理、處理企業業務數據的重要工具,在這樣的系統中,數據的導入和導出功能是非常重要的,其主要意義包括以下幾個方面:

1、提高數據操作效率:手動逐條添加或修改數據不僅費時費力,而且容易出錯,此時就可以將大量數據從Excel等表格軟件中導入到系統中時,通過數據導入功能,可以直接將表格中的數據批量導入到系統中,提高了數據操作的效率。

2、實現數據備份與遷移:通過數據導出功能,管理員可以將系統中的數據導出為 Excel 或其他格式的文件,以實現數據備份,避免數據丟失。同時,也可以將導出的數據文件用于數據遷移或其他用途。

3、方便企業內部協作:不同部門可能會使用不同的系統或工具進行數據處理,在這種情況下,通過數據導入和導出功能,可以方便地轉換和共享數據,促進企業內部協作。

2.2 EasyExcel簡介

官網地址:https://easyexcel.opensource.alibaba.com/

在這里插入圖片描述

EasyExcel 的主要特點如下:

1、高性能:EasyExcel 采用了異步導入導出的方式,并且底層使用 NIO 技術實現,使得其在導入導出大數據量時的性能非常高效。

2、易于使用:EasyExcel 提供了簡單易用的 API,用戶可以通過少量的代碼即可實現復雜的 Excel 導入導出操作。

3、增強的功能“EasyExcel 支持多種格式的 Excel 文件導入導出,同時還提供了諸如合并單元格、數據校驗、自定義樣式等增強的功能。

4、可擴展性好:EasyExcel 具有良好的擴展性,用戶可以通過自定義 Converter 對自定義類型進行轉換,或者通過繼承 EasyExcelListener 來自定義監聽器實現更加靈活的需求。

2.3 入門案例

2.3.1 解析Excel數據

需求:對資料中的excel數據進行解析,將其存儲到對應的List集合中,并遍歷List集合

步驟:

1、在spzx-model的pom.xml文件中添加如下依賴:

<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId>
</dependency>
<dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId>
</dependency>

2、定義一個實體類來封裝每一行的數據,如下所示:

// com.atguigu.spzx.model.vo.product
@Data
public class CategoryExcelVo {@ExcelProperty(value = "id" ,index = 0)private Long id;@ExcelProperty(value = "名稱" ,index = 1)private String name;@ExcelProperty(value = "圖片url" ,index = 2)private String imageUrl ;@ExcelProperty(value = "上級id" ,index = 3)private Long parentId;@ExcelProperty(value = "狀態" ,index = 4)private Integer status;@ExcelProperty(value = "排序" ,index = 5)private Integer orderNum;
}

3、定義一個監聽器,監聽解析到的數據,如下所示:

public class ExcelListener<T> extends AnalysisEventListener<T> {//可以通過實例獲取該值private List<T> datas = new ArrayList<>();@Overridepublic void invoke(T o, AnalysisContext analysisContext) {  // 每解析一行數據就會調用一次該方法datas.add(o);//數據存儲到list,供批量處理,或后續自己業務邏輯處理。}public List<T> getDatas() {return datas;}@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {// excel解析完畢以后需要執行的代碼}}

4、編寫測試方法

public class EasyExcelTest {@Testpublic void easyExcelReadTest() {String fileName = "E://分類數據.xlsx" ;ExcelListener<CategoryExcelVo> excelListener = new ExcelListener<>();  // 創建一個監聽器對象EasyExcel.read(fileName, CategoryExcelVo.class, excelListener).sheet().doRead();    // 解析excel表格List<CategoryExcelVo> excelVoList = excelListener.getDatas();       // 獲取解析到的數據excelVoList.forEach(s -> System.out.println(s) );   // 進行遍歷操作}}

2.3.2 存儲數據到Excel

需求:將如下的集合數據存儲到Excel中文件中

List<CategoryExcelVo> list = new ArrayList<>() ;
list.add(new CategoryExcelVo(1L , 0L , "數碼辦公" , 1 , 1)) ;
list.add(new CategoryExcelVo(2L , 1L , "手機通訊" , 1 , 1)) ;
list.add(new CategoryExcelVo(3L , 2L , "手機" , 1 , 0)) ;

代碼實現:

@Test
public void saveDataToExcel() {List<CategoryExcelVo> list = new ArrayList<>() ;list.add(new CategoryExcelVo(1L , 0L , "數碼辦公" , 1 , 1)) ;list.add(new CategoryExcelVo(2L , 1L , "手機通訊" , 1 , 1)) ;list.add(new CategoryExcelVo(3L , 2L , "手機" , 1 , 0)) ;EasyExcel.write("D://分類數據.xlsx" , CategoryExcelVo.class).sheet("分類數據").doWrite(list);
}

2.4 導出功能

2.4.1 需求說明

當用戶點擊導出按鈕的時候,此時將數據庫中的所有的分類的數據導出到一個excel文件中,如下所示:

在這里插入圖片描述

2.4.2 后端接口

CategoryController

表現層代碼實現:

// com.atguigu.spzx.manager.controller#CategoryController
@GetMapping(value = "/exportData")
public void exportData(HttpServletResponse response) {categoryService.exportData(response);
}
CategoryService

業務層代碼實現:

// com.atguigu.spzx.manager.service.impl#CategoryServiceImpl
@Override
public void exportData(HttpServletResponse response) {try {// 設置響應結果類型response.setContentType("application/vnd.ms-excel");response.setCharacterEncoding("utf-8");// 這里URLEncoder.encode可以防止中文亂碼 當然和easyexcel沒有關系String fileName = URLEncoder.encode("分類數據", "UTF-8");response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");// 查詢數據庫中的數據List<Category> categoryList = categoryMapper.selectAll();List<CategoryExcelVo> categoryExcelVoList = new ArrayList<>(categoryList.size());// 將從數據庫中查詢到的Category對象轉換成CategoryExcelVo對象for(Category category : categoryList) {CategoryExcelVo categoryExcelVo = new CategoryExcelVo();BeanUtils.copyProperties(category, categoryExcelVo, CategoryExcelVo.class);categoryExcelVoList.add(categoryExcelVo);}// 寫出數據到瀏覽器端EasyExcel.write(response.getOutputStream(), CategoryExcelVo.class).sheet("分類數據").doWrite(categoryExcelVoList);} catch (IOException e) {e.printStackTrace();}
}
CategoryMapper

持久層代碼實現:

@Mapper
public interface CategoryMapper {public abstract List<Category> selectAll();
}
CategoryMapper.xml

在映射文件中添加如下sql語句:

<select id="selectAll" resultMap="categoryMap">select <include refid="columns" />from categorywhere is_deleted = 0order by id
</select>

2.4.3 前端對接

category.js

在src/api文件夾下創建一個category.js文件,文件的內容如下所示:

// 導出方法
export const ExportCategoryData = () => {return request({url: `${api_name}/exportData`,method: 'get',responseType: 'blob'  // 這里指定響應類型為blob類型,二進制數據類型,用于表示大量的二進制數據})
}
category.vue

修改category.vue文件,內容如下所示:

<div class="tools-div"><el-button type="success" size="small" @click="exportData">導出</el-button>
</div><script setup>
import { ExportCategoryData } from '@/api/category.js'const exportData = () => {// 調用 ExportCategoryData() 方法獲取導出數據ExportCategoryData().then(res => {// 創建 Blob 對象,用于包含二進制數據const blob = new Blob([res]);             // 創建 a 標簽元素,并將 Blob 對象轉換成 URLconst link = document.createElement('a'); link.href = window.URL.createObjectURL(blob);// 設置下載文件的名稱link.download = '分類數據.xlsx';// 模擬點擊下載鏈接link.click();})  
}
</script>

2.5 導入功能

2.5.1 需求說明

當用戶點擊導入按鈕的時候,此時會彈出一個對話框,讓用戶選擇要導入的excel文件,選擇完畢以后將文件上傳到服務端,服務端通過easyExcel解析文件的內容,然后將解析的結果存儲到category表中。如下所示:

在這里插入圖片描述

2.5.2 后端接口

CategoryController

表現層代碼實現:

// com.atguigu.spzx.manager.controller#CategoryController
@PostMapping("importData")
public Result importData(MultipartFile file) {categoryService.importData(file);return Result.ok();
}
CategoryService

業務層代碼實現:

// com.atguigu.spzx.manager.service.impl#CategoryServiceImpl
@Override
public void importData(MultipartFile file) {// 使用EasyExcel解析數據List<CategoryExcelVo> categoryExcelVoList = ExcelHelper.importExcel(file, CategoryExcelVo.class);List<Category> categoryList = new ArrayList<>();// 如果解析到的數據不為空,那么此時將解析到的對象轉換成Category對象if(!CollectionUtils.isEmpty(categoryExcelVoList)) {for(CategoryExcelVo categoryExcelVo : categoryExcelVoList) {Category category = new Category();BeanUtils.copyProperties(categoryExcelVo, category, Category.class);categoryList.add(category);}// 進行數據的批量保存categoryMapper.batchInsert(categoryList);}
}
CategoryMapper

持久層代碼實現:

@Mapper
public interface CategoryMapper {public abstract void batchInsert(List<Category> categoryList);
}
CategoryMapper.xml

映射文件中添加如下sql語句:

<insert id="batchInsert" useGeneratedKeys="true" keyProperty="id">insert into category (id,name,image_url,parent_id,status,order_num,create_time ,update_time ,is_deleted) values<foreach collection="categoryList" item="item" separator="," >(#{item.id},#{item.name},#{item.imageUrl},#{item.parentId},#{item.status},#{item.orderNum},now(),now(),0)</foreach>
</insert>

2.5.3 前端對接

修改category.vue文件,內容如下所示:

<div class="tools-div"><el-button type="primary" size="small" @click="importData">導入</el-button>
</div><el-dialog v-model="dialogImportVisible" title="導入" width="30%"><el-form label-width="120px"><el-form-item label="分類文件"><el-uploadclass="upload-demo"action="http://localhost:8501/admin/product/category/importData":on-success="onUploadSuccess":headers="headers"><el-button type="primary">上傳</el-button></el-upload></el-form-item></el-form>
</el-dialog><script setup>
import { useApp } from '@/pinia/modules/app'// 文件上傳相關變量以及方法定義
const dialogImportVisible = ref(false)
const headers = {token: useApp().authorization.token // 從pinia中獲取token,在進行文件上傳的時候將token設置到請求頭中
}
const importData = () => {dialogImportVisible.value = true
}// 上傳文件成功以后要執行方法
const onUploadSuccess = async (response, file) => {ElMessage.success('操作成功')dialogImportVisible.value = falseconst { data } = await FindCategoryByParentId(0)list.value = data ; 
}
</script>

3 品牌管理

品牌管理就是對商品的所涉及到的品牌數據進行維護。常見的品牌數據:小米、華為、海爾…

3.1 菜單添加

首先在系統中添加品牌管理的菜單,具體步驟如下所示:

1、在后臺管理系統中通過系統管理的菜單管理添加品牌管理的菜單,如下所示:

在這里插入圖片描述

2、給系統管理員角色分配品牌管理菜單訪問權限:

在這里插入圖片描述

3、在前端項目中創建對應的頁面,以及配置對應的異步路由

在src/views/product的文件夾,在該文件夾中加入品牌管理頁面文件,如下所示:

在這里插入圖片描述

在src/router/modules文件夾下創建product.js路由文件,文件內容如下所示:

const Layout = () => import('@/layout/index.vue')
const category = () => import('@/views/product/category.vue')
const brand = () => import('@/views/product/brand.vue')export default [{path: '/product',component: Layout,name: 'product',meta: {title: '商品管理',},icon: 'Histogram',children: [{path: '/category',name: 'category',component: category,meta: {title: '分類管理',},},{path: '/brand',name: 'brand',component: brand,meta: {title: '品牌管理',},},],},
]

3.2 表結構介紹

品牌數據所對應的表結構如下所示:

CREATE TABLE `brand` (`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',`name` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8_general_ci DEFAULT NULL COMMENT '品牌名稱',`logo` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8_general_ci DEFAULT NULL COMMENT '品牌圖標',`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創建時間',`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',`is_deleted` tinyint NOT NULL DEFAULT '0' COMMENT '刪除標記(0:不可用 1:可用)',PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='分類品牌'

3.3 頁面制作

對比如下頁面結構,使用Element Plus制作出對應的頁面,數據可以暫時使用假數據。

在這里插入圖片描述

該頁面可以將其分為3部分:

1、添加按鈕

2、數據表格

3、分頁組件

代碼實現如下所示:

<template><div class="tools-div"><el-button type="success" size="small">添 加</el-button></div><el-table :data="list" style="width: 100%"><el-table-column prop="name" label="品牌名稱" /><el-table-column prop="logo" label="品牌圖標" #default="scope"><img :src="scope.row.logo" width="50" /></el-table-column><el-table-column prop="createTime" label="創建時間" /><el-table-column label="操作" align="center" width="200" ><el-button type="primary" size="small">修改</el-button><el-button type="danger" size="small">刪除</el-button></el-table-column></el-table><el-pagination:page-sizes="[10, 20, 50, 100]"layout="total, sizes, prev, pager, next":total="total"/></template><script setup>
import { ref } from 'vue'// 定義表格數據模型
const list = ref([{"id":1 , "name":"華為" , "logo":"http://139.198.127.41:9000/sph/20230506/華為.png"} , {"id":2 , "name":"小米" , "logo":"http://139.198.127.41:9000/sph/20230506/小米.png"} , 
])// 分頁條數據模型
const total = ref(0)</script><style scoped>
.tools-div {margin: 10px 0;padding: 10px;border: 1px solid #ebeef5;border-radius: 3px;background-color: #fff;
}
</style>

3.4 列表查詢

需求說明:當品牌管理頁面加載完畢以后就向后端發送分頁查詢請求,后端進行分頁查詢,返回分頁結果數據。

3.4.1 后端接口

Brand

創建一個與數據庫表相對應的實體類,如下所示:

@Data
public class Brand extends BaseEntity {private String name;private String logo;}
BrandController

表現層代碼實現:

// com.atguigu.spzx.manager.controller
@RestController
@RequestMapping(value="/admin/product/brand")
public class BrandController {@Autowiredprivate BrandService brandService ;@GetMapping("/{page}/{limit}")public Result<PageInfo<Brand>> findByPage(@PathVariable Integer page, @PathVariable Integer limit) {PageInfo<Brand> pageInfo = brandService.findByPage(page, limit);return Result.build(pageInfo , ResultCodeEnum.SUCCESS) ;}}
BrandService

業務層代碼實現:

// com.atguigu.spzx.manager.service.impl;
@Service
public class BrandServiceImpl implements BrandService {@Autowiredprivate BrandMapper brandMapper ;@Overridepublic PageInfo<Brand> findByPage(Integer page, Integer limit) {PageHelper.startPage(page, limit);List<Brand> brandList = brandMapper.findByPage() ;return new PageInfo(brandList);}
}
BrandMapper

持久層代碼實現:

// com.atguigu.spzx.manager.mapper
@Mapper
public interface BrandMapper {public abstract List<Brand> findByPage();}
BrandMapper.xml

在BrandMapper.xml映射文件中添加如下的sql語句:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.spzx.manager.mapper.BrandMapper"><resultMap id="brandMap" type="com.atguigu.spzx.model.entity.product.Brand" autoMapping="true"></resultMap><!-- 用于select查詢公用抽取的列 --><sql id="columns">id,name,logo,create_time,update_time,is_deleted</sql><select id="findByPage" resultMap="brandMap">select <include refid="columns" />from brandwhere is_deleted = 0order by id desc</select></mapper>

3.4.2 前端對接

brand.js

在src/api目錄下添加brand.js文件,內容如下所示:

import request from '@/utils/request'const api_name = '/admin/product/brand'// 分頁列表
export const GetBrandPageList = (page, limit) => {return request({url: `${api_name}/${page}/${limit}`,method: 'get'})
}
brand.vue

修改brand.vue文件,內容如下所示:

<el-paginationv-model:current-page="pageParams.page"v-model:page-size="pageParams.limit":page-sizes="[10, 20, 50, 100]"layout="total, sizes, prev, pager, next":total="total"@size-change="handleSizeChange"@current-change="handleCurrentChange"/><script setup>
import { ref , onMounted } from 'vue'
import { GetBrandPageList } from '@/api/brand.js'// 定義表格數據模型
const list = ref([])// 分頁條數據模型
const total = ref(0)//分頁條數據模型
const pageParamsForm = {page: 1, // 頁碼limit: 10, // 每頁記錄數
}
const pageParams = ref(pageParamsForm)// 鉤子函數
onMounted(()=> {fetchData()
})//頁面變化
const handleSizeChange = size => {pageParams.value.limit = sizefetchData()
}
const handleCurrentChange = number => {pageParams.value.page = numberfetchData()
}// 分頁查詢
const fetchData = async () => {const {code , message , data} = await GetBrandPageList(pageParams.value.page , pageParams.value.limit) list.value = data.listtotal.value = data.total
}</script>

3.5 品牌添加

3.5.1 需求說明

用戶點擊添加按鈕,此時需要展示一個添加數據的表單對話框,用戶填寫表單數據,點擊提交按鈕,請求后端接口完成數據的保存操作。效果如下所示:

在這里插入圖片描述

3.5.2 頁面制作

頁面代碼如下所示:

<div class="tools-div"><el-button type="success" size="small" @click="addShow">添 加</el-button>
</div><el-dialog v-model="dialogVisible" title="添加或修改" width="30%"><el-form label-width="120px"><el-form-item label="品牌名稱"><el-input /></el-form-item><el-form-item label="品牌圖標"><el-uploadclass="avatar-uploader"action="http://localhost:8503/admin/system/fileUpload":show-file-list="false"><img v-if="brand.logo" :src="brand.logo" class="avatar" /><el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon></el-upload></el-form-item><el-form-item><el-button type="primary">提交</el-button><el-button @click="dialogVisible = false">取消</el-button></el-form-item></el-form>
</el-dialog><script setup>// 定義提交表單數據模型
const defaultForm = {logo: ""
}
const brand = ref(defaultForm)
const dialogVisible = ref(false) // 顯示添加品牌表單
const addShow = () => {dialogVisible.value = true 
}</script><style>
.avatar-uploader .el-upload {border: 1px dashed var(--el-border-color);border-radius: 6px;cursor: pointer;position: relative;overflow: hidden;transition: var(--el-transition-duration-fast);
}.avatar-uploader .el-upload:hover {border-color: var(--el-color-primary);
}.el-icon.avatar-uploader-icon {font-size: 28px;color: #8c939d;width: 178px;height: 178px;text-align: center;
}
</style>

3.5.3 后端接口

BrandController

表現層代碼實現:

// com.atguigu.spzx.manager.controller
@PostMapping("save")
public Result save(@RequestBody Brand brand) {brandService.save(brand);return Result.build(null , ResultCodeEnum.SUCCESS) ;
}
BrandService

業務層代碼實現:

// com.atguigu.spzx.manager.service.impl;
public void save(Brand brand) {brandMapper.save(brand) ;
}
BrandMapper

持久層代碼實現:

// com.atguigu.spzx.manager.mapper
@Mapper
public interface BrandMapper {public abstract void save(Brand brand);
}
BrandMapper.xml

在BrandMapper.xml映射文件中添加如下的sql語句:

<insert id="save">insert into brand (id,name,logo,create_time ,update_time ,is_deleted) values (#{id},#{name},#{logo},now(),now(),0)
</insert>

3.5.4 前端對接

brand.js

在src/api目錄下添加brand.js文件,內容如下所示:

// 保存品牌
export const SaveBrand = brand => {return request({url: `${api_name}/save`,method: 'post',data: brand,})
}
brand.vue

修改brand.vue文件,內容如下所示:

<el-dialog v-model="dialogVisible" title="添加或修改" width="30%"><el-form label-width="120px"><el-form-item label="品牌名稱"><el-input v-model="brand.name"/></el-form-item><el-form-item label="品牌圖標"><el-uploadclass="avatar-uploader"action="http://localhost:8503/admin/system/fileUpload":show-file-list="false":on-success="handleAvatarSuccess"><img v-if="brand.logo" :src="brand.logo" class="avatar" /><el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon></el-upload></el-form-item><el-form-item><el-button type="primary" @click="saveOrUpdate">提交</el-button><el-button @click="dialogVisible = false">取消</el-button></el-form-item></el-form>
</el-dialog><script setup>
import { SaveBrand } from '@/api/brand.js'
import { ElMessage, ElMessageBox } from 'element-plus'// 定義提交表單數據模型
const defaultForm = {id: '',name: '',logo: ""
}
const brand = ref(defaultForm)
const dialogVisible = ref(false) // 顯示添加品牌表單
const addShow = () => {brand.value = {}dialogVisible.value = true 
}//上傳
const handleAvatarSuccess = (response) => {brand.value.logo = response.data
}// 保存數據
const saveOrUpdate = () => {if (!brand.value.id) {saveData()} 
}// 新增
const saveData = async () => {await SaveBrand(brand.value)dialogVisible.value = falseElMessage.success('操作成功')fetchData()
}
</script>

3.6 修改品牌

3.6.1 需求說明

當用戶點擊修改按鈕的時候,那么此時就彈出對話框,在該對話框中需要將當前行所對應的品牌數據在該表單頁面進行展示。當用戶在該表單中點擊提交按鈕的時候那么此時就需要將表單進行提交,在后端需要提交過來的表單數據修改數據庫中的即可。

效果如下所示:

在這里插入圖片描述

3.6.2 數據回顯

分析:

1、使用添加數據的表單即可

2、要將當前操作行的數據展示在表單中,那么此時需要用到插槽

代碼如下所示:

<el-table-column label="操作" align="center" width="200" #default="scope"><el-button type="primary" size="small" @click="editShow(scope.row)">修改</el-button>
</el-table-column><script setup>//進入修改
const editShow = row => {brand.value = rowdialogVisible.value = true
}</script>

3.6.3 提交修改

后端接口
BrandController

表現層代碼實現:

// com.atguigu.spzx.manager.controller
@PutMapping("updateById")
public Result updateById(@RequestBody Brand brand) {brandService.updateById(brand);return Result.build(null , ResultCodeEnum.SUCCESS) ;
}
BrandService

業務層代碼實現:

// com.atguigu.spzx.manager.service.impl;
@Override
public void updateById(Brand brand) {brandMapper.updateById(brand) ;
}
BrandMapper

持久層代碼實現:

// com.atguigu.spzx.manager.mapper
@Mapper
public interface BrandMapper {public abstract void updateById(Brand brand);
}
BrandMapper.xml

在BrandMapper.xml映射文件中添加如下的sql語句:

<update id="updateById" >update brand set<if test="name != null and name != ''">name = #{name},</if><if test="logo != null and logo != ''">logo = #{logo},</if>update_time =  now()whereid = #{id}
</update>
前端對接
brand.js

在src/api目錄下添加brand.js文件,內容如下所示:

// 修改信息
export const UpdateBrandById = brand => {return request({url: `${api_name}/updateById`,method: 'put',data: brand,})
}
brand.vue

修改brand.vue文件,內容如下所示:

<script setup>
import { UpdateBrandById } from '@/api/brand.js'// 保存數據
const saveOrUpdate = () => {if (!brand.value.id) {saveData()} else {updateData() }
}// 修改
const updateData = async () => {await UpdateBrandById(brand.value)dialogVisible.value = falseElMessage.success('操作成功')fetchData()
}</script>

3.7 刪除品牌

3.7.1 需求說明

當點擊刪除按鈕的時候此時需要彈出一個提示框,詢問是否需要刪除數據?如果用戶點擊是,那么此時向后端發送請求傳遞id參數,后端接收id參數進行邏輯刪除。

效果如下所示:

在這里插入圖片描述

3.7.2 后端接口

BrandController

表現層代碼實現:

// com.atguigu.spzx.manager.controller
@DeleteMapping("/deleteById/{id}")
public Result deleteById(@PathVariable Long id) {brandService.deleteById(id);return Result.build(null , ResultCodeEnum.SUCCESS) ;
}
BrandService

業務層代碼實現:

// com.atguigu.spzx.manager.service.impl;
@Override
public void deleteById(Long id) {brandMapper.deleteById(id) ;
}
BrandMapper

持久層代碼實現:

// com.atguigu.spzx.manager.mapper
@Mapper
public interface BrandMapper {public abstract void deleteById(Long id);
}
BrandMapper.xml

在BrandMapper.xml映射文件中添加如下的sql語句:

<update id="deleteById">update brand setupdate_time = now() ,is_deleted = 1whereid = #{id}
</update>

3.7.3 前端對接

brand.js

在src/api目錄下添加brand.js文件,內容如下所示:

// 根據id刪除品牌
export const DeleteBrandById = id => {return request({url: `${api_name}/deleteById/${id}`,method: 'delete',})
}
brand.vue

修改brand.vue文件,內容如下所示:

<el-table-column label="操作" align="center" width="200" #default="scope"><el-button type="danger" size="small" @click="remove(scope.row.id)">刪除</el-button>
</el-table-column><script setup>
import { DeleteBrandById } from '@/api/brand.js'//刪除
const remove = async id => {ElMessageBox.confirm('此操作將永久刪除該記錄, 是否繼續?', 'Warning', {confirmButtonText: '確定',cancelButtonText: '取消',type: 'warning',}).then(async () => {await DeleteBrandById(id)ElMessage.success('刪除成功')fetchData()}).catch(() => {ElMessage.info('取消刪除')})
}</script>

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/713185.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/713185.shtml
英文地址,請注明出處:http://en.pswp.cn/news/713185.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ABAP - SALV教程 01- 開篇:打開SALV的三種方式之一

關于SALV&#xff0c;這里參考巨佬江正軍的文章講解&#xff0c;在做SAP開發的遇到困難和瓶頸的時候&#xff0c;每每讀到巨佬的文章都會靈感爆發、醍醐灌頂。https://www.cnblogs.com/jiangzhengjun/p/4291387.html 博主由于是由JAVA轉型的ABAP開發&#xff0c;剛接觸ABAP的時…

力扣細節題:判斷是否為平衡二叉樹

經典題&#xff0c;需要記憶&#xff0c;且注意fabs和fmax函數的使用 /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };*/int deep(struct TreeNode*root){if(rootNULL){return 0;}r…

Unity3D 渲染隊列 ZTest與ZWrite詳解

前言 在Unity3D中&#xff0c;渲染隊列&#xff08;Rendering Queue&#xff09;是一個非常重要的概念&#xff0c;它決定了游戲中各個物體的渲染順序和優先級。而在渲染隊列中&#xff0c;ZTest和ZWrite又是兩個關鍵的參數&#xff0c;它們決定了物體在渲染的過程中如何處理深…

研發效能最佳實踐:持續集成應用實踐丨IDCF

作者&#xff1a;謝帶達 研發效能&#xff08;DevOps&#xff09;工程師&#xff08;中級&#xff09;認證學員 一、DevOps概述 DevOps的發展可以追溯到2009年&#xff0c;當時由Patrick Debois和Andrew Clay Shafer發起了第一次DevOps Days會議。隨后&#xff0c;DevOps開始…

【R語言簡介】講解

R語言簡介&#xff0c;環境與基礎語法及注釋 1. R語言簡介2. 環境安裝3. 基礎語法3.1 變量賦值3.2 數據結構3.3 函數調用3.4 控制流3.5 注釋 4. 基本的數據操作和函數 1. R語言簡介 R語言是一種專為統計分析、數據挖掘和圖形展示而設計的編程語言和軟件環境&#xff0c;它由統…

應用引導頁配置相關 - iOS

應用引導頁配置相關,通過 ScrollView 滑動至末頁點擊進入主頁,具體實現方式如下,可供參考; /**加載引導頁*/ - (void)loadGuidePage {// 基礎配置self.window [[UIWindow alloc] initWithFrame:SCREEN_RECT];self.window.backgroundColor [UIColor whiteColor];viewControll…

永磁同步電機無感FOC(龍伯格觀測器)算法技術總結-實戰篇

文章目錄 1、ST龍伯格算法分析&#xff08;定點數&#xff09;1.1 符號說明1.2 最大感應電動勢計算1.3 系數計算1.4 龍伯格觀測器計算1.5 鎖相環計算1.6 觀測器增益計算1.7 鎖相環PI計算&#xff08;ST&#xff09;1.8 平均速度的用意 2、啟動策略2.1 V/F壓頻比控制2.2 I/F壓頻…

qnx shell sh ,linux shell bash

for i in 1 2 3 4 5 doecho $i doneecho $SHELL Shell腳本的常用執行方式、bash 和 sh 的關系、子shell、Centos 默認的解析器是 bash、Linux 提供的 Shell 解析器、Shell 概述、Shell 腳本入門_centos sh bash-CSDN博客

php cli 多進程編程

前言 php cli 命令模式我想在日常開發中&#xff0c;大家用的都比較少。其實&#xff0c;在某些場景&#xff0c;cli命令真的很有作用&#xff0c; 我舉個例子 在mysql數據庫的某個表tab1中數據量有3000W條數據&#xff0c;現在需要對這張表中的每一條數據做計算處理。將處理…

設計模式(含7大原則)面試題

目錄 主要參考文章 設計模式的目的 設計模式的七大原則 設計模式的三大分類及關鍵點 1、創建型模式(用于解耦對象的實例化過程) 2、結構型模式 3、行為型模式 23種設計模式(亂序--現學現寫,不全面--應付面試為主) 單例模式 模板模式 哈哈哈哈哈 聲明 此文只針…

策略模式代碼示例(二)

一、定義 策略模式&#xff0c;針對每一個不同的類型&#xff0c;調用具有共同接口的不同實現類&#xff0c;從而使得它們可以相互替換。 策略模式 &#xff0c;針對實現同一接口的不同的類&#xff0c;采用不同的策略。比如&#xff0c;面對高級會員、初級會員會采用不同的折…

詳解字符串函數<string.h>(下)

1. strncpy函數的使用和模擬實現 char* strncpy(char* destination, const char* source, size_t num) 1.1 函數功能以及用法 拷貝指定長度的字符串 將“source”指向的字符串中的“num”個字符拷貝到“destination”指向的字符數組中。相比于strcpy函數&#xff0c;該函數多…

SQL語言的五大分類 (DQL、DDL、DML、DCL、TCL)

目錄 一、DQL 二、DDL 三、DML 四、DCL 五、TCL 一、DQL&#xff08;數據查詢語言&#xff09; Data Query Language&#xff0c;數據查詢語言&#xff1a; select&#xff1a;用于數據查詢 關鍵字&#xff1a;SELECT ... FROM ... WHERE 二、DDL&#xff08;數據定義語…

swift 長按桌面圖標彈出快捷選項

文章目錄 一、3D Touch二、主屏交互1. 靜態添加2. 動態添加三、監聽主屏交互按鈕的點擊事件四、預覽和跳轉1. 注冊3D touch2. 實現協議3. 在目標控制器復寫previewActionItems4. 使用UIContextMenuConfiguration一、3D Touch 3D Touch通過屏幕下方的壓力感應器來感知不同的壓力…

Cesium地表透明

之前Cesium是不能地表透明的&#xff0c;需要改內部代碼&#xff0c;將GlobeSurfaceTileProvider.js中的PASS.GLOBE改成PASS.TRANSPARENT&#xff0c;通過將地表的drawCommand放到透明隊列里渲染。現在發現有了新的方法&#xff08;其實2020年就有該方法了&#xff09;&#xf…

數據庫管理-第157期 Oracle Vector DB AI-08(20240301)

數據庫管理157期 2024-03-01 數據庫管理-第157期 Oracle Vector DB & AI-08&#xff08;20240301&#xff09;1 創建示例向量2 查找最近向量3 基于向量簇組的最近向量查詢總結 數據庫管理-第157期 Oracle Vector DB & AI-08&#xff08;20240301&#xff09; 作者&…

【axiox】前后端接口通訊數據交互

重要全局配置&#xff1a; axios.create(); 設置axios請求的公共配置信息。 service.interceptors.request.use((config)>{}) 請求攔截器 service.interceptors.response.use((res)>{},(err)>{}) 響應攔截器 const source axios.CancelToken.source(); 用…

oracle RAC節點重構

一、清除集群上二節點的節點信息 1、刪除實例 dbca或靜默&#xff1a; [oraclerac1 ~]$ dbca -silent -deleteinstance -nodelist rac2 -gdbname orcl -instancename orcl2 -sysdbausername sys -sysdbapassword oracledbca-實例管理-刪除節實例-選擇服務輸入密碼-選擇inactiv…

基于小波神經網絡的數據分類算法matlab仿真

目錄 1.程序功能描述 2.測試軟件版本以及運行結果展示 3.核心程序 4.本算法原理 1.程序功能描述 基于小波神經網絡的數據分類算法。輸入為5個特征值&#xff0c;輸出為判斷&#xff08;是&#xff0c;否&#xff09;。拿50組數據對本算法作為訓練組&#xff0c;后30組數據作…

B樹、B+樹、紅黑樹的定義、之間的區別、優缺點、數據結構、應用等

目錄 B樹 定義 數據結構 優點 缺點 應用 B樹 定義 數據結構 優點 缺點 應用 紅黑樹 定義 數據結構 優點 缺點 應用 B樹與B樹與紅黑樹的區別 B樹 定義 B樹是一種自平衡的多路搜索樹&#xff0c;它可以有多個子節點&#xff0c;不同于二叉樹的是&#xff0c;一…