完成菜品分类模块与后端接口的对接 #33

Merged
ppnwsfegt merged 5 commits from Brunch_LPQ into main 4 months ago

@ -0,0 +1,69 @@
package com.itmk.web.category.controller;
import com.alibaba.druid.util.StringUtils;
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.itmk.utils.ResultUtils;
import com.itmk.utils.ResultVo;
import com.itmk.web.category.entity.CategoryPageParm;
import com.itmk.web.category.entity.SysCategory;
import com.itmk.web.category.service.SysCategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/category")
public class SysCategoryController {
// 注入服务类
@Autowired
private SysCategoryService sysCategoryService;
// 新增菜品分类
@PostMapping
public ResultVo addCategory(@RequestBody SysCategory sysCategory){
//单独检查菜品分类名称
if(sysCategoryService.lambdaQuery()
.eq(SysCategory::getCategoryName, sysCategory.getCategoryName())
.exists()){
return ResultUtils.error("菜品分类已存在!");
}
return sysCategoryService.save(sysCategory)
? ResultUtils.success("新增菜品分类成功!", sysCategory)
: ResultUtils.error("新增菜品分类失败!");
}
// 编辑菜品分类
@PutMapping
public ResultVo editCategory(@RequestBody SysCategory sysCategory){
if(sysCategoryService.updateById(sysCategory)){
return ResultUtils.success("编辑菜品分类成功!", sysCategory);
}
return ResultUtils.error("编辑菜品分类失败!");
}
// 删除菜品分类
@DeleteMapping("/{categoryId}")
public ResultVo deleteCategory(@PathVariable Long categoryId){
if(sysCategoryService.removeById(categoryId)){
return ResultUtils.success("删除菜品分类成功!");
}
return ResultUtils.error("删除菜品分类失败!");
}
// 列表查询
// 列表查询需要分页
@GetMapping("/list")
public ResultVo getList(CategoryPageParm parm) {
IPage<SysCategory> page = new Page<>(parm.getCurrentPage(), parm.getPageSize());
QueryWrapper<SysCategory> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().like(!StringUtils.isEmpty(parm.getCategoryName()), SysCategory::getCategoryName, parm.getCategoryName())
.orderByAsc(SysCategory::getOrderNum);
IPage<SysCategory> list = sysCategoryService.page(page, queryWrapper);
return ResultUtils.success("查询成功", list);
}
}

@ -0,0 +1,11 @@
package com.itmk.web.category.entity;
import lombok.Data;
@Data
public class CategoryPageParm {
private Integer currentPage;//当前页
private Integer pageSize;//每页显示多少条
private String categoryName;
}

@ -0,0 +1,19 @@
package com.itmk.web.category.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("sys_category")//表明该类实体类所关联的数据表库
//创建一个实体类
public class SysCategory {
@TableId(type = IdType.AUTO) //表明这是一个主键,并且自动递增
private Long categoryId;
private String categoryName;
private Integer orderNum;
}

@ -0,0 +1,7 @@
package com.itmk.web.category.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itmk.web.category.entity.SysCategory;
public interface SysCategoryMapper extends BaseMapper<SysCategory> {
}

@ -0,0 +1,7 @@
package com.itmk.web.category.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.itmk.web.category.entity.SysCategory;
public interface SysCategoryService extends IService<SysCategory> {
}

@ -0,0 +1,11 @@
package com.itmk.web.category.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itmk.web.category.entity.SysCategory;
import com.itmk.web.category.mapper.SysCategoryMapper;
import com.itmk.web.category.service.SysCategoryService;
import org.springframework.stereotype.Service;
@Service
public class SysCategoryServiceImpl extends ServiceImpl<SysCategoryMapper, SysCategory> implements SysCategoryService {
}

@ -0,0 +1,7 @@
<!--xml接口映射文件-->
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itmk.web.category.mapper.SysCategoryMapper">
</mapper>

@ -0,0 +1,17 @@
// 定义数据类型
// 定义菜品列表查询的数据类型
export type listCategoryParm = {
currentPage: number;//当前页
pageSize: number;//每页显示多少条
categoryName: string;//根据菜品名查询
total: number;//总条数
}
// 定义菜品表单数据类型
export type categoryModel = {
categoryId: string;
categoryName: string;
orderNum: string;
type: string;
}

@ -0,0 +1,29 @@
// 配置接口
import http from "../../http";
// 导入数据类型的定义
import type { listCategoryParm, categoryModel } from "./categoryModel";
// 增(传入categoryModel参数用来接收需要传入该表单的数据类型)
export const addCategoryApi = (parm: categoryModel) => {
// 返回http中的post请求传入路径和数据参数通过请求接入后端接口
return http.post('/api/category', parm)
}
// 删
export const deleteCategoryApi = (categoryId: string) => {
return http.delete(`/api/category/${categoryId}`)
}
// 改
export const editCategoryApi = (parm: categoryModel) => {
return http.put('/api/category', parm)
}
// 查(传入的参数是列表参数,包括分页,查询等属性)
export const getCategoryApi = (parm: listCategoryParm) => {
// 查需要找到列表,把列表里面的数据返回出来
return http.get('/api/category/list', parm)
}

@ -0,0 +1,50 @@
// 抽取增删改业务
import { ref } from "vue";
import type { FuncList } from "../../type/baseType";
import type { categoryModel } from "../../api/category/categoryModel";
import { EditType } from "../../type/baseType";
import { deleteCategoryApi } from "../../api/category";
import { ElMessage } from "element-plus";
import useInstance from "@/hooks/useInstance";
export default function useCategory(getList: FuncList) {
const { global } = useInstance()
// 获取AddCategory里面的show方法
const showBtn = ref<{ show: (title: string, type: string, width?: number, height?: number, row?: categoryModel) => {} }>();
// 增
const addBtn = () => {
showBtn.value?.show("新增", EditType.ADD, 630, 180)
}
// 删
const deleteBtn = async (row: categoryModel) => {
let confirm = await global.$myconfirm('确定删除该数据吗?')
// 判断confirm返回true用户确定删除就进行删除调用删除api
if (confirm) {
let res = await deleteCategoryApi(row.categoryId)
if (res && res.code == 200) {
// 删除成功信息提示
ElMessage.success(res.msg)
// 删除后刷新列表
getList()
}
}
}
// 改
// 传递row参数将旧数据传递出去方便编辑
const editBtn = (row: categoryModel) => {
console.log(row)
showBtn.value?.show("编辑", EditType.EDIT, 630, 180, row)
}
return {
showBtn,
addBtn,
deleteBtn,
editBtn
}
}

@ -0,0 +1,97 @@
// 抽取表单操作
import { getCategoryApi } from "../../api/category"
import type { listCategoryParm } from "../../api/category/categoryModel"
import { ref, reactive, onMounted, nextTick } from "vue"
export default function useCategoryTable() {
// 设置列表查询参数(查)
const listParm = reactive<listCategoryParm>({
currentPage: 1,//当前页
pageSize: 10,//每页显示多少条
categoryName: '',//根据菜品名查询
total: 0//总条数
})
// 设置表格高度(默认值设置为0)
const tableHeight = ref(0)
// 需要在页面上显示列表所以定义一个变量用来存储从categoryList中查询到的值
const tableList = ref([])
// 列表查询
const getList = async () => {
// 调用列表查询api变量接收查询值listParm
let res = await getCategoryApi(listParm)
console.log(res)
// 如果调用查询api成功,同时满足res不为空,状态码返回正确状态(200)
if (res && res.code == 200) {
// ref定义的响应式变量,通过.value赋值
/* res.data.records resapi
public class ResultVo<T> {
private String msg;
private int code;
private T data;
} */
// data里面的records存储对象数组
tableList.value = res.data.records
// 更新列表查询查出来的总条数,覆盖默认值0
listParm.total = res.data.total;
}
}
// 搜索按钮
const searchBtn = () => {
getList()
}
// 重置按钮
const resetBtn = () => {
// 重置列表显示到第一页(首页)
listParm.currentPage = 1
// 重置搜索框为空(重置搜索值为空)
listParm.categoryName = ''
// 再调用getList显示全部列表
getList()
}
// 在组件挂载时加载数据
onMounted(() => {
getList()
// 计算表格高度覆盖默认值
nextTick(() => {
tableHeight.value = window.innerHeight - 220
})
})
// 当本页面页面大小变化时触发该方法
const sizeChange = (size:number)=>{
// 当当前页面的size变化时,设置本地页面size变化
listParm.pageSize = size
// 刷新页面(重调getList方法)
getList()
}
// 当页面指针变化时触发该方法(第n页变化)
const currentChange = (page:number)=>{
// 当当前页面的page变化时,设置本地页面page变化
listParm.currentPage = page
// 刷新页面(重调getList方法)
getList()
}
// 将所有属性方法返回出去
return {
tableList,
tableHeight,
listParm,
getList,
searchBtn,
resetBtn,
sizeChange,
currentChange
}
}

@ -0,0 +1,117 @@
<template>
<SysDialog :title="dialog.title" :visible="dialog.visible" :width="dialog.width" :height="dialog.height"
@onClose="onClose" @onConfirm="commit">
<!-- 通过插槽插入表单 -->
<template #content>
<!-- rules绑定表单验证规则 -->
<el-form :model="addModel" ref="addFormRef" :rules="rules" label-width="80px" :inline="false" size="default">
<el-form-item label="分类名称" prop="categoryName">
<el-input v-model="addModel.categoryName"></el-input>
</el-form-item>
<el-form-item label="序号" prop="orderNum">
<el-input v-model="addModel.orderNum"></el-input>
</el-form-item>
</el-form>
</template>
</SysDialog>
</template>
<script setup lang="ts">
import { reactive, nextTick, ref } from 'vue';
//
import SysDialog from '@/components/SysDialog.vue';
// ,
import useDialog from '@/hooks/useDialog';
const { dialog, onClose, onConfirm, onShow } = useDialog()
// category
import type { categoryModel } from '../../api/category/categoryModel';
//
import { ElMessage, type FormInstance } from 'element-plus';
import { EditType } from '../../type/baseType';
import { addCategoryApi, editCategoryApi } from '../../api/category';
// ,,
// reactive
const addModel = reactive<categoryModel>({
categoryId: "",
categoryName: "",
orderNum: "",
type: ""
})
//
const rules = reactive({
categoryName: [{
required: true,
message: '请输入菜品分类名称',
trigger: 'blur'
}]
})
// addFormRef
const addFormRef = ref<FormInstance>()
//
const show = (title: string, type: string, width: number, height: number, row?: categoryModel) => {
onShow(title, width, height)
//
addFormRef.value?.resetFields()
//
if (row) {
nextTick(() => {
Object.assign(addModel, row)
})
}
//
addModel.type = type
}
//
const emits = defineEmits(['onFresh'])
//
defineExpose({
show
})
//
const commit = () => {
addFormRef.value?.validate(async (valid) => {
if (valid) {
// addUserApi
let res = null
if (addModel.type == EditType.ADD) {
res = await addCategoryApi(addModel)
} else {
res = await editCategoryApi(addModel)
}
console.log(res)
if (res && res.code == 200) {
//
ElMessage.success(res.msg)
//
// getList()
emits('onFresh')
onConfirm()
}
}
})
}
</script>
<style scoped></style>

@ -1,13 +1,59 @@
<!-- 菜品分类的主界面 -->
<template>
<div>
菜品分类
</div>
<el-main>
<!-- 搜索栏 -->
<el-form :model="listParm" label-width="80px" :inline="true" size="default">
<el-form-item>
<!-- 通过v-model="listParm.categoryName"获取搜索框中输入的值 -->
<el-input v-model="listParm.categoryName" placeholder="请输入菜品分类名称:"></el-input>
</el-form-item>
<el-form-item>
<el-button @click="searchBtn" icon="Search">搜索</el-button>
<el-button plain type="danger" @click="resetBtn" icon="Close">重置</el-button>
<el-button plain type="primary" @click="addBtn" icon="Plus">新增</el-button>
</el-form-item>
</el-form>
<!-- 列表查询显示 -->
<!-- 通过data属性绑定tableList获取存储在数据库中的值来执行列表查询 -->
<el-table :height="tableHeight" :data="tableList" border stripe>
<!-- label属性设置标题,prop属性绑定表格的数据类型 -->
<el-table-column label="分类名称" prop="categoryName"></el-table-column>
<el-table-column label="序号" prop="orderNum"></el-table-column>
<!-- 为表格添加编辑删除按钮 -->
<el-table-column label="操作" min-width="100" align="center">
<template #default="scoped">
<el-button type="primary" size="default" @click="editBtn(scoped.row)" icon="Edit">
编辑
</el-button>
<el-button type="danger" size="default" @click="deleteBtn(scoped.row)" icon="Delete">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 为表格添加分页显示 -->
<el-pagination @size-change="sizeChange" @current-change="currentChange" :current-page.sync="listParm.currentPage"
:page-sizes="[10, 20, 40, 80, 100]" :page-size="listParm.pageSize"
layout="total, sizes, prev, pager, next, jumper" :total="listParm.total" background>
</el-pagination>
<AddCategory ref="showBtn" @onFresh="getList"></AddCategory>
</el-main>
</template>
<script setup lang="ts">
import useCategoryTable from '@/compositions/category/useCategoryTable';
const { tableList, tableHeight, listParm, getList, searchBtn, resetBtn, sizeChange, currentChange } = useCategoryTable()
</script>
import useCategory from '@/compositions/category/useCategory';
const { showBtn, addBtn, deleteBtn, editBtn } = useCategory(getList)
<style scoped>
// AddCategory
import AddCategory from './AddCategory.vue';
</script>
</style>
<style scoped></style>
Loading…
Cancel
Save