07 移动端——菜品展示
导入用户地址簿相关功能代码
预准备
代码实现
复制AddressBook
类到entity下,写好相对应的结构,最后在AddressBookController
类下:
package com.itheima.reggie.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.itheima.reggie.common.BaseContext;
import com.itheima.reggie.common.R;
import com.itheima.reggie.entity.AddressBook;
import com.itheima.reggie.service.AddressBookService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @author shkstart
* @create 2023-07-01 11:14
*/
@Slf4j
@RestController
@RequestMapping("/addressBook")
public class AddressBookController {
@Autowired
private AddressBookService addressBookService;
/**
* 新增
*/
@PostMapping
public R<AddressBook> save(@RequestBody AddressBook addressBook){
addressBook.setUserId(BaseContext.getCurrentId());
log.info("addressBook:{}",addressBook);
addressBookService.save(addressBook);
return R.success(addressBook);
}
/**
* 设置默认地址
*/
@PutMapping("/default")
public R<AddressBook> setDefault(@RequestBody AddressBook addressBook){
log.info("addressBook:{}",addressBook);
LambdaUpdateWrapper<AddressBook> wrapper=new LambdaUpdateWrapper<>();
wrapper.eq(AddressBook::getUserId,BaseContext.getCurrentId());
wrapper.set(AddressBook::getIsDefault, 0);
//sql:update address_book set is_default = 0 where user_id = ?
//找到这个用户创建的地址,再将所有isDefault字段下的值改为0,确保只有一个默认地址
addressBookService.update(wrapper);
//将当前的地址改成默认地址
addressBook.setIsDefault(1);
addressBookService.updateById(addressBook);
return R.success(addressBook);
}
/**
* 根据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("没有找到该对象");
}
}
/**
* 查询默认地址
*/
@GetMapping("/default")
public R<AddressBook> getDefault(){
LambdaQueryWrapper<AddressBook> queryWrapper=new LambdaQueryWrapper<>();
queryWrapper.eq(AddressBook::getUserId,BaseContext.getCurrentId());
queryWrapper.eq(AddressBook::getIsDefault,1);
//Sql:select * from address_book where user_id = ? and is_default = 1
AddressBook addressBook=addressBookService.getOne(queryWrapper);
if(null==addressBook){
return R.error("没有找到该对象");
}else{
return R.success(addressBook);
}
}
/**
* 查询指定用户的全部地址
*/
@GetMapping("/list")
public R<List<AddressBook>> list(AddressBook addressBook){
addressBook.setUserId(BaseContext.getCurrentId());
log.info("addressBook:{}",addressBook);
//条件构造器
LambdaQueryWrapper<AddressBook> queryWrapper=new LambdaQueryWrapper<>();
queryWrapper.eq(null!=addressBook.getUserId(),AddressBook::getUserId,addressBook.getUserId());
queryWrapper.orderByDesc(AddressBook::getUpdateTime);
//sql:select * from address_book where user_id = ? order by update_time desc
return R.success(addressBookService.list(queryWrapper));
}
}
菜品展示
预准备
菜品分类和套餐分类。
前端代码:
分类数据可以,但是购物车数据没有写,所以没有都满足,在移动端就显示不了数据。
交互逻辑
代码实现
展示分类数据(购物车暂时不弄)
- 修改
front/js/main.js
文件,改成访问静态资源:
//获取购物车内商品的集合
function cartListApi(data) {
return $axios({
// 'url': '/shoppingCart/list',
'url': '/front/cartData.json',
'method': 'get',
params:{...data}
})
}
- 复制day06下的
/front/cartData.json
到对应位置。
修改展示数据,增加口味数据显示
修改DishController
类下的list
方法:
/**
* 根据条件查询对应的菜品数据
* @param dish
* @return
*/
@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 = dishService.list(queryWrapper);
List<DishDto> dishDtoList = list.stream().map(item->{
DishDto dishDto=new DishDto();
BeanUtils.copyProperties(item,dishDto);
//根据id查询分类,让后台显示数据
Long categoryId=item.getCategoryId();
Category category = categoryService.getById(categoryId);
//因为导入的数据有些菜品没有分类名称,所以加个判断以防报错
if(category!=null){
String categoryName =category.getName();
dishDto.setCategoryName(categoryName);
}
//根据id查询口味数据,追加数据,方便移动端显示
LambdaUpdateWrapper<DishFlavor> LambdaQueryWrapper=new LambdaUpdateWrapper<>();
//查到了菜品还要查它对应的口味数据
LambdaQueryWrapper.eq(DishFlavor::getDishId,item.getId());
List<DishFlavor> dishFlavors = dishFlavorService.list(LambdaQueryWrapper);
dishDto.setFlavors(dishFlavors);
return dishDto;
}).collect(Collectors.toList());
return R.success(dishDtoList);
}
套餐分页数据展示
在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);
}
注意:如果提示有idea 在源文件中提示 Cannot resolve method,但是项目可以编译运行的问题,看看这个帖子,解决方案。
购物车
预准备
代码实现
复制`ShoppingCart.java`到entity下,创建其他对应的结构。
增加购物车
ShoppingCartController
类下编写:
package com.itheima.reggie.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.itheima.reggie.common.BaseContext;
import com.itheima.reggie.common.R;
import com.itheima.reggie.entity.AddressBook;
import com.itheima.reggie.entity.ShoppingCart;
import com.itheima.reggie.service.AddressBookService;
import com.itheima.reggie.service.ShoppingCartService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @author shkstart
* @create 2023-07-01 11:14
*/
@Slf4j
@RestController
@RequestMapping("/shoppingCart")
public class ShoppingCartController {
@Autowired
private ShoppingCartService shoppingCartService;
/**
* 添加购物车
* @param shoppingCart
* @return
*/
@PostMapping("/add")
public R<ShoppingCart> add(@RequestBody ShoppingCart shoppingCart){
log.info("购物车数据:{}",shoppingCart);
//设置用户id,指定哪个用户的购物车数据
Long currentId=BaseContext.getCurrentId();
shoppingCart.setUserId(currentId);
//查询当前菜品或者套餐是否在购物车当中,有了就修改number
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());
}
//SQL:select * from shopping_cart where user_id = ? and dish_id/setmea_id = ?
ShoppingCart cartServiceOne = shoppingCartService.getOne(queryWrapper);
//如果已经存在,就在原来数量基础上加一
if(cartServiceOne!=null){
Integer number = cartServiceOne.getNumber();
cartServiceOne.setNumber(number+1);
shoppingCartService.updateById(cartServiceOne);
}else {
//如果不存在,则添加到购物车,数量默认就是一
shoppingCart.setNumber(1);
shoppingCart.setCreateTime(LocalDateTime.now());
shoppingCartService.save(shoppingCart);
cartServiceOne=shoppingCart;
}
return R.success(cartServiceOne);
}
/**
* 新增
*/
@GetMapping
public R<Object> list(){
log.info("购物车!");
return null;
}
}
查看购物车
-
修改front/api/main.js:
-
在
ShoppingCartController
下:-
/** * 查看购物车 * @return */ @GetMapping("/list") public R<List<ShoppingCart>> list(){ log.info("查看购物车..."); 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); }
-
清空购物车
ShoppingCartController
下:
/**
* 清空购物车
* @return
*/
@DeleteMapping("/clean")
public R<String> clean(){
//sql:delete from shopping_cart where user_id=?
LambdaQueryWrapper<ShoppingCart> lambdaQueryWrapper=new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(ShoppingCart::getUserId,BaseContext.getCurrentId());
shoppingCartService.remove(lambdaQueryWrapper);
return R.success("清空购物车");
}
下单
预准备
默认地址。
查询购物数据。
提交订单。
代码实现
用户下单提交
-
在
OrderController
:-
package com.itheima.reggie.controller; import com.itheima.reggie.common.R; import com.itheima.reggie.entity.Orders; import com.itheima.reggie.service.OrderService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @author 订单 * @create 2023-07-04 16:42 */ @RestController @Slf4j @RequestMapping("/order") public class OrderController { @Autowired private OrderService orderService; /** * 用户下单 * @param orders * @return */ @PostMapping("/submit") public R<String> submit(@RequestBody Orders orders){ log.info("订单数据:{}",orders); orderService.submit(orders); return R.success("下单成功"); } }
-
-
在
OrderService
:-
package com.itheima.reggie.service; import com.baomidou.mybatisplus.extension.service.IService; import com.itheima.reggie.entity.Orders; /** * @author shkstart * @create 2023-07-04 16:35 */ public interface OrderService extends IService<Orders> { /** * 用户下单 * @param orders */ public void submit(Orders orders); }
-
-
在
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 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.Collector; import java.util.stream.Collectors; /** * @author shkstart * @create 2023-07-04 16:39 */ @Service public class OrderServiceImpl extends ServiceImpl<OrderMapper,Orders> implements OrderService { @Autowired private ShoppingCartService shoppingCartService; @Autowired private UserService userService; @Autowired private OrderDetailService orderDetailService; @Autowired private AddressBookService addressBookService; /** * 用户下单 * @param orders */ @Transactional @Override public void submit(Orders orders) { //获得当前用户id Long currentId = BaseContext.getCurrentId(); //查询当前用户的购物车数据 LambdaQueryWrapper<ShoppingCart> wrapper=new LambdaQueryWrapper<>(); wrapper.eq(ShoppingCart::getUserId,currentId); List<ShoppingCart> shoppingCarts = shoppingCartService.list(wrapper); if(shoppingCarts==null || shoppingCarts.size()==0){ throw new CustomException("购物车为空,不能下单"); } //查询用户数据 User user = userService.getById(currentId); //向订单表插入一条数据 Long addressBookId = orders.getAddressBookId(); AddressBook addressBook = addressBookService.getById(addressBookId); 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.setOrderTime(LocalDateTime.now()); orders.setCheckoutTime(LocalDateTime.now()); orders.setStatus(2); orders.setAmount(new BigDecimal(amount.get()));//总金额 orders.setUserId(currentId); 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(wrapper); } }
-