商品详情页中点击秒杀后,提交表单到url: /miaosha/do_miaosha
<form id="miaoshaForm" method="post" action="/miaosha/do_miaosha">
<button class="btn btn-primary btn-block" type="submit"
id="buyButton">立即秒杀</button>
<input type="hidden" name="goodsId" th:value="${goods.id}"/>
</form>
MiaoshaController
秒杀业务逻辑为:
- 判断是否登录 ->没有,去登录
- 判断是否有库存 ->没有,秒杀失败
- 判断是否重复秒杀 -> 重复秒杀,秒杀失败
- 秒杀商品(减库存 、下订单、 写入秒杀订单),跳转到订单详情页
@RequestMapping("/do_miaosha")
public String toList(Model model, MiaoshaUser user,
@RequestParam("goodsId") long goodsId) {
model.addAttribute("user", user);
if (user == null) {
return "login";
}
//判断库存
GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);
int stock = goods.getStockCount();
if (stock <= 0) {
model.addAttribute("errmsg", CodeMsg.MIAOSHA_OVER.getMsg());
return "miaosha_fail";
}
//判断是否已经秒杀到了,不能重复秒杀
MiaoshaOrder order = orderService.getMiaoshaOrderByUserIdGoodsId(user.getId(), goodsId);
if (order != null) {
model.addAttribute("errmsg", CodeMsg.REPEATE_MIAOSHA.getMsg());
return "miaosha_fail";
}
//减库存 下订单 写入秒杀订单 秒杀成功后进入订单详情页
OrderInfo orderInfo = miaoshaService.miaosha(user, goods);
model.addAttribute("orderInfo", orderInfo);
model.addAttribute("goods", goods);
return "order_detail";
}
MiaoshaService
秒杀商品操作(减库存 、下订单、 写入秒杀订单)要作为一个事务执行,保证数据的一致性,这里要在详细订单表和秒杀订单表同时生成对应订单。为了确保秒杀操作中一个用户只能秒杀一件商品,我们给秒杀订单表miaosha_order表添加了(user_id,goods_id)的唯一索引,如果再次插入同一用户同一商品的订单,那么将不会被允许,事务插入失败后回滚。
@Service
public class MiaoshaService {
@Autowired
GoodsService goodsService;
@Autowired
OrderService orderService;
@Transactional
public OrderInfo miaosha(MiaoshaUser user, GoodsVo goods){
//减库存 下订单 写入秒杀订单 返回订单详情
goodsService.reduceStock(goods);
//orderinfo和miaosha_order
return orderService.createOrder(user, goods);
}
}
OrderService
@Service
public class OrderService {
@Autowired
OrderDao orderDao;
public MiaoshaOrder getMiaoshaOrderByUserIdGoodsId(long userId, long goodsId) {
return orderDao.getMiaoshaOrderByUserIdGoodsId(userId,goodsId);
}
//orderinfo和miaosha_order
@Transactional
public OrderInfo createOrder(MiaoshaUser user, GoodsVo goods) {
//orderinfo
OrderInfo orderInfo = new OrderInfo();
orderInfo.setCreateDate(new Date());
orderInfo.setDeliveryAddrId(0L);
orderInfo.setGoodsCount(1);
orderInfo.setGoodsId(goods.getId());
orderInfo.setGoodsName(goods.getGoodsName());
orderInfo.setGoodsPrice(goods.getMiaoshaPrice());
orderInfo.setOrderChannel(1);
orderInfo.setStatus(0); //最好用枚举
orderInfo.setUserId(user.getId());
orderDao.insert(orderInfo);
//miaosha_order
MiaoshaOrder miaoshaOrder = new MiaoshaOrder();
miaoshaOrder.setGoodsId(goods.getId());
miaoshaOrder.setUserId(user.getId());
miaoshaOrder.setOrderId(orderInfo.getId());
orderDao.insertMiaoshaOrder(miaoshaOrder);
return orderInfo;
}
}
OrderDao
@Mapper
@Repository
public interface OrderDao {
@Select("select * from miaosha_order where user_id = #{userId} and goods_id = #{goodsId}")
public MiaoshaOrder getMiaoshaOrderByUserIdGoodsId(@Param("userId") long userId, @Param("goodsId") long goodsId);
@Select("select * from order_info where id=#{orderId}")
public OrderInfo getOrderById(@Param("orderId") long orderId);
//返回自增主键用SelectKey keyColumn:数据库列名 keyProperty:domain对象属性 before:是否在之前执行
@Insert("insert into order_info(user_id,goods_id,goods_name,goods_count,goods_price,order_channel,status,create_date)values(" +
"#{userId},#{goodsId},#{goodsName},#{goodsCount},#{goodsPrice},#{orderChannel},#{status},#{createDate})")
@SelectKey(keyColumn = "id", keyProperty = "id", resultType = long.class, before = false, statement = "select last_insert_id()")
public long insert(OrderInfo orderInfo);
@Insert("insert into miaosha_order(user_id,order_id,goods_id)values(#{userId},#{orderId},#{goodsId})")
public void insertMiaoshaOrder(MiaoshaOrder miaoshaOrder);
@Delete("delete from miaosha_order")
void deleteMiaoshaOrders();
@Delete("delete from order_info")
void deleteOrders();
}
————————————————
版权声明:本文为CSDN博主「lahhass」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/baidu_25104885/article/details/93420518