1. 项目背景与核心需求
最近在开发一个餐饮管理系统时,遇到了菜品数据管理的需求。其中"删除菜品"这个看似简单的功能,实际上涉及到前后端交互、数据库操作、业务逻辑验证等多个技术环节。今天就来详细拆解这个功能的完整实现过程,分享我在实际开发中积累的经验。
在餐饮系统中,菜品数据通常包含名称、价格、分类、图片等核心字段。当某个菜品下架或需要调整时,就需要从系统中移除。但直接删除数据可能会引发关联订单查询异常等问题,因此需要设计合理的删除策略。这个功能虽然基础,但实现质量直接影响系统的健壮性。
2. 技术方案设计
2.1 接口设计规范
采用RESTful风格设计接口,具体规范如下:
- 请求方法:DELETE
- 请求路径:/api/dishes/
- 请求参数:路径参数id
- 响应格式:统一JSON格式
json复制{
"code": 200,
"message": "success",
"data": null
}
2.2 数据库设计考量
菜品表(dish)主要字段设计:
- id: 主键
- name: 菜品名称
- price: 价格
- category_id: 分类ID
- status: 状态(1-上架,0-下架)
- create_time: 创建时间
- update_time: 更新时间
重要提示:实际开发中建议采用逻辑删除而非物理删除,通过status字段标记删除状态,避免数据丢失风险。
3. 后端实现详解
3.1 Controller层实现
java复制@RestController
@RequestMapping("/api/dishes")
public class DishController {
@Autowired
private DishService dishService;
@DeleteMapping("/{id}")
public Result deleteDish(@PathVariable Long id) {
return dishService.deleteDish(id);
}
}
3.2 Service层业务逻辑
java复制@Service
public class DishServiceImpl implements DishService {
@Autowired
private DishMapper dishMapper;
@Override
@Transactional
public Result deleteDish(Long id) {
// 1. 校验菜品是否存在
Dish dish = dishMapper.selectById(id);
if (dish == null) {
return Result.error("菜品不存在");
}
// 2. 校验菜品状态
if (dish.getStatus() == 0) {
return Result.error("菜品已下架");
}
// 3. 执行删除(逻辑删除)
dish.setStatus(0);
dish.setUpdateTime(LocalDateTime.now());
dishMapper.updateById(dish);
return Result.success();
}
}
3.3 Mapper层数据库操作
java复制@Mapper
public interface DishMapper extends BaseMapper<Dish> {
// 使用MyBatis-Plus提供的基础方法即可
}
4. 前端调用实现
4.1 API封装
javascript复制// api/dish.js
import request from '@/utils/request'
export function deleteDish(id) {
return request({
url: `/api/dishes/${id}`,
method: 'delete'
})
}
4.2 页面调用示例
javascript复制// 在Vue组件中的调用
methods: {
handleDelete(id) {
this.$confirm('确认删除该菜品?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
deleteDish(id).then(response => {
this.$message.success('删除成功')
this.fetchDishList() // 刷新列表
})
}).catch(() => {
this.$message.info('已取消删除')
})
}
}
5. 关键问题与解决方案
5.1 并发删除问题
当多个用户同时删除同一菜品时可能出现并发问题。解决方案:
- 在Service方法添加@Transactional注解保证事务
- 对重要操作添加操作日志
- 前端添加防重复提交机制
5.2 关联数据处理
如果菜品已被订单关联,直接删除会导致数据不一致。推荐做法:
- 删除前检查关联订单
- 采用逻辑删除而非物理删除
- 重要数据添加删除确认弹窗
5.3 性能优化建议
- 高频删除操作添加缓存处理
- 批量删除接口实现分批处理
- 数据库字段添加合适索引
6. 测试用例设计
6.1 正常场景测试
- 测试删除存在的菜品
- 验证数据库状态字段变更
- 检查返回结果是否符合预期
6.2 异常场景测试
- 删除不存在的菜品ID
- 重复删除同一菜品
- 无权限用户尝试删除
- 网络异常时的处理
6.3 性能测试
- 模拟高并发删除请求
- 监控数据库CPU和内存使用
- 检查事务隔离级别是否合适
7. 项目经验总结
在实际开发中,删除功能的实现往往比表面看起来复杂。通过这个项目我总结了以下几点经验:
- 一定要采用逻辑删除而非物理删除,这是数据安全的基本保障
- 删除前必须做好各种校验,包括存在性校验、状态校验、权限校验等
- 对于重要数据的删除操作,必须添加确认提示和操作日志
- 高并发场景下要考虑锁的粒度和事务隔离级别
- 前端防重复提交机制可以有效避免很多意外情况
删除接口虽然简单,但需要考虑的边界条件很多。建议在开发完成后,专门针对各种异常情况进行充分测试,确保系统的健壮性。