文章目录
- 前端补充功能
- 1、历史订单功能
- 1.1、梳理过程
- 1.2历史订单展示
- 1.3、效果展示
- 2、修改/删除地址
- 2.1、回显数据
- 梳理过程
- 代码展示
- 2.2、修改地址
- 梳理过程
- 代码
- 2.3、删除地址
- 梳理过程
- 代码展示
- 3、再来一单功能
- 3.1、梳理过程
- 3.2、具体实现思路(参考一下当初我们怎么添加购物车的)
- 4、购物车菜品减少按钮
- 后端补充功能
- 1、菜品启售/停售
- 2、菜品批量启售/停售
- 3、菜品批量删除
- 4、套餐修改
- 4.1、数据回显
- 4.2、套餐修改
前端补充功能
1、历史订单功能
1.1、梳理过程
当我们访问个人中心/历史订单的时候,都会发送请求
请求网址: http://localhost/order/userPage?page=1&pageSize=1
请求方法: GET
看样子是个分页的请求,我们之前把订单数据存进了order表中,那么该功能,大概率就是从表中查出数据然后返回给前端
那么具体要那些数据呢根据平时点外卖经验肯定是有具体的菜品、数量、价格,那么光靠一个order表是无法满足要求的,于是引入orderDao
特别注意
为什么要加入sumNum 因为该项目前端展示金额前端帮我们算好,但是我们不能相信前端数据,我们需要再后台计算一遍才好
@Data
public class OrdersDto extends Orders {
private int sumNum;
private List<OrderDetail> orderDetails;
}
1.2历史订单展示
大概流程就是先根据当前登录的用户id查询订单数据,再循环订单数据来查询每一单中具体的详细信息,然后计算金额,
然后将循环的order数据复制到ordersDto中,然后设置orderDto中的OrderDetails属性便可
//查询历史订单
@GetMapping("/userPage")
public R<Page> page(int page, int pageSize) {
//获取当前id
Long userId = BaseContext.getCurrentId();
Page<Orders> pageInfo = new Page<>(page, pageSize);
Page<OrdersDto> ordersDtoPage = new Page<>(page, pageSize);
//条件构造器
LambdaQueryWrapper<Orders> queryWrapper = new LambdaQueryWrapper<>();
//查询当前用户id订单数据
queryWrapper.eq(userId != null, Orders::getUserId, userId);
//按时间降序排序
queryWrapper.orderByDesc(Orders::getOrderTime);
orderService.page(pageInfo, queryWrapper);
List<OrdersDto> list = pageInfo.getRecords().stream().map((item) -> {
OrdersDto ordersDto = new OrdersDto();
//获取orderId,然后根据这个id,去orderDetail表中查数据
Long orderId = item.getId();
LambdaQueryWrapper<OrderDetail> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(OrderDetail::getOrderId, orderId);
List<OrderDetail> details = orderDetailService.list(wrapper);
//后端需要自己进行计算金额
// int j=0;
// for(int i=0;i<details.size();i++)
// {
// int a=details.get(i).getAmount().intValue();
// j=j+details.get(i).getAmount().intValue()*details.get(i).getNumber();
// }
// ordersDto.setSumNum(j);
BeanUtils.copyProperties(item, ordersDto);
//之后set一下属性
ordersDto.setOrderDetails(details);
return ordersDto;
}).collect(Collectors.toList());
BeanUtils.copyProperties(pageInfo, ordersDtoPage, "records");
ordersDtoPage.setRecords(list);
//日志输出看一下
log.info("list:{}", list.get(0));
return R.success(ordersDtoPage);
}
1.3、效果展示
2、修改/删除地址
2.1、回显数据
梳理过程
点击地址选项卡的铅笔图案,跳转到修改地址页面,发送请求
观察前端传的参数
请求网址: http://localhost/addressBook/1579828298672885762
请求方法: GET
这是一个restful风格传的参数,大概可以判断是传给后端一个id,然后结合前端判断是需要返回该id对应的地址
代码展示
/**
* 根据id查询地址
*/
@GetMapping("/{id}")
public R get(@PathVariable Long id) {
AddressBook addressBook = addressBookService.getById(id);
if (addressBook != null) {
return R.success(addressBook);
} else {
return R.error("没有找到该对象");
}
}
2.2、修改地址
梳理过程
点击上图中的保存地址按钮,查看发送的请求
请求网址: http://localhost/addressBook
请求方法: PUT
根据功能需求需要修改地址,可知后端需要用一个实体类接收数据
代码
@PutMapping
public R<String> updateaddress(@RequestBody AddressBook addressBook)
{
if (addressBook == null) {
throw new CustomException("地址信息不存在,请刷新重试");
}
addressBookService.updateById(addressBook);
return R.success("修改成功");
}
2.3、删除地址
梳理过程
点击上图中的删除地址按钮,查看发送的请求
请求网址: http://localhost/addressBook?ids=1579828298672885762
请求方法: DELETE
根据请求地址可知是根据id删除地址并且这不是restful风格,所以直接用一个Long类型参数接受便可
代码展示
@DeleteMapping()
public R<String> deleteAdd(@RequestParam("ids") Long id) {
if (id == null) {
throw new CustomException("地址信息不存在,请刷新重试");
}
AddressBook addressBook = addressBookService.getById(id);
if (addressBook == null) {
throw new CustomException("地址信息不存在,请刷新重试");
}
addressBookService.removeById(id);
return R.success("地址删除成功");
}
3、再来一单功能
3.1、梳理过程
这个功能其实比较隐晦,因为当订单状态为已完成时才会出现这个按钮(修改orders表中的status字段为4)。
查看请求的地址
请求网址: http://localhost/order/again
请求方法: POST
请求路径为/order/again,请求方式为POST,数据只携带了一个json格式的id数据,根据常识,这个id只能是orders表中的订单id,即order_id
{id: "1580121916188971009"}
这里其实有很多种想法,我想的是和平时外卖一样点击再来一单会跳转至购物车页面,然后之前选择的菜品会再次显示
3.2、具体实现思路(参考一下当初我们怎么添加购物车的)
之前是我们手动选择数据(菜品/套餐)添加到购物车,现在相当于我们手里有个发票,想办法看看上一单都买了啥,然后复刻一遍
分析完毕之后,我们来OrderController编写对应的方法
@PostMapping("/again")
public Result<String> again(@RequestBody Map<String,String> map){
//获取order_id
Long orderId = Long.valueOf(map.get("id"));
//条件构造器
LambdaQueryWrapper<OrderDetail> queryWrapper = new LambdaQueryWrapper<>();
//查询订单的口味细节数据
queryWrapper.eq(OrderDetail::getOrderId,orderId);
List<OrderDetail> details = orderDetailService.list(queryWrapper);
//获取用户id,待会需要set操作
Long userId = BaseContext.getCurrentId();
List<ShoppingCart> shoppingCarts = details.stream().map((item) ->{
ShoppingCart shoppingCart = new ShoppingCart();
//Copy对应属性值
BeanUtils.copyProperties(item,shoppingCart);
//设置一下userId
shoppingCart.setUserId(userId);
//设置一下创建时间为当前时间
shoppingCart.setCreateTime(LocalDateTime.now());
return shoppingCart;
}).collect(Collectors.toList());
//加入购物车
shoppingCartService.saveBatch(shoppingCarts);
return Result.success("喜欢吃就再来一单吖~");
}
这里我就直接用了BeanUtils.copyProperties直接复制了,然后在set两个属性,好像就可以了,不过我看数据库的时候,备注没有copy过来,地址是选择当前默认地址(如果你改了默认地址,那么不是之前的地址,好像也挺合理的)
4、购物车菜品减少按钮
思路分析
根据这前端传过来的id,来对不同的菜品/套餐的number属性修改(对应的数量-1),如果number等于0,则删除
@PostMapping("/sub")
public R<String> sub(@RequestBody ShoppingCart shoppingCart)
{
if(shoppingCart.getDishId()!=null)
{
LambdaQueryWrapper<ShoppingCart> lambdaQueryWrapper=new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(ShoppingCart::getDishId,shoppingCart.getDishId());
ShoppingCart shoppingCart1=shoppingCartService.getOne(lambdaQueryWrapper);
if(shoppingCart1.getNumber()>1)
{
shoppingCart1.setNumber(shoppingCart1.getNumber()-1);
shoppingCartService.updateById(shoppingCart1);
}
else
{
shoppingCartService.remove(lambdaQueryWrapper);
}
}
else
{
LambdaQueryWrapper<ShoppingCart> lambdaQueryWrapper=new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(ShoppingCart::getSetmealId,shoppingCart.getSetmealId());
ShoppingCart shoppingCart1=shoppingCartService.getOne(lambdaQueryWrapper);
if(shoppingCart1.getNumber()>1)
{
shoppingCart1.setNumber(shoppingCart1.getNumber()-1);
shoppingCartService.updateById(shoppingCart1);
}
else
{
shoppingCartService.remove(lambdaQueryWrapper);
}
}
return R.success("成功");
}
后端补充功能
1、菜品启售/停售
@PostMapping("/status/{status}")
public R<String> status(@PathVariable Integer status, Long ids) {
log.info("status:{},ids:{}", status, ids);
Dish dish = dishService.getById(ids);
if (dish != null) {
//直接用它传进来的这个status改就行
dish.setStatus(status);
dishService.updateById(dish);
return R.success("售卖状态修改成功");
}
return Result.error("系统繁忙,请稍后再试");
}
2、菜品批量启售/停售
@PostMapping("/status/{status}")
public R<String> status(@PathVariable Integer status, @RequestParam List<Long> ids) {
log.info("status:{},ids:{}", status, ids);
LambdaUpdateWrapper<Dish> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.in(ids != null, Dish::getId, ids);
updateWrapper.set(Dish::getStatus, status);
dishService.update(updateWrapper);
return R.success("批量操作成功");
}
3、菜品批量删除
@DeleteMapping()
public R<String> delete(@RequestParam List<Long> ids)
{
LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper();
queryWrapper.in(Dish::getId,ids);
queryWrapper.eq(Dish::getStatus,1);
Integer count=dishService.count(queryWrapper);
System.out.println(count);
if(count > 0){
//如果不能删除,抛出一个业务异常
throw new CustomException("套餐正在售卖中,不能删除");
}
for(int i=0;i<ids.size();i++)
{
dishService.removeById(ids.get(i));
}
return R.success("删除成功");
}
4、套餐修改
4.1、数据回显
点击修改按钮,查看发送的请求
请求网址: http://localhost/setmeal/1580361496716759041
请求方法: GET
这个请求大概率是用于处理数据回显的,请求路径/setmeal/{setmealId},请求方式GET
普通的Setmeal实体类肯定是不够用的,还是要用到SetmealDto
那么我们直接来SetmealController中编写对应的方法
@GetMapping("/{id}")
public R<SetmealDto> getById(@PathVariable Long id) {
Setmeal setmeal = setmealService.getById(id);
SetmealDto setmealDto = new SetmealDto();
//拷贝数据
BeanUtils.copyProperties(setmeal, setmealDto);
//条件构造器
LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
//根据setmealId查询具体的setmealDish
queryWrapper.eq(SetmealDish::getSetmealId, id);
List<SetmealDish> setmealDishes = setmealDishService.list(queryWrapper);
//然后再设置属性
setmealDto.setSetmealDishes(setmealDishes);
//作为结果返回
return R.success(setmealDto);
}
4.2、套餐修改
点击保存按钮,查看发送的请求
请求网址: http://localhost/setmeal
请求方法: PUT
@PutMapping
public R<Setmeal> updateWithDish(@RequestBody SetmealDto setmealDto) {
List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
Long setmealId = setmealDto.getId();
//先根据id把setmealDish表中对应套餐的数据删了
LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SetmealDish::getSetmealId,setmealId);
setmealDishService.remove(queryWrapper);
//然后在重新添加
setmealDishes = setmealDishes.stream().map((item) ->{
//这属性没有,需要我们手动设置一下
item.setSetmealId(setmealId);
return item;
}).collect(Collectors.toList());
//更新套餐数据
setmealService.updateById(setmealDto);
//更新套餐对应菜品数据
setmealDishService.saveBatch(setmealDishes);
return R.success(setmealDto);
}
还有一些简单的功能就不赘述了