步骤1:
创建orders订单表,子订单表和订单状态表对应的pojo和mappper
Orders和OrderItemsMapper
OrderItems和OrderItemsMapper
OrderStatus和OrderStatusMapper
步骤2:创建OrderService和对应的实现类
public interface OrderService {
/**
* 用于创建订单相关信息
* @param submitOrderBO
*/
public OrderVO createOrder(SubmitOrderBO submitOrderBO);
}
package com.one.service.order.impl;
import com.one.bo.SubmitOrderBO;
import com.one.enums.OrderStatusEnum;
import com.one.enums.YesOrNo;
import com.one.mapper.OrderItemsMapper;
import com.one.mapper.OrderStatusMapper;
import com.one.mapper.OrdersMapper;
import com.one.pojo.*;
import com.one.service.address.AddressService;
import com.one.service.item.ItemService;
import com.one.service.order.OrderService;
import com.one.vo.MerchantOrdersVO;
import com.one.vo.OrderVO;
import org.n3r.idworker.Sid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private OrdersMapper ordersMapper;
@Autowired
private OrderItemsMapper orderItemsMapper;
@Autowired
private OrderStatusMapper orderStatusMapper;
@Autowired
private AddressService addressService;
@Autowired
private ItemService itemService;
@Autowired
private Sid sid;
@Transactional(propagation = Propagation.REQUIRED)
@Override
public OrderVO createOrder(SubmitOrderBO submitOrderBO) {
String userId = submitOrderBO.getUserId();
String addressId = submitOrderBO.getAddressId();
String itemSpecIds = submitOrderBO.getItemSpecIds();
Integer payMethod = submitOrderBO.getPayMethod();
String leftMsg = submitOrderBO.getLeftMsg();
// 包邮费用设置为0
Integer postAmount = 0;
String orderId = sid.nextShort();
UserAddress address = addressService.queryUserAddres(userId, addressId);
// 1. 新订单数据保存
Orders newOrder = new Orders();
newOrder.setId(orderId);
newOrder.setUserId(userId);
newOrder.setReceiverName(address.getReceiver());
newOrder.setReceiverMobile(address.getMobile());
newOrder.setReceiverAddress(address.getProvince() + " " + address.getCity() + " " + address.getDistrict() + " " + address.getDetail());
newOrder.setPostAmount(postAmount);
newOrder.setPayMethod(payMethod);
newOrder.setLeftMsg(leftMsg);
newOrder.setIsComment(YesOrNo.NO.type);
newOrder.setIsDelete(YesOrNo.NO.type);
newOrder.setCreatedTime(new Date());
newOrder.setUpdatedTime(new Date());
// 2. 循环根据itemSpecIds保存订单商品信息表
String itemSpecIdArr[] = itemSpecIds.split(",");
Integer totalAmount = 0; // 商品原价累计
Integer realPayAmount = 0; // 优惠后的实际支付价格累计
for (String itemSpecId : itemSpecIdArr) {
// TODO 整合redis后,商品购买的数量重新从redis的购物车中获取
int buyCounts = 1;
// 2.1 根据规格id,查询规格的具体信息,主要获取价格
ItemsSpec itemSpec = itemService.queryItemSpecById(itemSpecId);
totalAmount += itemSpec.getPriceNormal() * buyCounts;
realPayAmount += itemSpec.getPriceDiscount() * buyCounts;
// 2.2 根据商品id,获得商品信息以及商品图片
String itemId = itemSpec.getItemId();
Items item = itemService.queryItemById(itemId);
String imgUrl = itemService.queryItemMainImgById(itemId);
// 2.3 循环保存子订单数据到数据库
String subOrderId = sid.nextShort();
OrderItems subOrderItem = new OrderItems();
subOrderItem.setId(subOrderId);
subOrderItem.setOrderId(orderId);
subOrderItem.setItemId(itemId);
subOrderItem.setItemName(item.getItemName());
subOrderItem.setItemImg(imgUrl);
subOrderItem.setBuyCounts(buyCounts);
subOrderItem.setItemSpecId(itemSpecId);
subOrderItem.setItemSpecName(itemSpec.getName());
subOrderItem.setPrice(itemSpec.getPriceDiscount());
orderItemsMapper.insert(subOrderItem);
// 2.4 在用户提交订单以后,规格表中需要扣除库存
itemService.decreaseItemSpecStock(itemSpecId, buyCounts);
}
newOrder.setTotalAmount(totalAmount);
newOrder.setRealPayAmount(realPayAmount);
ordersMapper.insert(newOrder);
// 3. 保存订单状态表
OrderStatus waitPayOrderStatus = new OrderStatus();
waitPayOrderStatus.setOrderId(orderId);
waitPayOrderStatus.setOrderStatus(OrderStatusEnum.WAIT_PAY.type);
waitPayOrderStatus.setCreatedTime(new Date());
orderStatusMapper.insert(waitPayOrderStatus);
// 4. 构建商户订单,用于传给支付中心
MerchantOrdersVO merchantOrdersVO = new MerchantOrdersVO();
merchantOrdersVO.setMerchantOrderId(orderId);
merchantOrdersVO.setMerchantUserId(userId);
merchantOrdersVO.setAmount(realPayAmount + postAmount);
merchantOrdersVO.setPayMethod(payMethod);
// 5. 构建自定义订单vo
OrderVO orderVO = new OrderVO();
orderVO.setOrderId(orderId);
orderVO.setMerchantOrdersVO(merchantOrdersVO);
return orderVO;
}
}
步骤3:创建订单使用的的操作方法
3.1接口ItemService中:
/**
* 根据商品规格id获取规格对象的具体信息
* @param specId
* @return
*/
public ItemsSpec queryItemSpecById(String specId);
/**
* 根据商品id获得商品图片主图url
* @param itemId
* @return
*/
public String queryItemMainImgById(String itemId);
/**
* 减少库存
* @param specId
* @param buyCounts
*/
public void decreaseItemSpecStock(String specId, int buyCounts);
3.2接口ItemService实现类
@Transactional(propagation = Propagation.SUPPORTS)
@Override
public ItemsSpec queryItemSpecById(String specId) {
return itemsSpecMapper.selectByPrimaryKey(specId);
}
@Transactional(propagation = Propagation.SUPPORTS)
@Override
public String queryItemMainImgById(String itemId) {
ItemsImg itemsImg = new ItemsImg();
itemsImg.setItemId(itemId);
itemsImg.setIsMain(YesOrNo.YES.type);
ItemsImg result = itemsImgMapper.selectOne(itemsImg);
return result != null ? result.getUrl() : "";
}
@Transactional(propagation = Propagation.REQUIRED)
@Override
public void decreaseItemSpecStock(String specId, int buyCounts) {
int result = itemsMapperCustom.decreaseItemSpecStock(specId, buyCounts);
if (result != 1) {
throw new RuntimeException("订单创建失败,原因:库存不足!");
}
}
3.3 mapper接口中ItemsMapperCustom类:
public int decreaseItemSpecStock(@Param("specId") String specId, @Param("pendingCounts") int pendingCounts);
<update id="decreaseItemSpecStock">
update
items_spec
set
stock = stock - #{pendingCounts}
where
id = #{specId}
and
stock >= #{pendingCounts}
</update>
步骤4:创建对应的bo类和枚举
public enum PayMethod {
WEIXIN(1, "微信"),
ALIPAY(2, "支付宝");
public final Integer type;
public final String value;
PayMethod(Integer type, String value){
this.type = type;
this.value = value;
}
}
public enum OrderStatusEnum {
WAIT_PAY(10, "待付款"),
WAIT_DELIVER(20, "已付款,待发货"),
WAIT_RECEIVE(30, "已发货,待收货"),
SUCCESS(40, "交易成功"),
CLOSE(50, "交易关闭");
public final Integer type;
public final String value;
OrderStatusEnum(Integer type, String value){
this.type = type;
this.value = value;
}
}
public class SubmitOrderBO {
private String userId;
private String itemSpecIds;
private String addressId;
private Integer payMethod;
private String leftMsg;
}
步骤5:创建controller类
package com.one.controller.order;
import com.one.bo.SubmitOrderBO;
import com.one.controller.BaseController;
import com.one.enums.PayMethod;
import com.one.service.order.OrderService;
import com.one.utils.JSONResult;
import com.one.vo.OrderVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Api(value = "订单相关", tags = {"订单相关的api接口"})
@RequestMapping("orders")
@RestController
public class OrdersController extends BaseController {
final static Logger logger = LoggerFactory.getLogger(OrdersController.class);
@Autowired
private OrderService orderService;
@ApiOperation(value = "用户下单", notes = "用户下单", httpMethod = "POST")
@PostMapping("/create")
public JSONResult create(@RequestBody SubmitOrderBO submitOrderBO, HttpServletRequest request, HttpServletResponse response) {
if (submitOrderBO.getPayMethod() != PayMethod.WEIXIN.type && submitOrderBO.getPayMethod() != PayMethod.ALIPAY.type ) {
return JSONResult.errorMsg("支付方式不支持!");
}
// 1. 创建订单
OrderVO orderVO = orderService.createOrder(submitOrderBO);
String orderId = orderVO.getOrderId();
// 2. 创建订单以后,移除购物车中已结算(已提交)的商品
// 3. 向支付中心发送当前订单,用于保存支付中心的订单数据
return JSONResult.ok(orderId);
}
}