一、流程分析(基础版本):
![](https://i-blog.csdnimg.cn/blog_migrate/57b8c455a9eecac69bc2d89653e2676e.png)
二、数据库实现
1.数据库操作:
- 根据收货地址ID,获取收货地址信息(tkMapper)
- 根据购物车ID,查询购物车详情(需要关联查询商品名称、sku名称、库存、商品图片、商品价格)——>获取生成商品快照的参数
- 保存订单(tkMapper)
- 修改库存(tkMapper)
- 保存商品快照(tkMapper)
(1)库存
改造shoopingCart:
ShoppingCartVO:
private int skuStock;//库存
<resultMap id="ShoppingCartVOMap2" type="com.qfedu.fmmall.entity.ShoppingCartVO">
<!--
WARNING - @mbg.generated
-->
<id column="cart_id" jdbcType="INTEGER" property="cartId" />
<result column="product_id" jdbcType="VARCHAR" property="productId" />
<result column="sku_id" jdbcType="VARCHAR" property="skuId" />
<result column="user_id" jdbcType="VARCHAR" property="userId" />
<result column="cart_num" jdbcType="VARCHAR" property="cartNum" />
<result column="cart_time" jdbcType="VARCHAR" property="cartTime" />
<result column="product_price" jdbcType="DECIMAL" property="productPrice" />
<result column="sku_props" jdbcType="VARCHAR" property="skuProps" />
<result column="product_name" jdbcType="VARCHAR" property="productName" />
<result column="url" jdbcType="VARCHAR" property="productImg" />
<result column="original_price" jdbcType="VARCHAR" property="originalPrice" />
<result column="sell_price" jdbcType="VARCHAR" property="sellPrice" />
<result column="sku_name" jdbcType="VARCHAR" property="skuName" />
<result column="stock" property="skuStock" />
</resultMap>
<select id="selectShopcartByCids" resultMap="ShoppingCartVOMap2">
SELECT c.cart_id,
c.product_id,
c.sku_id,
c.user_id,
c.cart_num,
c.cart_time,
c.product_price,
c.sku_props,
p.product_name,
i.url,
s.original_price,
s.sell_price,
s.sku_name,
s.stock
FROM shopping_cart c
INNER JOIN product p
INNER JOIN product_img i
INNER JOIN product_sku s
ON c.product_id=p.product_id
AND i.item_id=p.product_id
AND c.sku_id=s.sku_id
WHERE i.is_main=1 and c.cart_id IN
<foreach collection="cids" item="cid" separator="," open="(" close=")">
#{cid}
</foreach>
</select>
OrderService:
public interface OrderService {
public ResultVO addOrder();
}
OrderServiceImpl:
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private ShoppingCartMapper shoppingCartMapper;
@Autowired
private OrdersMapper ordersMapper;
@Autowired
private OrderItemMapper orderItemMapper;
public ResultVO addOrder(String cids,Orders order) {
//1.根据cids查询当前订单中关联的购物车记录详情(包括库存)
String[] arr = cids.split(",");
List<Integer> cidsList = new ArrayList<>();
for (int i=0; i<arr.length;i++){
cidsList.add(Integer.parseInt(arr[i]));
}
List<ShoppingCartVO> list = shoppingCartMapper.selectShopcartByCids(cidsList);
//2.校验库存
boolean f = true;
String untitled = "";
for (ShoppingCartVO sc:list){
if (Integer.parseInt( sc.getCartNum() )>sc.getSkuStock()){
f=false;
//break;
}
//获取所有商品的名称,以“,”分割拼接成字符串
untitled = untitled + sc.getProductName() + ",";
}
if (f){
//3.表示用户充足----------保存订单
order.setUntitled(untitled);
order.setCreateTime(new Date());
//生成订单编号
String orderId = UUID.randomUUID().toString().replace("-", "");
order.setOrderId(orderId);
//4.保存订单
int i = ordersMapper.insert(order);
if (i>0){
//生成商品快照
List<OrderItem> orderItems = new ArrayList<>();
for (ShoppingCartVO sc:list){
String itemId = System.currentTimeMillis()+""+ (new Random().nextInt(89999)+10000 );
OrderItem orderItem = new OrderItem(itemId, orderId, sc.getProductId(), sc.getProductName(), sc.getProductImg(),
sc.getSkuId(), sc.getSkuName(),new BigDecimal(sc.getSellPrice()) , Integer.parseInt(sc.getCartNum()),
new BigDecimal(sc.getSellPrice() * Integer.parseInt(sc.getCartNum())) , new Date(), new Date(), 0);
orderItems.add(orderItem);
}
int j = orderItemMapper.insertList(orderItems);
//扣减库存
}
}else {
//表示库存不足
return new ResultVO(ResStatus.NO,"库存不足,下单失败!",null);
}
return null;
}
}
(2)保存订单
OrderServiceImpl:
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private ShoppingCartMapper shoppingCartMapper;
@Autowired
private OrdersMapper ordersMapper;
@Autowired
private OrderItemMapper orderItemMapper;
@Autowired
private ProductSkuMapper productSkuMapper;
public ResultVO addOrder(String cids,Orders order) {
//1.根据cids查询当前订单中关联的购物车记录详情(包括库存)
String[] arr = cids.split(",");
List<Integer> cidsList = new ArrayList<>();
for (int i=0; i<arr.length;i++){
cidsList.add(Integer.parseInt(arr[i]));
}
List<ShoppingCartVO> list = shoppingCartMapper.selectShopcartByCids(cidsList);
//2.校验库存
boolean f = true;
String untitled = "";
for (ShoppingCartVO sc:list){
if (Integer.parseInt( sc.getCartNum() )>sc.getSkuStock()){
f=false;
//break;
}
//获取所有商品的名称,以“,”分割拼接成字符串
untitled = untitled + sc.getProductName() + ",";
}
if (f){
//3.表示用户充足----------保存订单
order.setUntitled(untitled);
order.setCreateTime(new Date());
order.setStatus("1");
//生成订单编号
String orderId = UUID.randomUUID().toString().replace("-", "");
order.setOrderId(orderId);
//4.保存订单
int i = ordersMapper.insert(order);
//if (i>0){
//生成商品快照
//List<OrderItem> orderItems = new ArrayList<>();
for (ShoppingCartVO sc:list){
int cnum = Integer.parseInt(sc.getCartNum());
String itemId = System.currentTimeMillis()+""+ (new Random().nextInt(89999)+10000 );
OrderItem orderItem = new OrderItem(itemId, orderId, sc.getProductId(), sc.getProductName(), sc.getProductImg(),
sc.getSkuId(), sc.getSkuName(),new BigDecimal(sc.getSellPrice()) , cnum,
new BigDecimal(sc.getSellPrice() * cnum) , new Date(), new Date(), 0);
//orderItems.add(orderItem);
int m = orderItemMapper.insert(orderItem);
}
//int j = orderItemMapper.insertList(orderItems);
//5.扣减库存
for (ShoppingCartVO sc:list){
String skuId = sc.getSkuId();
int newStock = sc.getSkuStock() - Integer.parseInt(sc.getCartNum());
// Example example = new Example(ProductSku.class);
// Example.Criteria criteria = example.createCriteria();
// criteria.andEqualTo("skuId",skuId);
// ProductSku productSku = productSkuMapper.selectByPrimaryKey(skuId);
// //ProductSku productSku = new ProductSku();
// productSku.setStock(newStock);
// int k = productSkuMapper.updateByPrimaryKey(productSku);
ProductSku productSku = new ProductSku();
productSku.setSkuId(skuId);
productSku.setStock(newStock);
int k = productSkuMapper.updateByPrimaryKeySelective(productSku);
}
return new ResultVO(ResStatus.OK,"下单成功!",orderId);
}else {
//表示库存不足
return new ResultVO(ResStatus.NO,"库存不足,下单失败!",null);
}
}
}
OrderController:
@RestController
@CrossOrigin
@RequestMapping("/order")
@Api(value = "提供订单相关的操作接口",tags = "订单管理")
public class OrderController {
@Autowired
private OrderService orderService;
@PostMapping("/add")
public ResultVO add(String cids,@RequestBody Orders order){
ResultVO resultVO = orderService.addOrder(cids, order);
return resultVO;
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/442a050bccea445709a14bf32db43eb0.png)
(3)事务管理
OrderServiceImpl:
//保存订单业务
@Transactional //事务
public ResultVO addOrder(String cids,Orders order) {
...
}
(4)删除购物车记录
OrderServiceImpl:
//6.删除购物车:当购物车中的记录购买成功后,购物车对应做删除操作
for (int cid:cidsList){
shoppingCartMapper.deleteByPrimaryKey(cid);
}
OrderServiceImpl抛出sq异常:
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private ShoppingCartMapper shoppingCartMapper;
@Autowired
private OrdersMapper ordersMapper;
@Autowired
private OrderItemMapper orderItemMapper;
@Autowired
private ProductSkuMapper productSkuMapper;
//保存订单业务
@Transactional//事务
public ResultVO addOrder(String cids,Orders order) throws SQLException{
//1.根据cids查询当前订单中关联的购物车记录详情(包括库存)
String[] arr = cids.split(",");
List<Integer> cidsList = new ArrayList<>();
for (int i=0; i<arr.length;i++){
cidsList.add(Integer.parseInt(arr[i]));
}
List<ShoppingCartVO> list = shoppingCartMapper.selectShopcartByCids(cidsList);
//2.校验库存
boolean f = true;
String untitled = "";
for (ShoppingCartVO sc:list){
if (Integer.parseInt( sc.getCartNum() )>sc.getSkuStock()){
f=false;
//break;
}
//获取所有商品的名称,以“,”分割拼接成字符串
untitled = untitled + sc.getProductName() + ",";
}
if (f){
//3.表示用户充足----------保存订单
order.setUntitled(untitled);
order.setCreateTime(new Date());
order.setStatus("1");
//生成订单编号
String orderId = UUID.randomUUID().toString().replace("-", "");
order.setOrderId(orderId);
//4.保存订单
ordersMapper.insert(order);
//if (i>0){
//生成商品快照
//List<OrderItem> orderItems = new ArrayList<>();
for (ShoppingCartVO sc:list){
int cnum = Integer.parseInt(sc.getCartNum());
String itemId = System.currentTimeMillis()+""+ (new Random().nextInt(89999)+10000 );
OrderItem orderItem = new OrderItem(itemId, orderId, sc.getProductId(), sc.getProductName(), sc.getProductImg(),
sc.getSkuId(), sc.getSkuName(),new BigDecimal(sc.getSellPrice()) , cnum,
new BigDecimal(sc.getSellPrice() * cnum) , new Date(), new Date(), 0);
//orderItems.add(orderItem);
orderItemMapper.insert(orderItem);
}
//int j = orderItemMapper.insertList(orderItems);
//5.扣减库存
for (ShoppingCartVO sc:list){
String skuId = sc.getSkuId();
int newStock = sc.getSkuStock() - Integer.parseInt(sc.getCartNum());
// Example example = new Example(ProductSku.class);
// Example.Criteria criteria = example.createCriteria();
// criteria.andEqualTo("skuId",skuId);
// ProductSku productSku = productSkuMapper.selectByPrimaryKey(skuId);
// //ProductSku productSku = new ProductSku();
// productSku.setStock(newStock);
// int k = productSkuMapper.updateByPrimaryKey(productSku);
ProductSku productSku = new ProductSku();
productSku.setSkuId(skuId);
productSku.setStock(newStock);
productSkuMapper.updateByPrimaryKeySelective(productSku);
}
//6.删除购物车:当购物车中的记录购买成功后,购物车对应做删除操作
for (int cid:cidsList){
shoppingCartMapper.deleteByPrimaryKey(cid);
}
return new ResultVO(ResStatus.OK,"下单成功!",orderId);
}else {
//表示库存不足
return new ResultVO(ResStatus.NO,"库存不足,下单失败!",null);
}
}
}
OrderController:
@RestController
@CrossOrigin
@RequestMapping("/order")
@Api(value = "提供订单相关的操作接口",tags = "订单管理")
public class OrderController {
@Autowired
private OrderService orderService;
@PostMapping("/add")
public ResultVO add(String cids,@RequestBody Orders order) {
ResultVO resultVO = null;
try {
resultVO = orderService.addOrder(cids, order);
}catch (SQLException e){
resultVO = new ResultVO(ResStatus.NO,"提交订单失败",null);
}
return resultVO;
}
}