效果展示
1. 导入用户地址簿相关功能代码 6-2
1.1 需求分析 6-2
1.2 数据模型 6-2
用户的地址信息会存储在address_ book表,即地址簿表中。具体表结构如下:
1.3 导入功能代码 6-2
功能代码清单:
●实体类AddressBook (直接从课程资料中导入即可)
●Mapper接口 AddressBookMapper
●业务层接口AddressBookService
●业务 层实现类AddressBookServicelmpl
●控制层AddressBookController ( 直接从课程资料中导入即可)
地址簿实体类 AddressBook
package com.itheima.reggie.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 地址簿实体类 6-2
*/
@Data
public class AddressBook implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
//用户id
private Long userId;
//收货人
private String consignee;
//手机号
private String phone;
//性别 0 女 1 男
private String sex;
//省级区划编号
private String provinceCode;
//省级名称
private String provinceName;
//市级区划编号
private String cityCode;
//市级名称
private String cityName;
//区级区划编号
private String districtCode;
//区级名称
private String districtName;
//详细地址
private String detail;
//标签
private String label;
//是否默认 0 否 1是
private Integer isDefault;
//创建时间
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
//更新时间
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
//创建人
@TableField(fill = FieldFill.INSERT)
private Long createUser;
//修改人
@TableField(fill = FieldFill.INSERT_UPDATE)
private Long updateUser;
//是否删除
private Integer isDeleted;
}
地址簿 持久层接口AddressBookMapper
package com.itheima.reggie.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.reggie.entity.AddressBook;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
//地址簿 持久层接口 6-2
@Mapper
public interface AddressBookMapper extends BaseMapper {
}
地址簿业务层接口 AddressBookService
package com.itheima.reggie.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.itheima.reggie.entity.AddressBook;
//地址簿业务层接口 6-2
public interface AddressBookService extends IService {
}
地址簿业务层接口 实现类AddressBookServiceImpl
package com.itheima.reggie.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.entity.AddressBook;
import com.itheima.reggie.mapper.AddressBookMapper;
import com.itheima.reggie.service.AddressBookService;
import org.springframework.stereotype.Service;
//地址簿业务层接口 实现类 6-2
@Service
public class AddressBookServiceImpl extends ServiceImpl implements AddressBookService {
}
地址簿管理 控制层AddressBookController
package com.itheima.reggie.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 地址簿管理 控制层 6-2
*/
@Slf4j
@RestController
@RequestMapping("/addressBook")
public class AddressBookController {
@Autowired
private AddressBookService addressBookService;
/**
* 新增
*/
@PostMapping
public R save(@RequestBody AddressBook addressBook) {
addressBook.setUserId(BaseContext.getCurrentId());
log.info("addressBook:{}", addressBook);
addressBookService.save(addressBook);
return R.success(addressBook);
}
/**
* 设置默认地址
*/
@PutMapping("default")
public R setDefault(@RequestBody AddressBook addressBook) {
log.info("addressBook:{}", addressBook);
LambdaUpdateWrapper 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 = ?
addressBookService.update(wrapper);
addressBook.setIsDefault(1);
//SQL:update address_book set is_default = 1 where id = ?
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 getDefault() {
LambdaQueryWrapper 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 addressBook) {
addressBook.setUserId(BaseContext.getCurrentId());
log.info("addressBook:{}", addressBook);
//条件构造器
LambdaQueryWrapper 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));
}
}
测试 6-2
新增成功
设置默认地址成功
根据id查询地址
我们只要进入地址管理界面,就会自动根据用户id查询其下所有地址
1.4 拓展修改地址 自己实现
AddressBookController
//修改地址,自己实现
@PutMapping
public R update(@RequestBody AddressBook addressBook){
addressBookService.updateById(addressBook);
return R.success("地址修改成功");
}
修改成功
2. 菜品展示 6-3
2.1 需求分析 6-3
2.2 代码开发-梳理交互过程 6-4
在开发代码之前,需要梳理一下前端页面和服务端的交互过程:
1、页面(front/index.html)发送ajax请求,获取分类数据(菜品分类和套餐分类)
2、页面发送ajax请求,获取第一一个分类下的菜品或者套餐开发菜品展示功能,其实就是在服务端编写代码去处理前端页面发送的这2次请求即可。
注意:首页加载完成后,还发送了一次ajax请求用于加载购物车数据,此处可以将这次请求的地址暂时修改一下,从静态json文件获取数据,等后续开发购物车功能时再修改回来,如下:
2.3 展示菜品数据 功能开发 6-4
用户刚打开后,发送一个请求,用来获取菜品和套餐的分类信息,这个功能我们在之前已经开发了,但是为什么没有展示出来分类呢,因为页面紧接着有发送了另外一次请求加载购物车数据,但是我们还没实现此功能所以没有展示页面(因为前端写的是这两次请求必须同时成功,才可展示)
所以我们为了不报错
在front下添加一个cartData.json的文件,应付一下这个请求
按ctrl,鼠标点击进入
修改以下
//获取购物车内商品的集合
function cartListApi(data) {
return $axios({
//'url': '/shoppingCart/list',
'url': '/front/carData.json',
'method': 'get',
params:{...data}
})
}
再次登录即可展示数据
(菜品展示功能我们之前已经开发了)
2.4 菜品展示改造 6-5
因为我们的菜品都设置了口味信息,但是前端并没有显示选择口味的按钮,只是有一个+号,是因为我们使用的返回类型是dish,其中并没有口味属性,所以使用dishDto作为返回值可以实现
菜品管理DishController
//根据菜品分类的id查询菜品改造 6-5
@GetMapping("/list")
public R> list(Dish dish){
//构造查询条件对象
LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper();
queryWrapper.eq(dish.getCategoryId()!=null,Dish::getCategoryId,dish.getCategoryId());
//添加条件,查询状态为1的也就是起售的菜品
queryWrapper.eq(Dish::getStatus,1);
//添加排序条件
queryWrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);
List list = dishService.list(queryWrapper);
//遍历list集合
List dishDtoList = list.stream().map((item)->{
DishDto dishDto = new DishDto();
//将普通数据赋值进dishDto
BeanUtils.copyProperties(item,dishDto);
//设置菜品分类名
Long categoryId = item.getCategoryId();//分类id
//根据id查询分类对象
Category category = categoryService.getById(categoryId);
if(category != null){
String categoryName = category.getName();
dishDto.setCategoryName(categoryName);
}
//设置菜品口味
Long id = item.getId();
LambdaQueryWrapper dishFlavorLambdaQueryWrapper = new LambdaQueryWrapper();
dishFlavorLambdaQueryWrapper.eq(DishFlavor::getDishId,id);
List dishFlavorList = dishFlavorService.list(dishFlavorLambdaQueryWrapper);
dishDto.setFlavors(dishFlavorList);
return dishDto;
}).collect(Collectors.toList());
return R.success(dishDtoList);
}
测试成功
2.5 展示套餐数据 6-6
套餐管理控制层SetmealController
/**
* 根据条件查询套餐数据
* @param setmeal
* @return
*/
@GetMapping("/list")
public R> list(Setmeal setmeal){
LambdaQueryWrapper 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 list = setmealService.list(queryWrapper);
return R.success(list);
}
测试
3. 购物车 6-7
3.1 需求分析 6-7
3.2 数据模型 6-7
购物车对应的数据表为shopping_cart表,具体表结构如下
购物车实体类 ShoppingCart
package com.itheima.reggie.entity;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* 购物车实体类 6-7
*/
@Data
public class ShoppingCart implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
//名称
private String name;
//用户id
private Long userId;
//菜品id
private Long dishId;
//套餐id
private Long setmealId;
//口味
private String dishFlavor;
//数量
private Integer number;
//金额
private BigDecimal amount;
//图片
private String image;
private LocalDateTime createTime;
}
购物车持久层接口 ShoppingCartMapper
package com.itheima.reggie.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.reggie.entity.ShoppingCart;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
//购物车持久层接口 6-7
@Mapper
public interface ShoppingCartMapper extends BaseMapper {
}
购物车业务层 接口ShoppingCartService
package com.itheima.reggie.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.itheima.reggie.entity.ShoppingCart;
//购物车业务层 接口 6-7
public interface ShoppingCartService extends IService {
}
购物车 业务层接口实现类ShoppingCartServiceImpl
package com.itheima.reggie.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.entity.ShoppingCart;
import com.itheima.reggie.mapper.ShoppingCartMapper;
import com.itheima.reggie.service.ShoppingCartService;
import org.springframework.stereotype.Service;
//购物车 业务层接口实现类 6-7
@Service
public class ShoppingCartServiceImpl extends ServiceImpl implements ShoppingCartService {
}
购物车控制层ShoppingCartController
package com.itheima.reggie.controller;
import com.itheima.reggie.service.ShoppingCartService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
//购物车控制层
@Slf4j
@RestController
@RequestMapping("/shoppingCart")
public class ShoppingCartController {
@Autowired
private ShoppingCartService shoppingCartService;
}
3.3 代码开发-梳理交互过程 6-7
在开发代码之前,需要梳理一.下购物车操作时前端页面和服务端的交互过程:
1、点击加入购物车或者+按钮,页面发送ajax请求,请求服务端,将菜品或者套餐添加到购物车
2、点击购物车图标,页面发送ajax请求,请求服务端查询购物车中的菜品和套餐
3、点击清空购物车按钮,页面发送ajax请求,请求服务端来执行清空购物车操作
开发购物车功能,其实就是在服务端编写代码去处理前端页面发送的这3次请求即可。
3.4 加入购物车 功能开发 6-8
购物车控制层ShoppingCartController
//加入购物车 6-8
@PostMapping("/add")
public R add(@RequestBody ShoppingCart shoppingCart){
log.info("购物车数据:{}",shoppingCart);
//设置用户id
//由debug调试和线圈传来的数据可知,前端并没有吧useId给我们,如果我们不设置userId的话
//根本就不知道这个购物车是谁的
//这个是从线程中取用户id
Long currentId = BaseContext.getCurrentId();
shoppingCart.setUserId(currentId);
//查询当前添加菜品或者套餐是否已经存在购物车了
Long dishId = shoppingCart.getDishId();
//构造查询条件userId和菜品id或者套餐id可以查出唯一值
LambdaQueryWrapper 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/setmeal_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);
}
测试添加成功
在添加相同的菜品
添加套餐成功
3.5 查看购物车 6-9
把之前修改的也买你改回来
购物车控制层ShoppingCartController
/**
* 查看购物车 6-9
* @return
*/
@GetMapping("/list")
public R> list(){
log.info("查看购物车...");
//构造查询条件,根据用户id来查
LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper();
queryWrapper.eq(ShoppingCart::getUserId,BaseContext.getCurrentId());
queryWrapper.orderByAsc(ShoppingCart::getCreateTime);
List list = shoppingCartService.list(queryWrapper);
return R.success(list);
}
3.6 清空购物车 6-9
购物车控制层ShoppingCartController
/**
* 清空购物车 6-9
* @return
*/
@DeleteMapping("/clean")
public R clean(){
//SQL:delete from shopping_cart where user_id = ?
LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper();
queryWrapper.eq(ShoppingCart::getUserId,BaseContext.getCurrentId());
shoppingCartService.remove(queryWrapper);
return R.success("清空购物车成功");
}
3.7 减少购物车中的菜品数量 自己实现
购物车控制层ShoppingCartController
//减少购物车中的菜品或者套餐数量 自己实现
@PostMapping("/sub")
public R sub(@RequestBody ShoppingCart shoppingCart){
Long currentId = BaseContext.getCurrentId();
shoppingCart.setUserId(currentId);
//查询
LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper();
queryWrapper.eq(ShoppingCart::getUserId,currentId);
//判断是菜品还是套餐
Long dishId = shoppingCart.getDishId();
if(dishId != null){
//是菜品
queryWrapper.eq(ShoppingCart::getDishId,dishId);
}else {
//是套餐
queryWrapper.eq(ShoppingCart::getSetmealId,shoppingCart.getSetmealId());
}
//取出菜品或者套餐的数据
ShoppingCart cartServiceOne = shoppingCartService.getOne(queryWrapper);
//查出当前菜品或者套餐的数量
Integer number = cartServiceOne.getNumber();
if(number==1){
//菜品数量为1了,直接从购物车中删除
shoppingCartService.remove(queryWrapper);
cartServiceOne.setNumber(0);
return R.success(cartServiceOne);
}else {
cartServiceOne.setNumber(number-1);
shoppingCartService.updateById(cartServiceOne);
}
return R.success(cartServiceOne);//这个返回是给前端页面做展示的,不是给购物车的而购物车会自己刷新
}
测试成功
4. 用户下单 6-10
4.1 需求分析 6-10
4.2 数据模型 6-10
用户下单业务对应的数据表为orders表和order_ _detail表 :
●orders: 订单表
●order_ detail: 订单明细表
4.3 代码开发-梳理交互过程 6-11
在开发代码之前,需要梳理一下用户下单操作时前端页面和服务端的交互过程:
1、在购物车中点击去结算按钮, 页面跳转到订单确认页面
2、在订单确认页面,发送ajax请求,请求服务端获取当前登录用户的默认地址
3、在订单确认页面,发送ajax请求,请求服务端获取当前登录用户的购物车数据
4、在订单确认页面点击去支付按钮, 发送ajax请求,请求服务端完成 下单操作
开发用户下单功能,其实就是在服务端编写代码去处理前端页面发送的请求即可。
4.4 数据准备 6-11
在开发业务功能前,先将需要用到的类和接口基本结构创建好:
●实体类Orders. OrderDetail ( 直接从课程资料中导入即可)
●Mapper接口 OrderMapper、OrderDetailMapper
●业务层接口OrderService、OrderDetailService
●业务层实现类OrderServicelmpl、OrderDetailServicelmpl
●控制层OrderController. OrderDetailController
订单实体类 Orders
package com.itheima.reggie.entity;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* 订单实体类 6-11
*/
@Data
public class Orders implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
//订单号
private String number;
//订单状态 1待付款,2待派送,3已派送,4已完成,5已取消
private Integer status;
//下单用户id
private Long userId;
//地址id
private Long addressBookId;
//下单时间
private LocalDateTime orderTime;
//结账时间
private LocalDateTime checkoutTime;
//支付方式 1微信,2支付宝
private Integer payMethod;
//实收金额
private BigDecimal amount;
//备注
private String remark;
//用户名
private String userName;
//手机号
private String phone;
//地址
private String address;
//收货人
private String consignee;
}
订单明细实体类OrderDetail
package com.itheima.reggie.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 订单明细实体类
*/
@Data
public class OrderDetail implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
//名称
private String name;
//订单id
private Long orderId;
//菜品id
private Long dishId;
//套餐id
private Long setmealId;
//口味
private String dishFlavor;
//数量
private Integer number;
//金额
private BigDecimal amount;
//图片
private String image;
}
订单持久层接口OrderMapper
package com.itheima.reggie.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.reggie.entity.Orders;
import org.apache.ibatis.annotations.Mapper;
//订单持久层接口 6-11
@Mapper
public interface OrderMapper extends BaseMapper {
}
订单明细持久层接口OrderDetailMapper
package com.itheima.reggie.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.reggie.entity.OrderDetail;
import org.apache.ibatis.annotations.Mapper;
//订单明细持久层接口 6-11
@Mapper
public interface OrderDetailMapper extends BaseMapper {
}
订单业务层接口OrderService
package com.itheima.reggie.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.itheima.reggie.entity.Orders;
//订单业务层接口 6-11
public interface OrderService extends IService {
}
订单明细业务层接口OrderDetailService
package com.itheima.reggie.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.itheima.reggie.entity.OrderDetail;
//订单明细业务层接口 6-11
public interface OrderDetailService extends IService {
}
订单业务层接口实现类OrderServiceImpl
package com.itheima.reggie.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.entity.*;
import com.itheima.reggie.mapper.OrderMapper;
import com.itheima.reggie.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
//订单业务层接口实现类 6-11
@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl implements OrderService {
}
订单业务层接口实现类OrderServiceImpl
package com.itheima.reggie.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.entity.*;
import com.itheima.reggie.mapper.OrderMapper;
import com.itheima.reggie.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
//订单业务层接口实现类 6-11
@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl implements OrderService {
}
订单明细业务层接口实现类OrderDetailServiceImpl
package com.itheima.reggie.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.entity.OrderDetail;
import com.itheima.reggie.mapper.OrderDetailMapper;
import com.itheima.reggie.service.OrderDetailService;
import org.springframework.stereotype.Service;
//订单明细业务层接口实现类 6-11
@Service
public class OrderDetailServiceImpl extends ServiceImpl implements OrderDetailService {
}
订单控制层OrderController
package com.itheima.reggie.controller;
import com.itheima.reggie.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
//订单控制层 6-11
@Slf4j
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
private OrderService orderService;
}
订单明细控制层OrderDetailController
package com.itheima.reggie.controller;
import com.itheima.reggie.service.OrderDetailService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
//订单明细控制层 6-11
@Slf4j
@RestController
@RequestMapping("/orderDetail")
public class OrderDetailController {
@Autowired
private OrderDetailService orderDetailService;
}
4.4 用户下单功能开发 6-12
订单业务层接口OrderService
//用户下单 6-12
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 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;
//订单业务层接口实现类 6-11
@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl implements OrderService {
@Autowired
private ShoppingCartService shoppingCartService;
@Autowired
private UserService userService;
@Autowired
private AddressBookService addressBookService;
@Autowired
private OrderDetailService orderDetailService;
//用户下单 6-12 6-13 6-14
@Override
@Transactional
public void submit(Orders orders) {
//获得当前用户id
Long userId = BaseContext.getCurrentId();
//查询当前用户的购物车数据
//根据用户id查
LambdaQueryWrapper wrapper = new LambdaQueryWrapper();
wrapper.eq(ShoppingCart::getUserId,userId);
List shoppingCarts = shoppingCartService.list(wrapper);
if(shoppingCarts == null || shoppingCarts.size() == 0){
throw new CustomException("购物车为空,不能下单");
}
//查询用户数据
User user = userService.getById(userId);
//查询地址数据
Long addressBookId = orders.getAddressBookId();
AddressBook addressBook = addressBookService.getById(addressBookId);
if(addressBook == null){
throw new CustomException("用户地址信息有误,不能下单");
}
//以上将订单表所需数据都准备好了,下面直接将上述数据封装进订单表数据库即可
//生成订单号 6-14
long orderId = IdWorker.getId();
//遍历购物车数据,计算总金额和封装订单明细表数据
AtomicInteger amount = new AtomicInteger(0);//用来计算金额,他是一个原子的操作,在多线程也可以保证数据准确
List orderDetails = shoppingCarts.stream().map((item)->{
OrderDetail orderDetail = new OrderDetail();
orderDetail.setOrderId(orderId);//订单id
orderDetail.setNumber(item.getNumber());//菜品或者套餐数量
orderDetail.setDishFlavor(item.getDishFlavor());//菜品口味
orderDetail.setDishId(item.getDishId());//菜品id
orderDetail.setSetmealId(item.getSetmealId());//套餐id
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());
//向订单表插入数据 6-14
orders.setId(orderId);//订单id
orders.setOrderTime(LocalDateTime.now());//生成订单时间
orders.setCheckoutTime(LocalDateTime.now());//结账时间
orders.setStatus(2);//2代表带派送
orders.setAmount(new BigDecimal(amount.get()));//总金额
orders.setUserId(userId);//用户id
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);
}
}
订单控制层OrderController
/**
* 用户下单 6-12
* @param orders
* @return
*/
@PostMapping("/submit")
public R submit(@RequestBody Orders orders){
log.info("订单数据:{}",orders);
orderService.submit(orders);
return R.success("下单成功");
}
测试成功
5. 服务端订单明细 自己实现
订单控制层OrderController
//服务端订单明细 分页查询 自己实现
@GetMapping("/page")
public R page(int page,int pageSize,String number){
//构造分页构造器
Page pageInfo = new Page();
//构造查询条件
LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper();
//构造订单号进行模糊查询
queryWrapper.eq(number!=null,Orders::getNumber,number);
//添加排序条件,根据更新时间降序排列
queryWrapper.orderByDesc(Orders::getOrderTime);
orderService.page(pageInfo,queryWrapper);
return R.success(pageInfo);
}
测试成功
6. 移动端 显示订单明细 自己实现
订单控制层OrderController
有bug
//移动端订单明细 分页查询 自己实现,由bug
@GetMapping("/userPage")
public R userPage(int page,int pageSize){
//构造分页构造器
Page pageInfo = new Page();
//构造查询条件
LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper();
//构造用户id进行查询
queryWrapper.eq(Orders::getUserId, BaseContext.getCurrentId());
//添加排序条件,根据更新时间降序排列
queryWrapper.orderByDesc(Orders::getOrderTime);
orderService.page(pageInfo,queryWrapper);
return R.success(pageInfo);
}
7. 移动端客户退出登录 自己实现
UserController
//移动端客户退出登录 自己实现
@PostMapping("/loginout")
public R logout(HttpServletRequest request){
//1、清理Session中的用户id
request.getSession().removeAttribute("user");
//2、返回结果
return R.success("退出登录成功");
}
至此项目基础部分已经完成,后面开始对项目进行优化
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
Py之imbalanced-ensemble:imbalanced-ensemble库的简介、安装、使用方法之详细攻略 目录 imbalanced-ensemble库的简介 imbalanced-ensemble库的安装 imbalanced-ensemble…