秒杀_商品模块

本文介绍了秒杀项目的数据库设计,包括商品表、秒杀商品表、秒杀订单表、订单详情表和秒杀用户表的创建。在商品列表部分,通过创建GoodsService和GoodsDao,实现数据库查询并封装GoodsVo对象,将商品和秒杀信息合并展示,以满足前端goodlist的需求。
摘要由CSDN通过智能技术生成

一、数据库及表设计

秒杀项目主要流程:用户浏览商品列表,然后选中了一个商品,进入商品的详情,在详情中点击商品秒杀按钮,假如秒杀成功,进入订单详情页。
在这里插入图片描述

1.create商品表goods:

create table goods
 (
 id BIGINT(20) primary key not null auto_increment,
 goods_name varchar(16) DEFAULT NULL,
 goods_title varchar(64) DEFAULT NULL,
 goods_img varchar(64) DEFAULT NULL,
 goods_detail LONGTEXT,
 goods_price DECIMAL(10,2) DEFAULT '0.00',
 goods_stock INT(11) DEFAULT '0' 
 );

2.create秒杀商品表:

(商品的id,秒杀的价格、库存(这个是可以秒杀的库存)、秒杀的开始时间和结束时间)

create table miaosha_goods
 (
 id BIGINT(20) primary key not null auto_increment,
 goods_id BIGINT(20)  DEFAULT NULL,
 miaosha_price DECIMAL(10,2) DEFAULT '0.00',
 stock_count INT(11) DEFAULT NULL,
 start_date datetime DEFAULT NULL,
 end_date datetime DEFAULT NULL
 );

3.秒杀订单表:

create table miaosha_order
 (
 id BIGINT(20) primary key not null auto_increment,
 user_id BIGINT(20)  DEFAULT NULL,
 order_id BIGINT(20)  DEFAULT NULL,
 goods_id BIGINT(20)  DEFAULT NULL 
 );

4.订单详情表:

create table order_info
 (
 id BIGINT(20) primary key not null auto_increment,
 user_id BIGINT(20)  DEFAULT NULL,
 goods_id BIGINT(20)  DEFAULT NULL,
 /*收获地址*/
 delivery_addr_id BIGINT(20)  DEFAULT NULL,
 goods_name varchar(16) DEFAULT NULL,
 goods_count INT(11)  DEFAULT '0',
 goods_price decimal(10,2) DEFAULT '0.00',
 order_channel TINYINT(4) DEFAULT '0',
 order_status TINYINT(4) DEFAULT '0',
 create_date datetime DEFAULT NULL,
 pay_date datetime DEFAULT NULL 
 );

5.秒杀用户表:

create table miaosha_user
 (
 id BIGINT(20) primary key not null auto_increment,
 nickname VARCHAR(255) NOT NULL,
 pwd VARCHAR(32) DEFAULT NULL,
 salt VARCHAR(10) DEFAULT NULL,
 head VARCHAR(128) DEFAULT NULL,
 register_date DATETIME DEFAULT NULL,
 last_login_time DATETIME DEFAULT NULL,
 login_count INT(11) DEFAULT 0
 );

二、商品列表

1.先创建商品的服务类GoodsService ,注入GoodsDao:

@Service
 public class GoodsService {
 public static final String COOKIE1_NAME_TOKEN="token"; 
 @Autowired
 GoodsDao goodsDao;
 @Autowired
 RedisService redisService;
 //获取商品信息列表  
 public List<GoodsVo>  getGoodsVoList() {
  return goodsDao.getGoodsVoList();
 } 
 //获取商品根据商品Id
 public GoodsVo getGoodsVoByGoodsId(long goodsId) {
  return goodsDao.getGoodsVoByGoodsId(goodsId);
 }
 //减少商品的库存
 public void reduceStock(GoodsVo goodsvo) {
  MiaoshaGoods goods=new MiaoshaGoods();
  goods.setGoodsId(goodsvo.getId());
  //goods.setStockCount(goodsvo.getGoodsStock()-1);  sql里面去运算
  //goodsDao.reduceStock(goods.getGoodsId());
  goodsDao.reduceStock(goods);
 } 
}

2.创建GoodsDao:
注意:这里我们查数据库的时候,不只是查找的商品的信息,我们同时想把商品的秒杀信息也一起查出来,但是这两个不同数据在两个表里面,我们就想办法封装一个GoodsVo,将两张表的数据封装到一起。
下面是GoodsVo对象,因为继承Goods,拥有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;

然后再自己定义MiaoshaGoods里面的字段,最终拼接成一个GoodsVo对象。

public class GoodsVo extends Goods{
 private Double miaoshaPrice;
 private Integer stockCount;
 private Date startDate;
 private Date endDate;
 public Integer getStockCount() {
  return stockCount;
 }
 public void setStockCount(Integer stockCount) {
  this.stockCount = stockCount;
 }
 public Date getStartDate() {
  return startDate;
 }
 public void setStartDate(Date startDate) {
  this.startDate = startDate;
 }
 public Date getEndDate() {
  return endDate;
 }
 public void setEndDate(Date endDate) {
  this.endDate = endDate;
 }
 public Double getMiaoshaPrice() {
  return miaoshaPrice;
 }
 public void setMiaoshaPrice(Double miaoshaPrice) {
  this.miaoshaPrice = miaoshaPrice;
 }
}

这里是将两个表做连接查询(miaosha_goods mg left join goods g),我们需要查找的数据库表里面的各个字段对应到我们GoodsVo里面的属性,那么就可以给其赋值。

@Mapper
public interface GoodsDao {		
@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(); 	
@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);    //stock_count>0的时候才去更新,数据库本身会有锁,那么就不会在数据库中同时多个线程更新一条记录,使用数据库特性来保证超卖的问题	

@Update("update miaosha_goods set stock_count = stock_count - 1 where goods_id = #{goodsId}")	public int reduceStock(MiaoshaGoods g);	}

前端goodlist:

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>商品详情</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <!-- jquery -->
    <script type="text/javascript" th:src="@{/js/jquery.min.js}"></script>
    <!-- bootstrap -->
    <link rel="stylesheet" type="text/css" th:href="@{/bootstrap/css/bootstrap.min.css}" />
    <script type="text/javascript" th:src="@{/bootstrap/js/bootstrap.min.js}"></script>
    <!-- jquery-validator -->
    <script type="text/javascript" th:src="@{/jquery-validation/jquery.validate.min.js}"></script>
    <script type="text/javascript" th:src="@{/jquery-validation/localization/messages_zh.min.js}"></script>
    <!-- layer -->
    <script type="text/javascript" th:src="@{/layer/layer.js}"></script>
    <!-- md5.js -->
    <script type="text/javascript" th:src="@{/js/md5.min.js}"></script>
    <!-- common.js -->
    <script type="text/javascript" th:src="@{/js/common.js}"></script>
</head>
<body>
<div class="panel panel-default">

    <div class="panel-heading">秒杀商品详情</div>

    <div class="panel-body">

        <span th:if="${user eq null}"> 您还没有登录,请登陆后再操作<br/></span>
        <span>请填写收货地址。</span>
    </div>
    <table class="table" id="goodslist">
        <tr>
            <td>商品名称</td>
            <td colspan="3" th:text="${goods.goodsName}"></td>
        </tr>
        <tr>
            <td>商品图片</td>
            <td colspan="3"><img th:src="@{${goods.goodsImg}}" width="200" height="200" /></td>
        </tr>
        <tr>
            <td>秒杀开始时间</td>
            <td th:text="${#dates.format(goods.startDate, 'yyyy-MM-dd HH:mm:ss')}"></td>
            <td id="miaoshaTip">
                <input type="hidden" id="remainSeconds" th:value="${remainSeconds}" />
                <span th:if="${miaoshaStatus eq 0}">秒杀倒计时:<span id="countDown" th:text="${remainSeconds}"></span></span>
                <span th:if="${miaoshaStatus eq 1}">秒杀进行中</span>
                <span th:if="${miaoshaStatus eq 2}">秒杀已结束</span>
            </td>
            <td>

                <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>
            </td>
        </tr>
        <tr>
            <td>商品原价</td>
            <td colspan="3" th:text="${goods.goodsPrice}"></td>
        </tr>
        <tr>
            <td>秒杀价</td>
            <td colspan="3" th:text="${goods.miaoshaPrice}"></td>
        </tr>
        <tr>
            <td>库存数量</td>
            <td colspan="3" th:text="${goods.stockCount}"></td>
        </tr>
    </table>
</div>
</body>
<script>
    $(function(){
        countDown();
    });

    function countDown(){

        var remainSeconds = $("#remainSeconds").val();

        var timeout;

        if(remainSeconds > 0){//秒杀还没开始,倒计时

            $("#buyButton").attr("disabled", true);

            timeout = setTimeout(function(){

                $("#countDown").text(remainSeconds - 1);

                $("#remainSeconds").val(remainSeconds - 1);

                countDown();

            },1000);

        }else if(remainSeconds == 0){//秒杀进行中

            $("#buyButton").attr("disabled", false);

            if(timeout){

                clearTimeout(timeout);

            }

            $("#miaoshaTip").html("秒杀进行中");

        }else{//秒杀已经结束

            $("#buyButton").attr("disabled", true);

            $("#miaoshaTip").html("秒杀已经结束");
        }
    }
</script>
</html>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值