✨✨个人主页:沫洺的主页
📚📚系列专栏: 📖 JavaWeb专栏📖 JavaSE专栏 📖 Java基础专栏📖vue3专栏
📖MyBatis专栏📖Spring专栏📖SpringMVC专栏📖SpringBoot专栏
📖Docker专栏📖Reids专栏📖MQ专栏📖SpringCloud专栏
💖💖如果文章对你有所帮助请留下三连✨✨
🍒效果图
🍉具体实现
Element Plus: Pagination 分页
后端接口实现:
核心代码
<template> <el-row :gutter="24"> <el-col :span="12" :offset="6"> <el-pagination background layout="prev, pager, next" :total="paginationData.total" :page-size="paginationData.pageSize" :current-page="paginationData.pageNum" @current-change="pageChange" /> </el-col> </el-row> </template> <script setup lang="ts"> const paginationData = reactive({ pageSize: 4, pageNum: 1, total: 0 }) const pageChange = (pageNum: number) => { // console.log(pageNum); paginationData.pageNum = pageNum callCategoryTableApi() } const onSubmit = () => { paginationData.pageNum = 1 callProductTableApi(); } const callProductTableApi= () => { let pageSize = paginationData.pageSize let pageNum = paginationData.pageNum productApi.select.call({ pageSize: pageSize,pageNum: pageNum }).then((res: any) => { // console.log(res) paginationData.total = res.total }) } </script>
🍇模糊查询
后端接口实现
ProductEntity
@Data public class ProductEntity { private Integer id; private String name; private String img; private Integer categoryId; private BigDecimal price; private String brief; private Integer status = 1; private Integer seq; private String lastUpdateBy; private LocalDateTime lastUpdateTime = LocalDateTimeUtil.now(); private String categoryName; }
ProductDto
@Data public class ProductDto { private Integer id; private String name; private String img; private Integer categoryId; private BigDecimal price; private String brief; private Integer status = 1; private Integer seq; private String lastUpdateBy; private LocalDateTime lastUpdateTime = LocalDateTimeUtil.now(); private String categoryName; private String statusX; public String getStatusX() { EnumProductStatus categoryStatus = EnumProductStatus.findByCode(this.status); return categoryStatus.getName(); } }
ProductQueryDto
@Data public class ProductQueryDto { private Integer id; private String name; private Integer categoryId; private Integer status; }
ProductMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.moming.dao.ProductMapper"> <select id="select" resultType="ProductEntity"> select p.id,p.name,p.img,p.categoryId,p.price,p.brief,p.status,p.seq,p.lastUpdateBy,p.lastUpdateTime,c.name as categoryName from scm_product p left join scm_category c on p.categoryId=c.id where 1 = 1 <if test="id != null"> and p.id = #{id} </if> <if test="name != null"> and p.name like concat('%',#{name},'%') </if> <if test="categoryId != null"> and p.categoryId = #{categoryId} </if> <if test="status != null"> and p.status = #{status} </if> order by seq desc </select> <update id="update" parameterType="ProductEntity"> update scm_product <set> <if test="name!=null"> name=#{name}, </if> <if test="img!=null"> img=#{img}, </if> <if test="categoryId!=null"> categoryId=#{categoryId}, </if> <if test="price!=null"> price=#{price}, </if> <if test="brief!=null"> brief=#{brief}, </if> <if test="status!=null"> status=#{status}, </if> <if test="seq!=null"> seq=#{seq}, </if> <if test="lastUpdateBy!=null"> lastUpdateBy=#{lastUpdateBy}, </if> </set> where id=#{id} </update> <insert id="insert" parameterType="ProductEntity"> insert into scm_product(name,img,categoryId,price,brief,status,seq,lastUpdateBy) values(#{name},#{img},#{categoryId},#{price},#{brief},#{status},#{seq},#{lastUpdateBy}) </insert> <delete id="delete"> delete from scm_product where id=#{id} </delete> </mapper>
ProductMapper
注意:查询语句上使用自定义的分页注解@PageCut
@Mapper public interface ProductMapper { @PageCut List<ProductEntity> select(ProductQueryDto productQueryDto); int update(ProductEntity productEntity); int insert(ProductEntity productEntity); int delete(Integer id); }
ProductService
@Service public class ProductService { @Autowired private ProductMapper productMapper; //查 public List<ProductDto> select(ProductQueryDto productQueryDto){ List<ProductEntity> selectEntity = productMapper.select(productQueryDto); List<ProductDto> productDtos = BeanUtil.copyToList(selectEntity, ProductDto.class); return productDtos; } //改 public int update(ProductDto productDto){ ProductEntity productEntity = BeanUtil.copyProperties(productDto, ProductEntity.class); return productMapper.update(productEntity); } //插 public int insert(ProductDto productDto){ ProductEntity productEntity = BeanUtil.copyProperties(productDto, ProductEntity.class); return productMapper.insert(productEntity); } //删 public int delete(Integer id){ return productMapper.delete(id); } }
ProductController
@RestController @RequestMapping("api/product") public class ProductController { @Autowired private ProductService productService; //查 @GetMapping public List<ProductDto> select(ProductQueryDto productQueryDto){ return productService.select(productQueryDto); } //改 @PutMapping public int update(@RequestBody ProductDto productDto){ return productService.update(productDto); } //插 @PostMapping public int insert(@RequestBody ProductDto productDto){ return productService.insert(productDto); } //删 @DeleteMapping("/{id}") public int delete(@PathVariable Integer id){ return productService.delete(id); } }
测试接口
前端实现接口
<template> <el-form :inline="true" :model="formData" class="demo-form-inline"> <el-form-item label="归类"> <el-tree-select v-model="formData.categoryId" :data="categoryTreeData" :render-after-expand="false" :default-expand-all="true" /> </el-form-item> <el-form-item label="商品名称"> <el-input v-model="formData.name" placeholder="请输入关键字"> </el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="onSubmit">查询</el-button> </el-form-item> </el-form> <el-row> <el-col :span="24"> <el-table :data="tableData" style="width: 100%"> <el-table-column fixed prop="id" label="编号" width="60" /> <el-table-column fixed prop="name" label="名称" width="80" /> <el-table-column prop="img" label="图片" width="80"> <template #default="scope"> <el-image style="width: 50px; height: 50px" :src="scope.row.imgs[0]" :preview-src-list="scope.row.imgs" :initial-index="0" fit="fill" :preview-teleported="true" /> </template> </el-table-column> <el-table-column prop="categoryName" label="归类" width="80" /> <el-table-column prop="price" label="价格" width="80"> <template #default="scope"> ¥ {{ scope.row.price }} </template> </el-table-column> <el-table-column prop="brief" label="描述" width="100" :formatter="formatter" /> <el-table-column prop="statusX" label="状态" width="60" /> <el-table-column prop="seq" label="排序" width="60" /> <el-table-column prop="lastUpdateBy" label="更新人" width="70" /> <el-table-column prop="lastUpdateTime" label="最近更新时间" width="200" :formatter="formatter" /> <el-table-column fixed="right" label="操作" width="140"> <template #default="scope"> <el-button link type="primary" size="small" @click="editClick(scope.row)">编辑</el-button> <el-button link type="primary" v-if="scope.row.status === 1" size="small" @click="offClick(scope.row)">下架 </el-button> <el-button link type="primary" v-if="scope.row.status === 0" size="small" @click="on_Click(scope.row)">上架 </el-button> </template> </el-table-column> </el-table> </el-col> </el-row> <el-row :gutter="24"> <el-col :span="12" :offset="10"> <el-pagination background layout="prev, pager, next" :total="paginationData.total" :page-size="paginationData.pageSize" :current-page="paginationData.pageNum" @current-change="pageChange" /> </el-col> </el-row> </template> <script setup lang="ts"> import { onMounted, ref, reactive } from 'vue' //导入productApi import { productApi, categoryApi } from "@/api/index" import { ElMessage, ElMessageBox } from 'element-plus' import dayjs from 'dayjs' import { useRouter } from 'vue-router' const router = useRouter(); const formData = reactive({ name: '', img: "", categoryId: 0, categoryName: "", price: 0.0, brief: '', seq: 10, }) //分页 const paginationData = reactive({ pageSize: 4, pageNum: 1, total: 0 }) const pageChange = (pageNum: number) => { // console.log(pageNum); paginationData.pageNum = pageNum callProductTableApi() } //定义tableData const tableData: any = ref([]) // 处理字段格式 const formatter = (row: any, column: any, cellValue: any, index: any) => { //console.log(column.property) if (column.property == "lastUpdateTime") { return dayjs(cellValue).format('YYYY年MM月DD日 HH时mm分'); } if (column.property === "brief") { if (cellValue.length > 6) { return cellValue.replace(/<.*?>/g, "").substring(0, 6) + "......"; } else { return cellValue; } } if (column.property == "lastUpdateBy") { if (row.id < 50) { return cellValue + " 先生"; } else { return cellValue + " 女士"; } } } onMounted(() => { callCategoryTreeApi() callProductTableApi() }) const categoryTreeData = ref([{ value: 0, label: "请选择分类" }]) const callCategoryTreeApi = () => { categoryApi.tree.call().then((res: any) => { // console.log(res); // concat 合并数组 categoryTreeData.value = categoryTreeData.value.concat(res) }) } // 查询商品 const callProductTableApi = () => { //因为在http/index.ts中对响应的数据已经处理过了 let name = formData.name === "" ? undefined : formData.name; let categoryId = formData.categoryId === 0 ? undefined : formData.categoryId; let pageSize = paginationData.pageSize let pageNum = paginationData.pageNum productApi.select.call({ categoryId: categoryId, name: name,pageSize: pageSize,pageNum: pageNum}).then((res: any) => { // console.log(res); for (let product of res.items) { product.imgs = product.img.split(',') } tableData.value = res.items paginationData.total = res.total }) } // 查询 const onSubmit = () => { paginationData.pageNum = 1 callProductTableApi(); } // 编辑跳转编辑页面 const editClick = (row: any) => { // console.log(row) router.push({ name: "product-edit", query: { id: row.id } }) } // 上架or下架 const offClick = (row: any) => { ElMessageBox.confirm( '你确定要下架' + row.name + "商品吗?", '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning', } ) .then(() => { productApi.update.call({ id: row.id, status: 0 }).then((res: any) => { if (res === 1) { ElMessage({ type: 'success', message: '下架成功', }) callProductTableApi() } }) }) .catch(() => { }) } const on_Click = (row: any) => { productApi.update.call({ id: row.id, status: 1 }).then((res: any) => { if (res === 1) { ElMessage({ type: 'success', message: '上架成功', }) callProductTableApi() } }) } </script>
核心部分
const callProductTableApi = () => { let name = formData.name === "" ? undefined : formData.name; let categoryId = formData.categoryId === 0 ? undefined : formData.categoryId; let pageSize = paginationData.pageSize let pageNum = paginationData.pageNum productApi.select.call({ categoryId: categoryId, name: name,pageSize: pageSize,pageNum: pageNum}).then((res: any) => { // console.log(res); for (let product of res.items) { product.imgs = product.img.split(',') } tableData.value = res.items paginationData.total = res.total }) }
let name = formData.name === "" ? undefined : formData.name; let categoryId = formData.categoryId === 0 ? undefined : formData.categoryId;
对name,categoryId进行处理,防止不赋值时自动默认值,改为不赋值时为undefined,这样就可以实现对所有数据进行查询