秒杀项目学习第三章

主要内容

  1. 数据库设计
  2. 商品列表页
  3. 商品详情页
  4. 订单详情页

一、数据库设计

商品表goods

在这里插入图片描述

商品订单表order_info

在这里插入图片描述

秒杀商品表miaosha_goods

在这里插入图片描述

秒杀商品订单表miaosha_order

在这里插入图片描述

domain对象

1.Goods

public class Goods {
	private Long id;
	private String goodsName;
	private String goodsTitle;
	private String goodsImg;
	private String goodsDetail;
	private Double goodsPrice;
	private Integer goodsStock;

2.OrderInfo

public class OrderInfo {
	private Long id;
	private Long userId;
	private Long goodsId;
	private Long  deliveryAddrId;
	private String goodsName;
	private Integer goodsCount;
	private Double goodsPrice;
	private Integer orderChannel;
	private Integer status;
	private Date createDate;
	private Date payDate;

3.MiaoshaGoods

public class MiaoshaGoods {
	private Long id;
	private Long goodsId;
	private Integer stockCount;
	private Date startDate;
	private Date endDate;

4.MiaoshaOrder

public class MiaoshaOrder {
	private Long id;
	private Long userId;
	private Long  orderId;
	private Long goodsId;

二、商品列表页

数据层

GoodsDao

@Repository
public interface GoodsDao {
	//查询所有秒杀商品的信息并封装进GoodsVo
	@Select("select g.*,mg.stock_count, mg.start_date, mg.end_date,mg.miaosha_price from miaosha_goods mg left join goods g on mg.goods_id = g.id")
	public List<GoodsVo> listGoodsVo();
}

为了展示秒杀商品的详情需要goods和miaosha_goods中的信息,所以封装一个GoodsVo

public class GoodsVo extends Goods {
	private Double miaoshaPrice;
	private Integer stockCount;
	private Date startDate;
	private Date endDate;

业务层

GoodsService

@Service
public class GoodsService {
	
	@Autowired
	GoodsDao goodsDao;
	
	public List<GoodsVo> listGoodsVo(){
		return goodsDao.listGoodsVo();
	}
}

表现层

GoodsController

@Controller
@RequestMapping("/goods")
public class GoodsController {
	@Autowired
	GoodsService goodsService;
    @RequestMapping("/to_list")
    public String list(Model model, MiaoshaUser user) {
    	model.addAttribute("user", user);
    	//查询商品列表
    	List<GoodsVo> goodsList = goodsService.listGoodsVo();
    	model.addAttribute("goodsList", goodsList);
        return "goods_list";
    }
}

goods_list页面
在这里插入图片描述

三、商品详情页

查数据库时间的时候有个bug读取的时间总比数据库中的时间多一天
解决方法:serverTimezone设置时区

spring.datasource.url=jdbc:mysql://192.168.174.10:3306/miaosha?
useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&
useSSL=false&serverTimezone=Asia/Shanghai

数据层

GoodsDao 增加方法

@Repository
public interface GoodsDao {
	。。。忽略以前代码
	//根据商品id查商品信息
	@Select("select g.*,mg.stock_count, mg.start_date, mg.end_date,mg.miaosha_price from miaosha_goods mg left join goods g on mg.goods_id = g.id where g.id = #{goodsId}")
	public GoodsVo getGoodsVoByGoodsId(@Param("goodsId") long goodsId);
}

业务层

GoodsService

@Service
public class GoodsService {
	。。。忽略以前代码
	public GoodsVo getGoodsVoByGoodsId(long goodsId) {
		return goodsDao.getGoodsVoByGoodsId(goodsId);
	}
}

表现层

GoodsController

@Controller
@RequestMapping("/goods")
public class GoodsController {
	。。。忽略以前代码
	@Autowired
	MiaoshaUserService userService;
    @RequestMapping("/to_detail/{goodsId}")
    public String detail(Model model,MiaoshaUser user,
    		@PathVariable("goodsId")long goodsId) {
    	model.addAttribute("user", user);
    	
    	GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);
		System.out.println(goods.getStartDate());
    	model.addAttribute("goods", goods);
    	
    	long startAt = goods.getStartDate().getTime();
    	long endAt = goods.getEndDate().getTime();
    	long now = System.currentTimeMillis();
    	
    	int miaoshaStatus = 0;
    	int remainSeconds = 0;
    	//这个用来设置距离秒杀结束多长时间
    	int endSeconds = 0;
    	if(now < startAt ) {//秒杀还没开始,倒计时
    		miaoshaStatus = 0;
    		remainSeconds = (int)((startAt - now )/1000);
    		endSeconds = (int)((endAt - now )/1000);
    	}else  if(now > endAt){//秒杀已经结束
    		miaoshaStatus = 2;
    		remainSeconds = -1;
    	}else {//秒杀进行中
    		miaoshaStatus = 1;
    		remainSeconds = 0;
			endSeconds = (int)((endAt - now )/1000);
    	}
    	model.addAttribute("miaoshaStatus", miaoshaStatus);
    	model.addAttribute("remainSeconds", remainSeconds);
    	model.addAttribute("endSeconds", endSeconds);

        return "goods_detail";
    }
}

goods_detail页面
在这里插入图片描述倒计时处理

<script>
    /*这是jQuery的写法
    * 原本为:
    *
    *    $(document).ready(function(){
            // 开始写 jQuery 代码...
         });
         * 页面加载完之后才会执行
    * */
    $(function(){
        countDown();
    });
    function countDown(){
        var remainSeconds = $("#remainSeconds").val();
        var endSeconds = $("#endSeconds").val();
        var timeout;
        var endtimeout;
        if(remainSeconds > 0){//秒杀还没开始,倒计时
            $("#buyButton").attr("disabled", true);
            timeout = setTimeout(function(){
                $("#countDown").text(remainSeconds - 1);
                $("#remainSeconds").val(remainSeconds - 1);
                $("#endSeconds").val(endSeconds - 1);
                countDown();
            },1000);
        }else if(remainSeconds == 0){//秒杀进行中
            $("#buyButton").attr("disabled", false);
            if(timeout){
                clearTimeout(timeout);
            }
            if(endSeconds>0){
                $("#miaoshaTip").html("秒杀进行中");
            }else{
                $("#remainSeconds").val(remainSeconds - 1);
            }
            endtimeout = setTimeout(function(){
                $("#endSeconds").val(endSeconds - 1);
                countDown();
            },1000);
        }else{//秒杀已经结束
            if(endtimeout){
                clearTimeout(endtimeout);
            }
            $("#buyButton").attr("disabled", true);
            $("#miaoshaTip").html("秒杀已经结束");
        }
    }

</script>

四、订单详情页

数据层

GoodsDao

@Repository
public interface GoodsDao {
	。。。忽略以前代码
	@Update("update miaosha_goods set stock_count = stock_count - 1 where goods_id = #{goodsId}")
	public int reduceStock(MiaoshaGoods g);
}

OrderDao

@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);

	@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()")
	//@Options(useGeneratedKeys = true,keyProperty = "id")
	//@SelectKey和/@Options注解作用一样都是把插入的id好回写进OrderInfo中
	public long insert(OrderInfo orderInfo);
	
	@Insert("insert into miaosha_order (user_id, goods_id, order_id)values(#{userId}, #{goodsId}, #{orderId})")
	public int insertMiaoshaOrder(MiaoshaOrder miaoshaOrder);
}

业务层

GoodsService

@Service
public class GoodsService {
	。。。省略以前代码
	@Autowired
	GoodsDao goodsDao;

	public void reduceStock(GoodsVo goods) {
		MiaoshaGoods g = new MiaoshaGoods();
		g.setGoodsId(goods.getId());
		goodsDao.reduceStock(g);
	}
}

MiaoshaService

@Service
public class MiaoshaService {
	@Autowired
	GoodsService goodsService;
	@Autowired
	OrderService orderService;
	@Transactional
	public OrderInfo miaosha(MiaoshaUser user, GoodsVo goods) {
		//减库存 下订单 写入秒杀订单
		goodsService.reduceStock(goods); //代码见上
		//下订单 order_info maiosha_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);
	}
	@Transactional
	public OrderInfo createOrder(MiaoshaUser user, GoodsVo goods) {
		//插入订单
		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());
		long orderId = orderDao.insert(orderInfo);
		//插入秒杀订单
		MiaoshaOrder miaoshaOrder = new MiaoshaOrder();
		miaoshaOrder.setGoodsId(goods.getId());
		miaoshaOrder.setOrderId(orderId);
		miaoshaOrder.setUserId(user.getId());
		orderDao.insertMiaoshaOrder(miaoshaOrder);
		return orderInfo;
	}
}

表现层

MiaoshaController

@Controller
@RequestMapping("/miaosha")
public class MiaoshaController {
	@Autowired
	MiaoshaUserService userService;
	
	@Autowired
	RedisService redisService;
	
	@Autowired
	GoodsService goodsService;
	
	@Autowired
	OrderService orderService;
	
	@Autowired
	MiaoshaService miaoshaService;
	
    @RequestMapping(path = "/do_miaosha",method = RequestMethod.POST)
    public String list(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.MIAO_SHA_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";
    }
}

为了跳转到订单页面处理下goods_detail页面
在这里插入图片描述

order_detail页面
在这里插入图片描述
miaosha_fail页面
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值