Java项目实战跟练day12------springboot + mybatis plus开发
套餐管理
新增套餐
前后端交互分析:
1.页面(backend/page/combo/add.html)发送ajax请求,请求服务端获取套餐分类 数据并展示到下拉框中。
2.页面发送ajax请求,请求服务端获取菜品分类 数据并展示到添加菜品窗口中。
3.页面发送ajax请求,请求服务端,根据菜品分类查询 对应的菜品数据并展示到添加菜品窗口中。
4.页面发送请求进行图片上传 ,请求服务端将图片保存到服务器。
5.页面发送请求进行图片下载 ,将上传的图片进行回显。
6.点击保存按钮,发送ajax请求,将套餐 相关数据以json形式提交到服务端。
请求1、2、4、5均已实现。
请求1前端:
java
// 获取套餐分类
getDishTypeList() {
getCategoryList({ type: 2, page: 1, pageSize: 1000 }).then((res) => {
if (res.code === 1) {
this.setMealList = res.data.map((obj) => ({ ...obj, idType: obj.id }))
} else {
this.$message.error(res.msg || '操作失败')
}
})
},
java
// 获取菜品分类列表
const getCategoryList = (params) => {
return $axios({
url: '/category/list',
method: 'get',
params
})
}
请求1后端:
CategoryController.java
java
/**
* 菜品列表按条件查询
* @param category
*/
@GetMapping("/list")
public R<List<Category>> list(Category category){
log.info("接收的分类类型为:{}",category);
//条件构造器
LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
//添加条件
queryWrapper.eq(category.getType()!=null,Category::getType,category.getType());
//添加排序条件
//优先按照sort序号排序,再按照更新时间排序
queryWrapper.orderByDesc(Category::getSort).orderByDesc(Category::getUpdateTime);
List<Category> list = categoryService.list(queryWrapper);
return R.success(list);
}
请求2前端:
java
// 获取套餐分类
getDishType () {
getCategoryList({'type':1}).then(res => {
if (res.code === 1) {
this.dishType = res.data
this.getDishList(res.data[0].id)
} else {
this.$message.error(res.msg)
}
})
},
java
// 获取菜品分类列表
const getCategoryList = (params) => {
return $axios({
url: '/category/list',
method: 'get',
params
})
}
请求2后端:
CategoryController.java
java
/**
* 菜品列表按条件查询
* @param category
*/
@GetMapping("/list")
public R<List<Category>> list(Category category){
log.info("接收的分类类型为:{}",category);
//条件构造器
LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
//添加条件
queryWrapper.eq(category.getType()!=null,Category::getType,category.getType());
//添加排序条件
//优先按照sort序号排序,再按照更新时间排序
queryWrapper.orderByDesc(Category::getSort).orderByDesc(Category::getUpdateTime);
List<Category> list = categoryService.list(queryWrapper);
return R.success(list);
}
请求3前端:
java
// 通过套餐ID获取菜品列表分类
getDishList (id) {
queryDishList({categoryId: id}).then(res => {
if (res.code === 1) {
if (res.data.length == 0) {
this.dishAddList = []
return
}
let newArr = res.data;
newArr.forEach((n) => {
n.dishId = n.id
n.copies = 1
// n.dishCopies = 1
n.dishName = n.name
})
this.dishAddList = newArr
} else {
this.$message.error(res.msg)
}
})
},
java
// 查菜品列表的接口
const queryDishList = (params) => {
return $axios({
url: '/dish/list',
method: 'get',
params
})
}
请求3后端:
DishController.java
java
/**
* 根据分类id进行菜品的条件查询
* @param dish
* @return
*/
@GetMapping("/list")
public R<List<Dish>> list(Dish dish){
log.info("接收的菜品id:{}",dish);
Long id = dish.getCategoryId();
//条件构造器
LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
//添加条件
queryWrapper.eq(dish.getCategoryId()!=null,Dish::getCategoryId,id);
//添加条件:查询起售状态的菜品
queryWrapper.eq(Dish::getStatus,1);
//添加排序条件
//优先按照sort序号排序,再按照更新时间排序
queryWrapper.orderByDesc(Dish::getSort).orderByDesc(Dish::getUpdateTime);
List<Dish> list = dishService.list(queryWrapper);
return R.success(list);
}
请求6前端:
java
if (this.actionType == 'add') {
delete prams.id
addSetmeal(prams)
.then((res) => {
if (res.code === 1) {
this.$message.success('套餐添加成功!')
if (!st) {
this.goBack()
} else {
.......
java
// 新增数据接口
const addSetmeal = (params) => {
return $axios({
url: '/setmeal',
method: 'post',
data: { ...params }
})
}
请求6后端:
SetmealController.java
java
/**
* ClassName:SetmealDishController
* Description:套餐管理
*
* @Author:Hyt
* @Create:2024/2/18 10:44
* @Version 1.0
*/
@Controller
@RestController
@Slf4j
@RequestMapping("/setmeal")
public class SetmealController {
@Autowired
private SetmealService setmealService;
@Autowired
private SetmealDishService setmealDishService;
/**
*新增套餐
* @param setmealDto
* @return
*/
@PostMapping
public R<String> add(@RequestBody SetmealDto setmealDto){
log.info(setmealDto.toString());
setmealService.saveWithDishs(setmealDto);
return R.success("新增套餐成功!");
}
}
SetmealService.java
java
@Service
public interface SetmealService extends IService<Setmeal> {
//新增套餐,同时插入套餐关联的菜品数据,需要操作两张表:setmeal、setmeal_dish
public void saveWithDishs(SetmealDto setmealDto);
}
SetmealServicelmpl.java
java
@Service
public class SetmealServicelmpl extends ServiceImpl<SetmealMapper, Setmeal> implements SetmealService {
@Autowired
private SetmealDishService setmealDishService;
@Transactional
public void saveWithDishs(SetmealDto setmealDto) {
//保存套餐的基本信息到套餐表setmeal
this.save(setmealDto);
//获取套餐id
Long setmealId = setmealDto.getId();
// //为套餐关联的菜品设置id
// List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
// for (SetmealDish setmealDish : setmealDishes) {
// setmealDish.setSetmealId(setmealId);
// setmealDishService.save(setmealDish);
// }
//关联菜品
List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
setmealDishes = setmealDishes.stream().map((item) -> {
item.setSetmealId(setmealId);
return item;
}).collect(Collectors.toList());
//保存关联的菜品数据到表setmeal_dish中
setmealDishService.saveBatch(setmealDishes);
}
}
套餐信息分页查询
前后端交互分析:
1、页面(backend/page/combo/list.html)发送ajax请求,将分页查询参数(page、pageSize、name)提交到服务端,获取分页数据。
2、页面发送请求,请求服务端进行图片下载,用于页面图片展示
前端:
java
async init () {
const params = {
page: this.page,
pageSize: this.pageSize,
name: this.input ? this.input : undefined
}
await getSetmealPage(params).then(res => {
if (String(res.code) === '1') {
this.tableData = res.data.records || []
this.counts = res.data.total
}
}).catch(err => {
this.$message.error('请求出错了:' + err)
})
},
java
// 查询列表数据
const getSetmealPage = (params) => {
return $axios({
url: '/setmeal/page',
method: 'get',
params
})
}
后端:
SetmealController.java
java
/**
* 套餐分页查询
* @param page
* @param pageSize
* @param name
* @return
*/
@GetMapping("/page")
public R<Page> page(int page, int pageSize,String name){
log.info("套餐分页信息:page={},pageSize={},name={}",page,pageSize,name);
//构建分页构造器
Page<Setmeal> pageInfo = new Page(page,pageSize);
Page<SetmealDto> setmealDtoPage = new Page(page,pageSize);
//构建条件构造器
LambdaQueryWrapper<Setmeal> queryWrapper1 = new LambdaQueryWrapper<>();
//添加过滤条件
queryWrapper1.like(name!=null, Setmeal::getName,name);
//添加排序条件
queryWrapper1.orderByDesc(Setmeal::getUpdateTime);
//执行查询
setmealService.page(pageInfo,queryWrapper1);
//对象拷贝
BeanUtils.copyProperties(pageInfo,setmealDtoPage,"records");
List<Setmeal> records = pageInfo.getRecords();
List <SetmealDto> list = records.stream().map((item)->{
SetmealDto setmealDto = new SetmealDto();
BeanUtils.copyProperties(item,setmealDto);
Long categoryId = item.getCategoryId();//获取分类id
Category category = categoryService.getById(categoryId);//通过id获取分类对象
if(category!=null){
String categoryName = category.getName();
setmealDto.setCategoryName(categoryName);
}
return setmealDto;
}).collect(Collectors.toList());
setmealDtoPage.setRecords(list);
return R.success(setmealDtoPage);
}
套餐起售、停售
单个起停售、批量起停售两种情况。
前端
java
{
// 起售停售---批量起售停售接口
setmealStatusByStatus(params).then(res => {
if (res.code === 1) {
this.$message.success('套餐状态已经更改成功!')
this.handleQuery()
} else {
this.$message.error(res.msg || '操作失败')
}
}).catch(err => {
this.$message.error('请求出错了:' + err)
})
}
java
// 批量起售禁售
const setmealStatusByStatus = (params) => {
return $axios({
url: `/setmeal/status/${params.status}`,
method: 'post',
params: { ids: params.ids }
})
}
后端
java
/**
* 套餐单个/批量起停售
* @param status
* @param ids
* @return
*/
@PostMapping("/status/{status}")
public R<String> editStatus(@PathVariable Integer status, Long[] ids){
log.info("套餐状态:{},套餐id:{}",status,ids);
for (Long id : ids) {
Setmeal setmeal = setmealService.getById(id);
setmeal.setStatus(status);
setmealService.updateById(setmeal);
}
return R.success("修改套餐状态成功!");
}
套餐删除
单个删除、批量删除两种情况。
前端
java
{
deleteSetmeal(type === '批量' ? this.checkList.join(',') : id).then(res => {
if (res.code === 1) {
this.$message.success('删除成功!')
this.handleQuery()
} else {
this.$message.error(res.msg || '操作失败')
}
}).catch(err => {
this.$message.error('请求出错了:' + err)
})
}
java
// 删除数据接口
const deleteSetmeal = (ids) => {
return $axios({
url: '/setmeal',
method: 'delete',
params: { ids }
})
}
后端
SetmealController.java
java
/**
* 套餐单个/批量删除
* @param ids
* @return
*/
@DeleteMapping
public R<String> delete(@RequestParam List<Long> ids){
log.info("接收的待删除套餐id:{}",ids);
setmealService.deleteWithDishs(ids);
return R.success("删除套餐成功!");
}
SetmealService.java
java
//删除套餐,同时阐述套餐关联的菜品数据,需要操作两张表:setmeal、setmeal_dish
public void deleteWithDishs(List<Long> ids);
SetmealServicelmpl.java
java
/**
* 删除套餐及关联的菜品数据
* @param ids
*/
@Transactional
public void deleteWithDishs(List<Long> ids) {
//处理方式一
// //构建条件构造器
// LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
//
// for (Long id : ids) {
// //查询套餐售卖状态
// if(this.getById(id).getStatus()==0){
// //在setmeal表中删除套餐数据
// this.removeById(id);
//
// //添加过滤条件
// queryWrapper.like(id!=null, SetmealDish::getSetmealId,id);
//
// //执行删除操作
// setmealDishService.remove(queryWrapper);
// } else{
// break;
// }
// }
//处理方式二
//构建条件构造器
LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
LambdaQueryWrapper<SetmealDish> setmealDishqueryWrapper = new LambdaQueryWrapper<>();
//添加过滤条件
queryWrapper.in(Setmeal::getId,ids);
queryWrapper.eq(Setmeal::getStatus,1);
int count = this.count(queryWrapper);
if(count>0){
throw new CustomException("套餐正在售卖,不能删除!");
}
//套餐可删除,先删除套餐信息,操作setmeal表格
this.removeByIds(ids);
//删除套餐关联的菜品信息,操作setmeal_dish表格
setmealDishqueryWrapper.in(SetmealDish::getSetmealId,ids);
setmealDishService.remove(setmealDishqueryWrapper);
}