该项目是一个简单的秒杀系统,项目都是跟着学的,相关代码都是自己敲的。
技术介绍:运用springboot, redis, mybits-plus, mybatis,rabbitmq消息队列
相关应用:md5加密,自定义注解使用,全局异常定义,redis分布式锁的运用
介绍:项目经过多次优化和测试,基本可以
项目目录:
运行首页:
登陆后页面:
相关代码:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>商品列表</title>
<script type="text/javascript" th:src="@{/js/jquery-2.2.4.min.js}"></script>
<link rel="stylesheet" type="text/css" th:href="@{/bootstrap/dist/css/bootstrap.css}"/>
<script type="text/javascript" th:src="@{/bootstrap/dist/js/bootstrap.js}"></script>
<script type="text/javascript" th:src="@{/layer/layer.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>
<table class="table" id="goodsList">
<tr>
<td>商品名称</td>
<td>商品图片</td>
<td>商品原价</td>
<td>秒杀价</td>
<td>库存数量</td>
<td>详情</td>
</tr>
<tr th:each="goods,goodsStat : ${goodsList}">
<td th:text="${goods.goodsName}"></td>
<td><img th:src="@{${goods.goodsImg}}" width="100" height="100"/></td>
<td th:text="${goods.goodsPrice}"></td>
<td th:text="${goods.seckillPrice}"></td>
<td th:text="${goods.stockCount}"></td>
<td><a th:href="'/goodsDetail.htm?goodsId='+${goods.id}">详情</a></td>
</tr>
</table>
</div>
</body>
</html>
redis同步存入:
详情页面:
相关代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>商品详情</title>
<script type="text/javascript" src="/js/jquery-2.2.4.min.js"></script>
<link rel="stylesheet" type="text/css" href="/bootstrap/dist/css/bootstrap.css"/>
<script type="text/javascript" src="/bootstrap/dist/js/bootstrap.js"></script>
<script type="text/javascript" src="/layer/layer.js"></script>
<!-- common.js-->
<script type="text/javascript" src="/js/common.js"></script>
</head>
<body>
<div class="panel panel-default">
<div class="panel-heading">秒杀商品详情</div>
<div class="panel-body">
<span id="userTip">您还没有登录,请先登录再操作<br/></span>
<span>没有收货地址的提示。。。</span>
</div>
<table class="table" id="goods">
<tr>
<td>商品名称</td>
<td colspan="3" id="goodsName"></td>
</tr>
<tr>
<td>商品图片</td>
<td colspan="3"><img id="goodsImg" width="200" height="200"/></td>
</tr>
<tr>
<td>秒杀开始时间</td>
<td id="startTime"></td>
<td>
<input type="hidden" id="remainSeconds"/>
<!-- <span th:if="${seckillStatus eq 0}">秒杀倒计时:
<span id="countDown" th:text="${remainSeconds}"></span>秒
</span>
<span th:if="${seckillStatus eq 1}">秒杀进行中</span>
<span th:if="${seckillStatus eq 2}">秒杀已结束</span>-->
<span id="seckillTip"></span>
</td>
<td>
<!--<form id="seckillForm" method="post" action="/seckill/doSeckill2">
<button class="btn btn-primary btn-block" type="submit" id="buyButton">立即秒杀</button>
<input type="hidden" name="goodsId" id="goodsId" />
</form>-->
<!-- 优化页面静态化-->
<div class="row">
<div class="form-inline">
<img id="captchaImg" width="130" height="32" onclick="refreshCaptcha()" style="display: none"/>
<input id="captcha" class="form-control" style="display: none">
<button class="btn btn-primary" type="button" id="buyButton" onclick="getSeckillPath()">立即秒杀
<input type="hidden" name="goodsId" id="goodsId" />
</button>
</div>
</div>
</td>
</tr>
<tr>
<td>商品原价</td>
<td colspan="3" id="goodsPrice"></td>
</tr>
<tr>
<td>秒杀价</td>
<td colspan="3" id="seckillPrice"></td>
</tr>
<tr>
<td>库存数量</td>
<td colspan="3" id="stockCount"></td>
</tr>
</table>
</div>
</body>
<script>
$(function (){
//countDown();
getDetails();
});
function refreshCaptcha(){
$("#captchaImg").attr("src","/seckill/captcha?goodsId="+$("#goodsId").val()+"&time="+new Date());
}
function getSeckillPath(){
var goodsId = $("#goodsId").val();
var captcha = $("#captcha").val();
// 加载动画
g_showLoading();
$.ajax({
url:"/seckill/path",
type:"GET",
data:{
goodsId: goodsId,
captcha: captcha
},
success:function (data){
if (data.code == 200){
var path = data.obj;
doSeckill(path);
}else {
layer.msg(data.message)
}
},
error:function (){
layer.msg("客户端请求错误!")
}
})
}
function doSeckill(path){
$.ajax({
url: '/seckill/' + path + '/doSeckill',
type: 'POST',
data:{
goodsId:$("#goodsId").val()
},
success:function (data){
// console.log(data.obj);
if(data.code == 200){
//location.href="/orderDetail.htm?orderId="+data.obj.id;
getResult($("#goodsId").val());
}else {
layer.msg(data.message)
}
},
error:function (){
layer.msg("客户端请求错误幺");
}
})
}
function getResult(goodsId){
g_showLoading();
$.ajax({
url:"/seckill/result",
type:"GET",
data: {
goodsId: goodsId,
},
success:function (data){
if (data.code == 200){
var result = data.obj;
if (result < 0){
layer.msg("对不起,秒杀失败!")
}else if (result==0){
setTimeout(function (){
getResult(goodsId);
},50);
}else {
layer.confirm("恭喜您,秒杀成功!是否查看订单?",{btn:["确认","取消"]},
function (){
window.location.href = "/orderDetail.htm?orderId="+result;
},
function (){
layer.close();
})
}
}
},
error:function (){
layer.msg("客户端请求失败!")
}
})
}
function getDetails(){
var goodsId = g_getQueryString("goodsId");
$.ajax({
url:'/goods/detail/'+goodsId,
type:'GET',
success:function (data){
if (data.code==200){
render(data.obj);
}else {
layer.msg(data.message);
}
},
error:function (){
layer.msg("客户端请求失败哈");
}
});
}
function render(detail){
var user = detail.user;
var goods = detail.goodsVo;
var remainSeconds = detail.remainSeconds;
if (user) {
$("#userTip").hide();
}
$("#goodsName").text(goods.goodsName);
$("#goodsImg").attr("src",goods.goodsImg);
$("#startTime").text(new Date(goods.startDate).format("yyyy-MM-dd HH:mm:ss"));
$("#remainSeconds").val(remainSeconds);
$("#goodsId").val(goods.id);
$("#goodsPrice").text(goods.goodsPrice);
$("#seckillPrice").text(goods.seckillPrice);
$("#stockCount").text(goods.stockCount);
countDown();
}
function countDown(){
var remainSeconds = $("#remainSeconds").val();
var timeout;
// 秒杀开始
if (remainSeconds > 0){
$("#buyButton").attr("disabled",true);
$("#seckillTip").html("秒杀倒计时:"+remainSeconds+"秒");
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);
}
$("#seckillTip").html("秒杀进行中");
$("#captchaImg").attr("src","/seckill/captcha?goodsId="+$("#goodsId").val()+"&time="+new Date());
$("#captchaImg").show();
$("#captcha").show();
// 秒杀已结束
}else {
$("#buyButton").attr("disabled",true);
$("#seckillTip").html("秒杀已经结束");
$("#captchaImg").hide();
$("#captcha").hide();
}
}
</script>
</html>
秒杀成功后:
页面很简单,跟着老师学的。根据自己的需求,页面可以升华,有些功能可以完善(支付功能没写),经过压测测试,它的QPS还是挺高的,当做练习项目用。
功能没写),经过压测测试,它的QPS还是挺高的,当做练习项目用。
有需要的源码到码云下载:https://gitee.com/cgc888/seckill
或加qq: 3316127206发给你😀