1 地址簿模块
地址簿实体对象:
package com.sky.entity;import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;import java.io.Serializable;/*** 地址簿*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AddressBook implements Serializable {private static final long serialVersionUID = 1L;private Long id;//用户idprivate 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;
}
数据库地址簿表
1.1 Path 和 Method 设计
1.2 实现
controller
package com.sky.controller.user;import com.sky.context.BaseContext;
import com.sky.entity.AddressBook;
import com.sky.result.Result;
import com.sky.service.AddressBookService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.List;@RestController
@RequestMapping("/user/addressBook")
@Api(tags = "地址簿相关代码")
public class AddressBookController {@Autowiredprivate AddressBookService addressBookService;/*** 新增地址** @param addressBook* @return*/@ApiOperation("新增地址")@PostMappingpublic Result save(@RequestBody AddressBook addressBook) {// 这里要进行处理:// 1.设置 userId,因为传过来的addressBook无法拿到用户 idaddressBook.setUserId(BaseContext.getCurrentId());// 2.设置默认状态为 0,因为在新增地址模块不能先设置默认地址addressBook.setIsDefault(0);addressBookService.save(addressBook);return Result.success();}/*** 查询地址** @return*/@ApiOperation("查询地址")@GetMapping("/list")public Result<List<AddressBook>> list() {List<AddressBook> list = addressBookService.list();return Result.success(list);}/*** 查询默认地址** @return*/@ApiOperation("查询默认地址")@GetMapping("/default")public Result<AddressBook> getDefault() {AddressBook addressBook = addressBookService.getDefault();return Result.success(addressBook);}/*** 修改地址** @return*/@PutMapping@ApiOperation("修改地址")public Result update(@RequestBody AddressBook addressBook) {addressBookService.update(addressBook);return Result.success();}/*** 根据id删除地址** @param id* @return*/@DeleteMapping@ApiOperation("根据id删除地址")public Result deleteById(Long id) {addressBookService.deleteById(id);return Result.success();}/*** 根据id查询地址** @param id* @return*/@GetMapping("/{id}")@ApiOperation("根据id查询地址")public Result<AddressBook> getById(@PathVariable Long id) {AddressBook addressBook = addressBookService.getById(id);return Result.success(addressBook);}/*** 设置默认地址** @param addressBook* @return*/@PutMapping("/default")@ApiOperation("设置默认地址")public Result setDefault(@RequestBody AddressBook addressBook) {addressBookService.setDefault(addressBook);return Result.success();}
}
service
package com.sky.service.impl;import com.sky.context.BaseContext;
import com.sky.entity.AddressBook;
import com.sky.mapper.AddressBookMapper;
import com.sky.service.AddressBookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class AddressBookServiceImpl implements AddressBookService {@Autowiredprivate AddressBookMapper addressBookMapper;/*** 新增地址*/@Overridepublic void save(AddressBook addressBook) {addressBookMapper.save(addressBook);}/*** 查询地址** @return*/@Overridepublic List<AddressBook> list() {List<AddressBook> list = addressBookMapper.list();return list;}/*** 查询默认地址** @return*/@Overridepublic AddressBook getDefault() {return addressBookMapper.getDefault();}/*** 修改地址** @param addressBook*/@Overridepublic void update(AddressBook addressBook) {addressBookMapper.update(addressBook);}/*** 根据id删除地址** @param id*/@Overridepublic void deleteById(Long id) {addressBookMapper.deleteById(id);}/*** 根据id查询地址** @param id* @return*/@Overridepublic AddressBook getById(Long id) {AddressBook addressBook = addressBookMapper.getById(id);return addressBook;}/*** 设置默认地址** @param addressBook*/@Overridepublic void setDefault(AddressBook addressBook) {//1、将当前用户的所有地址修改为非默认地址 update address_book set is_default = ? where user_id = ?addressBook.setIsDefault(0);addressBook.setUserId(BaseContext.getCurrentId());addressBookMapper.updateIsDefaultByUserId(addressBook);//2、将当前地址改为默认地址 update address_book set is_default = ? where id = ?addressBook.setIsDefault(1);addressBookMapper.update(addressBook);}
}
mapper
package com.sky.mapper;import com.sky.entity.AddressBook;
import org.apache.ibatis.annotations.*;import java.util.List;@Mapper
public interface AddressBookMapper {/*** 新增地址** @param addressBook*/@Insert("insert into sky_take_out.address_book" +"(user_id, consignee, sex, phone, province_code, province_name, city_code, city_name, district_code, district_name, detail, label,is_default)" +"values " +"(#{userId}, #{consignee}, #{sex},#{phone}, #{provinceCode}, #{provinceName}, #{cityCode}, #{cityName}, #{districtCode}, #{districtName}, #{detail}, #{label}, #{isDefault})")void save(AddressBook addressBook);/*** 查询地址** @return*/
// 这里应该条件查询,代码复用
// @Select("select * from sky_take_out.address_book")List<AddressBook> list();/*** 查询默认地址** @return*/@Select("select * from sky_take_out.address_book where is_default = 1")AddressBook getDefault();/*** 修改地址** @param addressBook*/void update(AddressBook addressBook);/*** 根据id删除地址** @param id*/@Delete("delete from sky_take_out.address_book where id = #{id}")void deleteById(Long id);/*** 根据id查询地址** @param id* @return*/@Select("select * from sky_take_out.address_book where id = #{id}")AddressBook getById(Long id);/*** 根据 用户id修改 是否默认地址** @param addressBook*/@Update("update sky_take_out.address_book set is_default = #{isDefault} where user_id = #{userId}")void updateIsDefaultByUserId(AddressBook addressBook);
}
xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd" ><mapper namespace="com.sky.mapper.AddressBookMapper"><select id="list" parameterType="AddressBook" resultType="AddressBook">select * from sky_take_out.address_book<where><if test="userId != null">and user_id = #{userId}</if><if test="phone != null">and phone = #{phone}</if><if test="isDefault != null">and is_default = #{isDefault}</if></where></select><update id="update" parameterType="addressBook">update sky_take_out.address_book<set><if test="consignee != null">consignee = #{consignee},</if><if test="sex != null">sex = #{sex},</if><if test="phone != null">phone = #{phone},</if><if test="detail != null">detail = #{detail},</if><if test="label != null">label = #{label},</if><if test="isDefault != null">is_default = #{isDefault},</if></set>where id = #{id}</update></mapper>
1.3 测试
2 下单
为什么两张表:
订单表 是描述订单的
订单明细表 是描述订单里面的商品
2.1 实现
controller
service
package com.sky.service.impl;import com.sky.constant.MessageConstant;
import com.sky.context.BaseContext;
import com.sky.dto.OrdersSubmitDTO;
import com.sky.entity.AddressBook;
import com.sky.entity.OrderDetail;
import com.sky.entity.Orders;
import com.sky.entity.ShoppingCart;
import com.sky.exception.AddressBookBusinessException;
import com.sky.exception.ShoppingCartBusinessException;
import com.sky.mapper.AddressBookMapper;
import com.sky.mapper.OrderDetailMapper;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.ShoppingCartMapper;
import com.sky.service.OrderService;
import com.sky.vo.OrderSubmitVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.time.LocalDateTime;
import java.util.List;@Service
public class OrderServiceImpl implements OrderService {@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate OrderDetailMapper orderDetailMapper;@Autowiredprivate AddressBookMapper addressBookMapper;@Autowiredprivate ShoppingCartMapper shoppingCartMapper;/*** 用户下单** @param ordersSubmitDTO* @return*/public OrderSubmitVO submit(OrdersSubmitDTO ordersSubmitDTO) {// 处理异常(地址簿为空、购物车为空)AddressBook addressBook = addressBookMapper.getById(ordersSubmitDTO.getAddressBookId());if (addressBook == null) {throw new AddressBookBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL);}ShoppingCart shoppingCart = new ShoppingCart();shoppingCart.setUserId(BaseContext.getCurrentId());List<ShoppingCart> list = shoppingCartMapper.list(shoppingCart);if (list == null || list.isEmpty()) {throw new ShoppingCartBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);}// 订单表插入1条数据Orders order = new Orders();BeanUtils.copyProperties(ordersSubmitDTO, order);order.setOrderTime(LocalDateTime.now());order.setPayStatus(Orders.UN_PAID);order.setStatus(Orders.PENDING_PAYMENT);order.setNumber(String.valueOf(System.currentTimeMillis()));order.setPhone(addressBook.getPhone());order.setConsignee(addressBook.getConsignee());order.setUserId(BaseContext.getCurrentId());orderMapper.insert(order);// 订单明细表插入n条数据for (ShoppingCart cart :list) {OrderDetail orderDetail = new OrderDetail();BeanUtils.copyProperties(cart, orderDetail);orderDetail.setOrderId(order.getId()); // useGeneratedKeys="true" keyProperty="id"才可以获得主键值orderDetailMapper.insert(orderDetail);}// 清空购物车shoppingCartMapper.clean();// 封装VO返回OrderSubmitVO orderSubmitVO = OrderSubmitVO.builder().id(order.getId()).orderNumber(order.getNumber()).orderAmount(order.getAmount()).orderTime(order.getOrderTime()).build();return orderSubmitVO;}
}
mapper 略
2.2 测试
3 订单定时处理
3.1 定时处理 - - - Spring Task
Spring Task 是 spring 框架提供的任务调度工具,可以按照约定的时间 自动执行某个代码逻辑
cron 表达式 是一个字符串,通过 cron 表达式可以定义任务触发的时间,构成规则:分为 6 或 7 个域,由空格分隔开,每个域代表一个含义
每个域的含义分别为:秒、分钟、小时、日、月、周、年(可选)
在线Cron表达式生成器 (qqe2.com)
使用时,在启动类上加
@EnableScheduling 注解
然后在定时任务类上加注解
@Scheduled(cron = " ")
在控制台每一秒输出当前时间
对于订单超时任务,每一分钟检查一次,如果超时则自动取消订单
4 WebSocket //Todo
(回过头再看)
WebSocket 是基于 TCP 的一种新的 网络协议。它实现了 浏览器 与 服务器 全双工通信——浏览器和服务器只需要完成一次握手,两者之间就可以创建 持久性 的连接,并进行 双向数据传输。
来单提醒: