若依框架学习日志 04 - 二次开发 - 菜品管理
一、需求理解与规划
1. 需求分析
本次要开发的菜品管理模块,主要功能包括菜品信息的增删改查,同时要关联菜品分类和图片信息。用户可以根据菜品名称、分类等条件查询菜品列表,对单个菜品进行详细信息的查看、修改和删除操作,并且能够上传菜品图片。
2. 功能规划
- 菜品列表展示:显示菜品的基本信息,如菜品名称、价格、所属分类等。
- 菜品添加:输入菜品的详细信息,选择所属分类,上传菜品图片。
- 菜品编辑:修改已存在菜品的信息。
- 菜品删除:删除指定的菜品记录。
- 菜品查询:支持按菜品名称、分类进行模糊查询。
二、数据库设计
1. 菜品表(tb_dish
)
sql
CREATE TABLE `tb_dish` (
`dish_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '菜品 ID',
`dish_name` varchar(200) NOT NULL COMMENT '菜品名称',
`price` decimal(10, 2) NOT NULL COMMENT '菜品价格',
`category_id` bigint(20) NOT NULL COMMENT '菜品分类 ID',
`image_url` varchar(500) DEFAULT NULL COMMENT '菜品图片 URL',
`description` text COMMENT '菜品描述',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`dish_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='菜品表';
2. 菜品分类表(tb_dish_category
)
sql
CREATE TABLE `tb_dish_category` (
`category_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '分类 ID',
`category_name` varchar(100) NOT NULL COMMENT '分类名称',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`category_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='菜品分类表';
三、后端开发
1. 实体类创建
- Dish 实体类:在
ruoyi-admin/src/main/java/com/ruoyi/system/domain
目录下创建SysDish
类。
java
package com.ruoyi.system.domain;
import com.ruoyi.common.core.domain.BaseEntity;
import lombok.Data;
@Data
public class SysDish extends BaseEntity {
private Long dishId;
private String dishName;
private Double price;
private Long categoryId;
private String imageUrl;
private String description;
}
- DishCategory 实体类:同样在该目录下创建
SysDishCategory
类。
java
package com.ruoyi.system.domain;
import com.ruoyi.common.core.domain.BaseEntity;
import lombok.Data;
@Data
public class SysDishCategory extends BaseEntity {
private Long categoryId;
private String categoryName;
}
2. Mapper 接口与 XML 文件
- DishMapper 接口:在
ruoyi-admin/src/main/java/com/ruoyi/system/mapper
目录下创建SysDishMapper
接口。
java
package com.ruoyi.system.mapper;
import com.ruoyi.system.domain.SysDish;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface SysDishMapper {
List<SysDish> selectDishList(SysDish dish);
int insertDish(SysDish dish);
int updateDish(SysDish dish);
int deleteDishById(Long dishId);
}
- DishMapper XML 文件:在
ruoyi-admin/src/main/resources/mapper/system
目录下创建SysDishMapper.xml
文件。
xml
<?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.ruoyi.system.mapper.SysDishMapper">
<select id="selectDishList" resultType="com.ruoyi.system.domain.SysDish">
SELECT * FROM tb_dish
<where>
<if test="dishName != null and dishName != ''">
AND dish_name LIKE CONCAT('%', #{dishName}, '%')
</if>
<if test="categoryId != null">
AND category_id = #{categoryId}
</if>
</where>
</select>
<insert id="insertDish">
INSERT INTO tb_dish (dish_name, price, category_id, image_url, description)
VALUES (#{dishName}, #{price}, #{categoryId}, #{imageUrl}, #{description})
</insert>
<update id="updateDish">
UPDATE tb_dish
SET dish_name = #{dishName},
price = #{price},
category_id = #{categoryId},
image_url = #{imageUrl},
description = #{description}
WHERE dish_id = #{dishId}
</update>
<delete id="deleteDishById">
DELETE FROM tb_dish WHERE dish_id = #{dishId}
</delete>
</mapper>
- DishCategoryMapper 接口与 XML 文件:类似地创建
SysDishCategoryMapper
接口和对应的 XML 文件,用于处理菜品分类的数据库操作。
3. 服务层开发
- DishService 接口:在
ruoyi-admin/src/main/java/com/ruoyi/system/service
目录下创建ISysDishService
接口。
java
package com.ruoyi.system.service;
import com.ruoyi.system.domain.SysDish;
import java.util.List;
public interface ISysDishService {
List<SysDish> selectDishList(SysDish dish);
int insertDish(SysDish dish);
int updateDish(SysDish dish);
int deleteDishById(Long dishId);
}
- DishServiceImpl 实现类:在该目录下创建
SysDishServiceImpl
类。
java
package com.ruoyi.system.service.impl;
import com.ruoyi.system.domain.SysDish;
import com.ruoyi.system.mapper.SysDishMapper;
import com.ruoyi.system.service.ISysDishService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class SysDishServiceImpl implements ISysDishService {
@Autowired
private SysDishMapper dishMapper;
@Override
public List<SysDish> selectDishList(SysDish dish) {
return dishMapper.selectDishList(dish);
}
@Override
public int insertDish(SysDish dish) {
return dishMapper.insertDish(dish);
}
@Override
public int updateDish(SysDish dish) {
return dishMapper.updateDish(dish);
}
@Override
public int deleteDishById(Long dishId) {
return dishMapper.deleteDishById(dishId);
}
}
4. 控制器开发
在 ruoyi-admin/src/main/java/com/ruoyi/system/controller
目录下创建 SysDishController
控制器。
java
package com.ruoyi.system.controller;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.system.domain.SysDish;
import com.ruoyi.system.service.ISysDishService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/system/dish")
public class SysDishController extends BaseController {
@Autowired
private ISysDishService dishService;
@GetMapping("/list")
public TableDataInfo list(SysDish dish) {
startPage();
List<SysDish> list = dishService.selectDishList(dish);
return getDataTable(list);
}
@PostMapping
public AjaxResult add(@RequestBody SysDish dish) {
return toAjax(dishService.insertDish(dish));
}
@PutMapping
public AjaxResult edit(@RequestBody SysDish dish) {
return toAjax(dishService.updateDish(dish));
}
@DeleteMapping("/{dishId}")
public AjaxResult remove(@PathVariable Long dishId) {
return toAjax(dishService.deleteDishById(dishId));
}
}
四、前端开发
1. API 接口封装
在 ruoyi-ui/src/api/system
目录下创建 dish.js
文件。
javascript
import request from '@/utils/request'
export function getDishList(query) {
return request({
url: '/system/dish/list',
method: 'get',
params: query
})
}
export function addDish(data) {
return request({
url: '/system/dish',
method: 'post',
data: data
})
}
export function updateDish(data) {
return request({
url: '/system/dish',
method: 'put',
data: data
})
}
export function deleteDish(dishId) {
return request({
url: `/system/dish/${dishId}`,
method: 'delete'
})
}
2. 页面组件开发
在 ruoyi-ui/src/views/system
目录下创建 dish
文件夹,并在其中创建 index.vue
文件。
vue
<template>
<div>
<el-form :inline="true" :model="queryParams" class="demo-form-inline">
<el-form-item label="菜品名称">
<el-input v-model="queryParams.dishName" placeholder="请输入菜品名称"></el-input>
</el-form-item>
<el-form-item label="菜品分类">
<el-select v-model="queryParams.categoryId" placeholder="请选择分类">
<!-- 这里应动态加载分类数据 -->
<el-option label="分类 1" value="1"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getDishList">查询</el-button>
</el-form-item>
</el-form>
<el-table :data="dishList" stripe>
<el-table-column prop="dishId" label="菜品 ID"></el-table-column>
<el-table-column prop="dishName" label="菜品名称"></el-table-column>
<el-table-column prop="price" label="菜品价格"></el-table-column>
<el-table-column label="菜品图片">
<template slot-scope="scope">
<img :src="scope.row.imageUrl" alt="菜品图片" width="50">
</template>
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button type="primary" size="mini" @click="editDish(scope.row)">编辑</el-button>
<el-button type="danger" size="mini" @click="deleteDish(scope.row.dishId)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-dialog :visible.sync="dialogVisible" title="菜品信息">
<el-form :model="dishForm">
<el-form-item label="菜品名称">
<el-input v-model="dishForm.dishName"></el-input>
</el-form-item>
<el-form-item label="菜品价格">
<el-input v-model="dishForm.price"></el-input>
</el-form-item>
<el-form-item label="菜品分类">
<el-select v-model="dishForm.categoryId" placeholder="请选择分类">
<!-- 这里应动态加载分类数据 -->
<el-option label="分类 1" value="1"></el-option>
</el-select>
</el-form-item>
<el-form-item label="菜品图片">
<el-upload
action="#"
:show-file-list="false"
@success="handleUploadSuccess">
<el-button size="small" type="primary">上传图片</el-button>
</el-upload>
<img v-if="dishForm.imageUrl" :src="dishForm.imageUrl" alt="菜品图片" width="100">
</el-form-item>
<el-form-item label="菜品描述">
<el-input type="textarea" v-model="dishForm.description"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="saveDish">保存</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { getDishList, addDish, updateDish, deleteDish } from '@/api/system/dish'
export default {
data() {
return {
queryParams: {
dishName: '',
categoryId: null
},
dishList: [],
dialogVisible: false,
dishForm: {}
}
},
created() {
this.getDishList()
},
methods: {
getDishList() {
getDishList(this.queryParams).then(response => {
this.dishList = response.rows
})
},
editDish(row) {
this.dishForm = { ...row }
this.dialogVisible = true
},
saveDish() {
if (this.dishForm.dishId) {
updateDish(this.dishForm).then(response => {
if (response.code === 200) {
this.$message.success('更新成功')
this.dialogVisible = false
this.getDishList()
}
})
} else {
addDish(this.dishForm).then(response => {
if (response.code === 200) {
this.$message.success('添加成功')
this.dialogVisible = false
this.getDishList()
}
})
}
},
deleteDish(dishId) {
this.$confirm('确定要删除该菜品吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
deleteDish(dishId).then(response => {
if (response.code === 200) {
this.$message.success('删除成功')
this.getDishList()
}
})
})
},
handleUploadSuccess(response, file, fileList) {
// 处理图片上传成功后的逻辑,更新 dishForm.imageUrl
this.dishForm.imageUrl = response.data.url
}
}
}
</script>
3. 路由配置
在 ruoyi-ui/src/router/index.js
文件中添加菜品管理页面的路由配置。
javascript
{
path: '/system/dish',
component: Layout,
children: [
{
path: 'index',
name: 'DishManagement',
component: () => import('@/views/system/dish/index'),
meta: { title: '菜品管理', icon: 'table' }
}
]
}
五、权限配置与测试
1. 权限配置
在系统管理 - 菜单管理中添加 “菜品管理” 菜单,设置相应的菜单信息,并关联到需要访问该模块的角色。同时,在 SysDishController
控制器的方法上添加权限注解,如 @PreAuthorize("@ss.hasPermi('system:dish:list')")
等。
2. 测试
启动若依后端和前端项目,使用具有相应权限的账号登录系统,测试菜品管理模块的各项功能,包括列表展示、添加、编辑、删除和查询等操作,确保功能正常且数据交互准确。
六、总结
通过本次二次开发,成功实现了若依框架下的菜品管理模块。在开发过程中,充分利用了若依框架的前后端结构和工具,遵循了数据库设计、实体类创建、Mapper 开发、服务层和控制器编写等后端开发流程,以及 API 封装、页面组件开发和路由配置等前端开发流程。同时,进行了权限配置,保证了系统的安全性和数据的访问控制。后续可以进一步优化该模块,如完善图片上传功能、优化界面样式等。