目录
1、用户地址簿
1.1、分析
1.1.1、需求分析
1.1.2、数据模型
用户的地址信息会存储在 address_book 表,即地址簿表中。具体表结构如下:
1.1.3、导入代码
2、菜品展示
2.1、分析
2.1.1、需求分析
2.1.2、交互过程
2.2、代码
2.2.1、代码修改
前端在初始化时发送上面的两次请求后,需要都成功才会渲染数据
initData(){
// 两次请求都成功蔡渲染页面
Promise.all([categoryListApi(),cartListApi({})]).then(res=>{
//获取分类数据
if(res[0].code === 1){
this.categoryList = res[0].data
if(Array.isArray(res[0].data) && res[0].data.length > 0){
this.categoryId = res[0].data[0].id
if(res[0].data[0].type === 1){
this.getDishList()
}else{
this.getSetmealData()
}
}
}else{
this.$notify({ type:'warning', message:res[0].msg});
}
//获取菜品数据
if(res[1].code === 1){
this.cartData = res[1].data
}else{
this.$notify({ type:'warning', message:res[1].msg});
}
})
},
所以将获取购物车的请求修改为获取假数据
//获取购物车内商品的集合
function cartListApi(data) {
return $axios({
// 'url': '/shoppingCart/list',
'url': '/front/cartData.json',
'method': 'get',
params:{...data}
})
}
假数据内容
{"code":1,"msg":null,"data":[],"map":{}}
修改完后便可以看到展示的菜品及图品,但没有其口味信息,因为 DishController 中的 list 方法返回的是 Dish 实体类,而 Dish 中没有口味属性,需要添加口味属性,要返回 DishDto
/**
* 根据条件查询菜品数据
* @param dish
* @return
*/
/*@GetMapping("/list")
public R<List<Dish>> list(Dish dish){
LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(dish.getCategoryId() != null, Dish::getCategoryId, dish.getCategoryId());
queryWrapper.eq(Dish::getStatus, 1);
queryWrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);
List<Dish> list = dishSerivce.list(queryWrapper);
return R.success(list);
}*/
@GetMapping("/list")
public R<List<DishDto>> list(Dish dish){
LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(dish.getCategoryId() != null, Dish::getCategoryId, dish.getCategoryId());
queryWrapper.eq(Dish::getStatus, 1);
queryWrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);
List<Dish> list = dishSerivce.list(queryWrapper);
List<DishDto> dishDtoList = list.stream().map((item) -> {
DishDto dishDto = new DishDto();
BeanUtils.copyProperties(item, dishDto);
// 获取分类名称
Long categoryId = item.getCategoryId();
Category category = categoryService.getById(categoryId);
if(category != null){
String categoryName = category.getName();
dishDto.setCategoryName(categoryName);
}
// 获取口味信息
Long dishId = item.getId();
LambdaQueryWrapper<DishFlavor> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(DishFlavor::getDishId, dishId);
List<DishFlavor> dishFlavorList = dishFlavorService.list(wrapper);
dishDto.setFlavors(dishFlavorList);
return dishDto;
}).collect(Collectors.toList());
return R.success(dishDtoList);
}
2.2.2、获取套餐信息
请求:
在 SetmealController 中添加方法
/**
* 根据条件获取套餐数据
* @param setmeal
* @return
*/
@GetMapping("/list")
public R<List<Setmeal>> list(Setmeal setmeal){
LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(setmeal.getCategoryId() != null, Setmeal::getCategoryId, setmeal.getCategoryId());
queryWrapper.eq(setmeal.getStatus() != null, Setmeal::getStatus, setmeal.getStatus());
queryWrapper.orderByDesc(Setmeal::getUpdateTime);
List<Setmeal> list = setmealService.list(queryWrapper);
return R.success(list);
}
3、购物车
3.1、分析
3.1.1、需求分析
3.1.2、数据模型
购物车对应的数据表为 shopping_cart 表,具体表结构如下:
3.1.3、交互过程
3.1.4、准备工作
将获取购物车信息的代码改回来
3.2、代码
3.2.1、向购物车添加菜品或套餐
添加菜品请求:
添加套餐请求:
在 ShoppingCartController 添加方法
/**
* 向购物车添加菜品或套餐
* @param shoppingCart
* @return
*/
@PostMapping("/add")
public R<ShoppingCart> add(@RequestBody ShoppingCart shoppingCart){
// 设置用户id,指定当前是哪个用户的购物车数据
Long currentId = BaseContext.getCurrentId();
shoppingCart.setUserId(currentId);
// 查询当前菜品或套餐是否在购物车中
Long dishId = shoppingCart.getDishId();
LambdaQueryWrapper<ShoppingCart> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(ShoppingCart::getUserId, currentId);
if(dishId != null){
// 添加到购物车的是菜品
queryWrapper.eq(ShoppingCart::getDishId, dishId);
} else {
// 添加到购物车的是套餐
queryWrapper.eq(ShoppingCart::getSetmealId, shoppingCart.getSetmealId());
}
ShoppingCart cart = shoppingCartService.getOne(queryWrapper);
if(cart != null){
// 如果已存在,在原来的数量上加一
cart.setNumber(cart.getNumber() + 1);
shoppingCartService.updateById(cart);
} else {
// 如果不存在,则添加到购物车,默认数量为1
shoppingCart.setNumber(1);
shoppingCart.setCreateTime(LocalDateTime.now());
shoppingCartService.save(shoppingCart);
cart = shoppingCart;
}
return R.success(cart);
}
3.2.2、获取购物车信息
获取购物车信息的请求:
在 ShoppingCartController 添加方法
/**
* 查看购物车
* @return
*/
@GetMapping("/list")
public R<List<ShoppingCart>> list(){
LambdaQueryWrapper<ShoppingCart> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(ShoppingCart::getUserId, BaseContext.getCurrentId());
queryWrapper.orderByAsc(ShoppingCart::getCreateTime);
List<ShoppingCart> list = shoppingCartService.list(queryWrapper);
return R.success(list);
}
3.2.3、清空购物车
清空购物车请求:
在 ShoppingCartController 添加方法
/**
* 清空购物车
* @return
*/
@DeleteMapping("/clean")
public R<String> clean(){
LambdaQueryWrapper<ShoppingCart> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(ShoppingCart::getUserId, BaseContext.getCurrentId());
shoppingCartService.remove(queryWrapper);
return R.success("清空购物车成功");
}
3.2.4、减少购物车菜品或套餐
请求:
/**
* 减少购物车菜品或套餐
* @return
*/
@PostMapping("/sub")
public R<ShoppingCart> sub(@RequestBody ShoppingCart shoppingCart){
Long currentId = BaseContext.getCurrentId();
LambdaQueryWrapper<ShoppingCart> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(ShoppingCart::getUserId, currentId);
ShoppingCart cart = null;
// 获取要减少的菜品或套餐信息
Long dishId = shoppingCart.getDishId();
if(dishId == null){
// 减少的是套餐数量
Long setmealId = shoppingCart.getSetmealId();
queryWrapper.eq(ShoppingCart::getSetmealId, setmealId);
cart = shoppingCartService.getOne(queryWrapper);
} else {
// 减少的是菜品数量
queryWrapper.eq(ShoppingCart::getDishId, dishId);
cart = shoppingCartService.getOne(queryWrapper);
}
Integer number = cart.getNumber();
if(number > 1){
cart.setNumber(number - 1);
shoppingCartService.updateById(cart);
} else {
shoppingCartService.removeById(cart.getId());
}
return R.success(cart);
}
4、用户下单
4.1、分析
4.1.1、需求分析
4.1.2、数据模型
用户下单业务对应的数据表为 orders 表和 order_detail 表:
orders 表:
order_detail 表
4.1.3、交互过程
4.1.4、准备工作
4.2、代码
4.2.1、支付
支付请求:
① 在 OrderServiceImpl 实现方法
package com.itheima.reggie.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.common.BaseContext;
import com.itheima.reggie.common.CustomException;
import com.itheima.reggie.entity.*;
import com.itheima.reggie.mapper.OrderMapper;
import com.itheima.reggie.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Orders> implements OrderService {
@Autowired
private ShoppingCartService shoppingCartService;
@Autowired
private UserService userService;
@Autowired
private AddressBookService addressBookService;
@Autowired
private OrderDetailService orderDetailService;
/**
* 用户下单
* @param orders
*/
@Transactional
public void submit(Orders orders) {
//获得当前用户id
Long userId = BaseContext.getCurrentId();
// 查询当前用户的购物车数据
LambdaQueryWrapper<ShoppingCart> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(ShoppingCart::getUserId, userId);
List<ShoppingCart> shoppingCarts = shoppingCartService.list(queryWrapper);
if(shoppingCarts == null || shoppingCarts.size() == 0){
throw new CustomException("购物车为空,无法下单");
}
// 查询用户数据
User user = userService.getById(userId);
// 查询地址信息
AddressBook addressBook = addressBookService.getById(orders.getAddressBookId());
if(addressBook == null){
throw new CustomException("用户地址信息有误,无法下单");
}
// 生成订单号
long orderId = IdWorker.getId();
// 计算订单总金额
AtomicInteger amount = new AtomicInteger(0); // 保证线程安全
List<OrderDetail> orderDetails = shoppingCarts.stream().map((item) -> {
OrderDetail orderDetail = new OrderDetail();
orderDetail.setOrderId(orderId);
orderDetail.setNumber(item.getNumber());
orderDetail.setDishFlavor(item.getDishFlavor());
orderDetail.setDishId(item.getDishId());
orderDetail.setSetmealId(item.getSetmealId());
orderDetail.setName(item.getName());
orderDetail.setImage(item.getImage());
orderDetail.setAmount(item.getAmount());
amount.addAndGet(item.getAmount().multiply(new BigDecimal(item.getNumber())).intValue()); // +=
return orderDetail;
}).collect(Collectors.toList());
// 向订单表插入数据
orders.setId(orderId);
orders.setOrderTime(LocalDateTime.now());
orders.setCheckoutTime(LocalDateTime.now());
orders.setStatus(2);
orders.setAmount(new BigDecimal(amount.get())); //总金额
orders.setUserId(userId);
orders.setNumber(String.valueOf(orderId));
orders.setUserName(user.getName());
orders.setConsignee(addressBook.getConsignee());
orders.setPhone(addressBook.getPhone());
orders.setAddress((addressBook.getProvinceName() == null ? "" : addressBook.getProvinceName())
+ (addressBook.getCityName() == null ? "" : addressBook.getCityName())
+ (addressBook.getDistrictName() == null ? "" : addressBook.getDistrictName())
+ (addressBook.getDetail() == null ? "" : addressBook.getDetail()));
this.save(orders);
// 向订单明细表插入数据(多条数据)
orderDetailService.saveBatch(orderDetails);
// 清空购物车数据
shoppingCartService.remove(queryWrapper);
}
}
② 在 OrderController 中使用方法
/**
* 支付订单
* @param orders
* @return
*/
@PostMapping("/submit")
public R<String> submit(@RequestBody Orders orders){
orderService.submit(orders);
return null;
}