entity为了传递信息增加@Transient修饰的属性会污染实体纯净
@Entity
@Data
@DynamicUpdate
public class OrderMaster {
/** 订单id. */
@Id
private String orderId;
/** 买家名字. */
private String buyerName;
/** 买家手机号. */
private String buyerPhone;
/** 买家地址. */
private String buyerAddress;
/** 买家微信Openid. */
private String buyerOpenid;
/** 订单总金额. */
private BigDecimal orderAmount;
/** 订单状态, 默认为0新下单. */
private Integer orderStatus = OrderStatusEnum.NEW.getCode();
/** 支付状态, 默认为0未支付. */
private Integer payStatus = PayStatusEnum.WAIT.getCode();
/** 创建时间. */
private Date createTime;
/** 更新时间. */
private Date updateTime;
@Transient
private List<OrderDetail> orderDetailList;
}
订单对象中放入订单详情列表会方便传递信息,但造成订单实体的不纯洁,理论上应该和DB字段一一对应
DTO 数据传输对象就是用来解决上面的问题
@Data
public class OrderDTO {
/** 订单id. */
private String orderId;
/** 买家名字. */
private String buyerName;
/** 买家手机号. */
private String buyerPhone;
/** 买家地址. */
private String buyerAddress;
/** 买家微信Openid. */
private String buyerOpenid;
/** 订单总金额. */
private BigDecimal orderAmount;
/** 订单状态, 默认为0新下单. */
private Integer orderStatus;
/** 支付状态, 默认为0未支付. */
private Integer payStatus;
/** 创建时间. */
@JsonSerialize(using = Date2LongSerializer.class)
private Date createTime;
/** 更新时间. */
@JsonSerialize(using = Date2LongSerializer.class)
private Date updateTime;
List<OrderDetail> orderDetailList;
@JsonIgnore
public OrderStatusEnum getOrderStatusEnum() {
return EnumUtil.getByCode(orderStatus, OrderStatusEnum.class);
}
@JsonIgnore
public PayStatusEnum getPayStatusEnum() {
return EnumUtil.getByCode(payStatus, PayStatusEnum.class);
}
}
@Data
public class CartDTO {
/** 商品Id. */
private String productId;
/** 数量. */
private Integer productQuantity;
public CartDTO(String productId, Integer productQuantity) {
this.productId = productId;
this.productQuantity = productQuantity;
}
}
创建订单中的dto与entity交互
POST /sell/buyer/order/create
参数
name: "张三"
phone: "18868822111"
address: "慕课网总部"
openid: "ew3euwhd7sjw9diwkq" //用户的微信openid
items: [{
productId: "1423113435324",
productQuantity: 2 //购买数量
}]
@Override
@Transactional
public OrderDTO create(OrderDTO orderDTO) {
String orderId = KeyUtil.genUniqueKey()
BigDecimal orderAmount = new BigDecimal(BigInteger.ZERO)
//1. 查询商品(数量, 价格)
for (OrderDetail orderDetail: orderDTO.getOrderDetailList()) {
ProductInfo productInfo = productService.findOne(orderDetail.getProductId())
if (productInfo == null) {
throw new SellException(ResultEnum.PRODUCT_NOT_EXIST)
// throw new ResponseBankException()
}
//2. 计算订单总价
orderAmount = productInfo.getProductPrice()
.multiply(new BigDecimal(orderDetail.getProductQuantity()))
.add(orderAmount)
//订单详情入库
orderDetail.setDetailId(KeyUtil.genUniqueKey())
orderDetail.setOrderId(orderId)
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()
//先在DTO完成赋值,然后再对象拷贝到entity,否则容易覆盖
orderDTO.setOrderId(orderId)
BeanUtils.copyProperties(orderDTO, orderMaster)
orderMaster.setOrderAmount(orderAmount)
orderMaster.setOrderStatus(OrderStatusEnum.NEW.getCode())
orderMaster.setPayStatus(PayStatusEnum.WAIT.getCode())
orderMasterRepository.save(orderMaster)
//4. 扣库存
List<CartDTO> cartDTOList = orderDTO.getOrderDetailList().stream().map(e ->
new CartDTO(e.getProductId(), e.getProductQuantity())
).collect(Collectors.toList())
productService.decreaseStock(cartDTOList)
//发送websocket消息
webSocket.sendMessage(orderDTO.getOrderId())
return orderDTO
}
public class KeyUtil {
/**
* 生成唯一的主键
* 格式: 时间+随机数
* @return
*/
public static synchronized String genUniqueKey() {
Random random = new Random();
Integer number = random.nextInt(900000) + 100000;
return System.currentTimeMillis() + String.valueOf(number);
}
}
订单分页列表
@Override
public Page<OrderDTO> findList(String buyerOpenid, Pageable pageable) {
Page<OrderMaster> orderMasterPage = orderMasterRepository.findByBuyerOpenid(buyerOpenid, pageable);
List<OrderDTO> orderDTOList = OrderMaster2OrderDTOConverter.convert(orderMasterPage.getContent());
return new PageImpl<OrderDTO>(orderDTOList, pageable, orderMasterPage.getTotalElements());
}
public class OrderMaster2OrderDTOConverter {
public static OrderDTO convert(OrderMaster orderMaster) {
OrderDTO orderDTO = new OrderDTO();
BeanUtils.copyProperties(orderMaster, orderDTO);
return orderDTO;
}
public static List<OrderDTO> convert(List<OrderMaster> orderMasterList) {
return orderMasterList.stream().map(e ->
convert(e)
).collect(Collectors.toList());
}
}