IDEA写maven微信购物端项目的过程和注意重点(三)

买家订单(OrderMaster)

5.1、 流程一览

  1. 实体类
  • 两个实体类 OrderMaster.java和OrderDetail.java
  • 写了两个状态枚举类 OrderStatusEnum.java、PayStatusEnum.java
  1. dao接口
  • OrderMasterRepository.java和OrderDetailRepository.java
  • 测试类
  1. service层
  • OrderService.java
  • OrderDTO //数据传输对象(DTO是数据库中不存在的库,但代码中需要)
  • OrderServiceImpl.java
  • SellException.java // 错误信息
  • ResultEnum.java // 结果枚举
  • keyUtil.java // 随机数生成工具 时间戳(毫秒)+随机六位数
  • CartDTO.java// 购物车对象
  • 测试OrderServiceImpl

5.2 dao接口和测试类

5.2.1 OrderMasterRepository,查询回来结果按页查找

参数传入一个Pageable 对象

public interface OrderMasterRepository extends JpaRepository<OrderMaster, String>{
    // 通过id分页查找
    Page<OrderMaster> findByBuyerOpenid(String buyerOpenid, Pageable pageable);
}

5.2.2 OrderMasterRepository的测试类

但测试类中,传入的是PageRequest
因为PageRequest 继承一个抽象类,该抽象类又继承了Pageable
这里注意测试类的带page信息的测试方法

@RunWith(SpringRunner.class)
@SpringBootTest
public class OrderMasterRepositoryTest {
    @Autowired
    private OrderMasterRepository repository;

    @Test
    public void findByBuyerOpenid() throws Exception {
        PageRequest request = new PageRequest(0,3);     //获取第一页,获取3条记录
        Page<OrderMaster> result = repository.findByBuyerOpenid("110110", request);
        System.out.println(result.getTotalElements());
        Assert.assertNotEquals(0,result.getTotalElements());
    }
}

5.3 service层

5.3.1 OrderService

写一个OrderService的接口,因为一个订单会对应多个商品详细,为了方便,应该在OrderMaster实体类中,增加一个List,
但是这个List在数据库中并木有数据,@transient标签可以在对应数据库生成对象时,忽略该变量。

@Transient  // 对应数据库时 忽略
private List<OrderDetail> orderDetailList;

但一般不这样直接添加在原service上,而是建立一个dto类,OrderDTO.java

5.3.2 OrderDTO

DTO ---- date transform Object // 数据传输对象
该实体类和OrderMaster一毛一样,然后多一个orderDetailList变量

@Data
@DynamicUpdate      //自动更新时间
public class OrderDTO {
	... // 内容和OrderMaster一毛一样,就多下面这一行

    private List<OrderDetail> orderDetailList;

}

5.3.3 OrderServiceImpl

ProductServiceImpl.java中添加减库存的具体操作

@Service    //service端的注解
public class ProductServiceImpl implements ProductService {
    @Autowired
    ProductinfoRepository repository ;

    @Override
    @Transactional  // 事务回滚,如果操作失败,扔出error然后啥都不操作
    public void decreaseStock(List<CartDTO> cartDTOList) {
        for(CartDTO cartDTO : cartDTOList) {
            ProductInfo productInfo= repository.findOne(cartDTO.getProductId());
            if(productInfo == null) {
                throw new SellException(ResultEnum.PRODUCT_NOT_EXIST);
            }

            Integer result = productInfo.getProductStock() - cartDTO.getProductQuantity();
            if(result < 0 ) {
                throw new SellException(ResultEnum.PRODUCT_STOCK_ERROR);
            }

            productInfo.setProductStock(result);
            repository.save(productInfo);
        }
    }
}

OrderServiceImpl.java 中新建订单的代码
代码中多次使用lambda表达式,要多看,不容易看懂
用lambda表达式之前,都是先建一个购物车的list,然后for循环中向list中add对象,id和数量,
使用lambda表达式后,代码部分

@Service
public class OrderServiceImpl implements OrderService {
    @Override
    @Transactional  //事务回滚
    public OrderDTO create(OrderDTO orderDTO) {
        for(OrderDetail orderDetail : orderDTO.getOrderDetailList()) {
        }
        // 4.下单成功,减库存
        // 用lambda表达式
        List<CartDTO> cartDTOList= orderDTO.getOrderDetailList().stream().map(e ->
                new CartDTO(e.getProductId(), e.getProductQuantity())
        ).collect(Collectors.toList());
        orderDTO.getOrderDetailList();

        productService.decreaseStock(cartDTOList);
        return orderDTO;
    }
}

OrderServiceImpl .java 新增订单完整代码

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private ProductService productService;

    @Autowired
    private OrderDetailRepository orderDetailRepository;

    @Autowired
    private OrderMasterRepository orderMasterRepository;

    @Override
    @Transactional  //事务回滚
    public OrderDTO create(OrderDTO orderDTO) {
        // 一开始创建订单的时候就生成了订单id
        String orderId = KeyUtil.genUniqueKey();
        // 初始总价是0
        BigDecimal orderAmount = new BigDecimal(BigInteger.ZERO);


        // 存放购物车中详情的list ,但一般不用这种方法
//        List<CartDTO> cartDTOList = new ArrayList<>();


        // 1. 查询商品(数量,价格)
        for(OrderDetail orderDetail : orderDTO.getOrderDetailList()) {
            ProductInfo productInfo = productService.findOne(orderDetail.getProductId());
            if(productInfo == null){
                throw new SellException(ResultEnum.PRODUCT_NOT_EXIST);
            }
            // 2.计算订单总价
            orderAmount = orderDetail.getProductPrice()
                    .multiply(new BigDecimal(orderDetail.getProductQuantity()))
                    .add(orderAmount);

            // 3.订单详情入库(页面只传id和quantity数量)
            orderDetail.setDetailId(KeyUtil.genUniqueKey());    // 原来详情中商品的id是自己生成的??
            orderDetail.setOrderId(orderId);
                    // 拷贝productInfo中的属性
            BeanUtils.copyProperties(productInfo, orderDetail);
            orderDetailRepository.save(orderDetail);

            // 信息写入购物车,但一般不用这种方法
//            CartDTO cartDTO = new CartDTO(orderDetail.getProductId(), orderDetail.getProductQuantity());
//            cartDTOList.add(cartDTO);

        }
        // 3.写入订单数据库(orderMaster和orderDetail都要写入)
        OrderMaster orderMaster = new OrderMaster();
        orderMaster.setOrderId(orderId);
        orderMaster.setOrderAmount(orderAmount);
        // 拷贝数据
        BeanUtils.copyProperties(orderDTO, orderMaster);
        // 写入数据看
        orderMasterRepository.save(orderMaster);

        // 4.下单成功,减库存
        // 用lambda表达式

        List<CartDTO> cartDTOList= orderDTO.getOrderDetailList().stream().map(e ->
                new CartDTO(e.getProductId(), e.getProductQuantity())
        ).collect(Collectors.toList());
        orderDTO.getOrderDetailList();

        productService.decreaseStock(cartDTOList);
        return orderDTO;
    }
}

5.3.4 SellException 错误类

从ResultEnum 读需要返回的错误信息。

public class SellException extends RuntimeException{
    private Integer code;

    public SellException(ResultEnum resultEnum) {
        super(resultEnum.getMessage());

        this.code = resultEnum.getCode();
    }
}

5.3.5 keyUtil .java 生成随机数

注意加锁!!光是时间戳不够!!

public class keyUtil {
    /**
     * 生成唯一主键
     * 格式:时间+随机数
     * */
    public static synchronized String genUniqueKey() {
        Random random = new Random();
        Integer number = random.nextInt(900000)+100000;  //生成6位随机数

        return System.currentTimeMillis() + String.valueOf(number);
    }
}

5.3.6 CartDTO 购物车对象,传需要的id、Quantity数量

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值