Step 1:
Create orders order table, sub-order table and order status table corresponding pojo and mappper Orders and OrderItemsMapper OrderItems and OrderItemsMapper OrderStatus and OrderStatusMapper
Step 2: Create OrderService and corresponding implementation class
public interface OrderService {<!-- --> /** * Used to create order related information * @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(); // Set the free shipping fee to 0 Integer postAmount = 0; String orderId = sid.nextShort(); UserAddress address = addressService.queryUserAddres(userId, addressId); // 1. Save new order data 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. Loop to save the order product information table based on itemSpecIds String itemSpecIdArr[] = itemSpecIds.split(","); Integer totalAmount = 0; // Accumulated original price of the product Integer realPayAmount = 0; // Accumulated actual payment price after discount for (String itemSpecId : itemSpecIdArr) {<!-- --> // TODO After integrating redis, the quantity of product purchased will be obtained from the redis shopping cart again. int buyCounts = 1; // 2.1 According to the specification id, query the specific information of the specification, mainly to obtain the price ItemsSpec itemSpec = itemService.queryItemSpecById(itemSpecId); totalAmount + = itemSpec.getPriceNormal() * buyCounts; realPayAmount + = itemSpec.getPriceDiscount() * buyCounts; // 2.2 Obtain product information and product pictures based on the product ID String itemId = itemSpec.getItemId(); Items item = itemService.queryItemById(itemId); String imgUrl = itemService.queryItemMainImgById(itemId); // 2.3 Loop to save sub-order data to the database 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 After the user submits the order, the inventory needs to be deducted from the specification table itemService.decreaseItemSpecStock(itemSpecId, buyCounts); } newOrder.setTotalAmount(totalAmount); newOrder.setRealPayAmount(realPayAmount); ordersMapper.insert(newOrder); // 3. Save the order status table OrderStatus waitPayOrderStatus = new OrderStatus(); waitPayOrderStatus.setOrderId(orderId); waitPayOrderStatus.setOrderStatus(OrderStatusEnum.WAIT_PAY.type); waitPayOrderStatus.setCreatedTime(new Date()); orderStatusMapper.insert(waitPayOrderStatus); // 4. Construct merchant orders for transmission to the payment center MerchantOrdersVO merchantOrdersVO = new MerchantOrdersVO(); merchantOrdersVO.setMerchantOrderId(orderId); merchantOrdersVO.setMerchantUserId(userId); merchantOrdersVO.setAmount(realPayAmount + postAmount); merchantOrdersVO.setPayMethod(payMethod); // 5. Build custom order vo OrderVO orderVO = new OrderVO(); orderVO.setOrderId(orderId); orderVO.setMerchantOrdersVO(merchantOrdersVO); return orderVO; } }
Step 3: How to create an order
3.1 Interface ItemService:
/** * Obtain the specific information of the specification object based on the product specification id * @param specId * @return */ public ItemsSpec queryItemSpecById(String specId); /** * Obtain the product image main image url based on the product ID * @param itemId * @return */ public String queryItemMainImgById(String itemId); /** * decrease stock * @param specId * @param buyCounts */ public void decreaseItemSpecStock(String specId, int buyCounts);
3.2 Interface ItemService implementation class
@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("Order creation failed, reason: Insufficient inventory!"); } }
3.3 ItemsMapperCustom class in mapper interface:
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>
Step 4: Create the corresponding bo class and enumeration
public enum PayMethod {<!-- --> WEIXIN(1, "WeChat"), ALIPAY(2, "Alipay"); 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, "Pending payment"), WAIT_DELIVER(20, "Paid, waiting for shipment"), WAIT_RECEIVE(30, "Delivered, waiting to be received"), SUCCESS(40, "Transaction successful"), CLOSE(50, "Transaction Closed"); 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; }
Step 5: Create controller class
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 = "Order-related", tags = {<!-- -->"Order-related api interface"}) @RequestMapping("orders") @RestController public class OrdersController extends BaseController {<!-- --> final static Logger logger = LoggerFactory.getLogger(OrdersController.class); @Autowired private OrderService orderService; @ApiOperation(value = "User Places Order", notes = "User Places Order", httpMethod = "POST") @PostMapping("/create") public JSONResult create(@RequestBody SubmitOrderBO submitOrderBO, HttpServletRequest request, HttpServletResponse response) {<!-- --> if (submitOrderBO.getPayMethod() != PayMethod.WEIXIN.type & amp; & amp; submitOrderBO.getPayMethod() != PayMethod.ALIPAY.type ) {<!-- --> return JSONResult.errorMsg("Payment method not supported!"); } // 1. Create an order OrderVO orderVO = orderService.createOrder(submitOrderBO); String orderId = orderVO.getOrderId(); // 2. After creating the order, remove the settled (submitted) items in the shopping cart // 3. Send the current order to the payment center to save the order data of the payment center return JSONResult.ok(orderId); } }