< template>
< div>
< el-container>
< el-header height = "120px" >
< miao-sha-header> < /miao-sha-header>
< /el-header>
< el-main>
< p class = "goods_head" > 秒杀商品详情< /p>
< el-form label-position= "left" label-width= "120px" >
< el-form-item label = "商品名称:" >
{ { this.miaoShaGoods.goods.name} }
< /el-form-item>
< el-form-item label = "商品图片:" >
< img :src= "getSrcUrl(this.miaoShaGoods.goods.image)" />
< /el-form-item>
< el-form-item label = "商品原价:" >
{ { this.miaoShaGoods.goods.price+'元' } }
< /el-form-item>
< el-form-item label = "秒杀价:" >
{ { this.miaoShaGoods.price+'元' } }
< /el-form-item>
< el-form-item label = "库存数量:" >
{ { this.miaoShaGoods.stock} }
< /el-form-item>
< el-form-item label = "秒杀开始时间:" >
{ { this.miaoShaGoods.startTime} }
< span v-show= "miaoShaGoods.miaoShaStatus==0" > 秒杀倒计时:{ { miaoShaGoods.remainBeginSecond} } 秒< /span>
< span v-show= "miaoShaGoods.miaoShaStatus==1" > 秒杀进行中< /span>
< span v-show= "miaoShaGoods.miaoShaStatus==2" > 秒杀结束< /span>
< /el-form-item>
< el-form-item label = "秒杀结束时间:" >
{ { this.miaoShaGoods.endTime} }
< /el-form-item>
< /el-form>
< img id = "verifyCodeImg" width = "80" height = "32" :src= "verifyCodeImgSrc" v-show= "miaoShaGoods.miaoShaStatus==1" @click= "refreshVerifyCode" >
< input id = "verifyCode" type = "text" style = "width: 60px;height: 23px;padding: 4px;border: 1px solid gray;" v-model= "verifyCode" v-show= "miaoShaGoods.miaoShaStatus==1" />
< el-button v-show= "miaoShaGoods.miaoShaStatus==1" type = "primary" size = "small" @click= "exec_miaosha" > 立即秒杀< /el-button>
< p style = "color: red" > { { miaoShaResult} } < /p>
< /el-main>
< el-footer>
< miao-sha-footer> < /miao-sha-footer>
< /el-footer>
< /el-container>
< /div>
< /template>
< script>
import MiaoShaHeader from './common/Header' ;
import MiaoShaFooter from './common/Footer' ;
import axios from 'axios' ;
import { getServerUrl} from '@/config/sys' ;
export default {
name: 'Detail' ,
data ( ) {
return {
miaoShaGoods:{
goods:{
name:'' ,
image:'default.jpg' ,
price:0
}
} ,
miaoShaResult:"" ,
verifyCodeImgSrc:"" ,
verifyCode:""
}
} ,
components: {
MiaoShaHeader,
MiaoShaFooter
} ,
methods: {
getSrcUrl( t) {
return getServerUrl( 'image/' + t) ;
} ,
exec_miaosha ( ) {
if( this.verifyCode== "" ) {
alert( "请输入验证码结果!" ) ;
return ;
}
let url = getServerUrl( "miaoSha/exec" ) ;
let token = window.sessionStorage.getItem( "token" ) ;
axios.defaults.headers.common[ 'token' ] = token;
axios.get( url,{
params:{
miaoShaGoodsId:this.$route .params.id,
verifyCode:this.verifyCode
}
} ) .then( response= > {
let data = response.data;
if( data.code!= 0 ) {
alert( data.msg) ;
} else{
// alert( data.orderId) ;
this.miaoShaGoods.miaoShaStatus = 4 ;
this.miaoShaResult = data.msg;
this.getMiaoShaResult( this.$route .params.id) ;
}
} ) .catch( error= > {
alert( error+"-请联系管理员" ) ;
} )
} ,
getMiaoShaResult( miaoShaGoodsId) {
let url = getServerUrl( "miaoSha/result" ) ;
let token = window.sessionStorage.getItem( "token" ) ;
axios.defaults.headers.common[ 'token' ] = token;
axios.get( url,{
params:{
miaoShaGoodsId:this.$route .params.id,
verifyCode:this.verifyCode
}
} ) .then( response= > {
let data = response.data;
if( data.code!= 0 ) {
alert( data.msg) ;
} else{
let result = data.result;
if( result== "0" ) { // 排队中,继续轮询
setTimeout( function ( ) {
this.getMiaoShaResult( miaoShaGoodsId)
} ,50) ;
} else if( result== "-1" ) {
this.miaoShaResult = "秒杀失败" ;
} else{
alert( "秒杀成功! " ) ;
alert( result) ;
}
}
} ) .catch( error= > {
alert( error+"-请联系管理员" ) ;
} )
} ,
getInfo ( ) {
let url = getServerUrl( "miaoShaGoods/detail" ) ;
let token = window.sessionStorage.getItem( "token" ) ;
axios.defaults.headers.common[ 'token' ] = token;
axios.get( url,{
params:{
id:this.$route .params.id
}
} ) .then( response= > {
console.log( response.data.data) ;
this.miaoShaGoods = response.data.data;
this.countDown( ) ;
if( this.miaoShaGoods.remainEndSecond> 0 ) { //秒杀还没结束
setTimeout(( ) = > {
this.miaoShaGoods.miaoShaStatus = 2 ;
} ,this.miaoShaGoods.remainEndSecond*1000)
}
} ) .catch( error= > {
alert( error+"-请联系管理员" ) ;
} )
} ,
countDown ( ) {
let timeout ;
let rs = this.miaoShaGoods.remainBeginSecond;
if( rs> 0 ) { //秒杀还没开始,倒计时
timeout = setTimeout(( ) = > {
this.miaoShaGoods.remainBeginSecond = this.miaoShaGoods.remainBeginSecond-1;
this.countDown( ) ;
} ,1000) ;
} else if( rs== 0 ) { //秒杀进行中
this.miaoShaGoods.miaoShaStatus = 1 ;
let url = getServerUrl( "verifyCode/get" ) ;
this.verifyCodeImgSrc = url+"?miaoShaGoodsId=" +this.$route .params.id+"&token=" +window.sessionStorage.getItem( "token" ) ;
if( timeout) {
clearTimeout( timeout) ;
}
} else{ //秒杀结束
this.miaoShaGoods.miaoShaStatus = 2 ;
}
} ,
refreshVerifyCode ( ) {
let url = getServerUrl( "verifyCode/get" ) ;
this.verifyCodeImgSrc = url+"?miaoShaGoodsId=" +this.$route .params.id+"&token=" +window.sessionStorage.getItem( "token" ) +"×tamp=" +new Date( ) .getTime( ) ;
}
} ,
mounted ( ) {
this.getInfo( ) ;
}
}
< /script>
< style scoped>
.goods_head{
font-weight: bold;
font-size: 20px;
}
< /style>
package com.java1234.miaosha.config;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* rabbitmg配置类
*/
@Configuration
public class MQConfig {
public static final String MIAOSHA_QUEUE = "miaosha_queue" ;
@Bean
public Queue queue ( ) {
return new Queue( MIAOSHA_QUEUE) ;
}
}
package com.java1234.miaosha.rabbitmq;
import com.java1234.miaosha.config.MQConfig;
import com.java1234.miaosha.entity.MiaoShaMessage;
import com.java1234.miaosha.entity.Order;
import com.java1234.miaosha.entity.R;
import com.java1234.miaosha.entity.User;
import com.java1234.miaosha.service.IMiaoShaGoodsService;
import com.java1234.miaosha.service.IMiaoShaService;
import com.java1234.miaosha.service.IOrderService;
import com.java1234.miaosha.util.BeanUtil;
import com.java1234.miaosha.util.RedisUtil;
import com.java1234.miaosha.vo.MiaoShaGoodsVo;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
@Service
public class MQReceiver {
@Autowired
private RedisUtil redisUtil;
@Autowired
private IMiaoShaGoodsService miaoShaGoodsService;
@Autowired
private IMiaoShaService miaoShaService;
@Autowired
private IOrderService orderService;
@RabbitListener( queues = MQConfig.MIAOSHA_QUEUE)
public void receiveMiaoShaMessage( String message) {
MiaoShaMessage miaoShaMessage = BeanUtil.stringToBean( message, MiaoShaMessage.class) ;
System.out.println( "receive message:" +miaoShaMessage) ;
User user = miaoShaMessage.getUser( ) ;
Integer miaoShaGoodsId = miaoShaMessage.getMiaoShaGoodsId( ) ;
//第二步:判断库存是否足够
MiaoShaGoodsVo miaoShaGoods = miaoShaGoodsService.findById( miaoShaGoodsId) ;
Integer stock = miaoShaGoods.getStock( ) ;
if( stock<= 0 ) {
System.out.println( "库存不足" ) ;
return ;
}
//第三步:判断用户是否重复秒杀
HashMap map = new HashMap( ) ;
map.put( "user_id" ,user.getId( )) ;
map.put( "miaosha_goods_id" ,miaoShaGoodsId) ;
Order orderE = orderService.findByUserIdAndMiaoShaGoodsId( map) ;
if( orderE!= null) {
System.out.println( "您已经秒杀过此商品,不能重复秒杀" ) ;
return ;
}
//第四步:减库存,下订单,必须同一个事务
String orderId = miaoShaService.miaoSha( user, miaoShaGoods) ;
}
}
package com.java1234.miaosha.rabbitmq;
import com.java1234.miaosha.config.MQConfig;
import com.java1234.miaosha.entity.MiaoShaMessage;
import com.java1234.miaosha.util.BeanUtil;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class MQSender {
@Autowired
private AmqpTemplate amqpTemplate;
public void sendMiaoShaMessage( MiaoShaMessage miaoShaMessage) {
String msg = BeanUtil.beanToString( miaoShaMessage) ;
System.out.println( "send message:" +msg) ;
amqpTemplate.convertAndSend( MQConfig.MIAOSHA_QUEUE,msg) ;
}
}