<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\Goods;
use Illuminate\Http\Request;
use App\Models\ActivityGoods;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
use Lcobucci\JWT\Exception;
class GoodsController extends Controller
{
//商品秒杀列表
public function activityList()
{
$result = ActivityGoods::with(['goods'])
->get();
return response()->json(['errorCode' => 0, 'data' => $result, 'msg' => '查询成功']);
}
//商品秒杀列表
public function goodsDetail(Request $request)
{
$goods_id = $request->get('goods_id');
$result = ActivityGoods::with(['goods'])
->where('goods_id',$goods_id)
->first();
return response()->json(['errorCode' => 0, 'data' => $result, 'msg' => '查询成功']);
}
//同步库存
public function syncStock()
{
//查看队列的长度
// $count = Redis::llen('activity_goods_1');
// echo $count;
// die;
//查出所有参与秒杀活动列表
$result = ActivityGoods::with(['goods'])
->get()->toArray();
//进行把参与秒杀的商品写入到数据库
foreach ($result as $val){
//生成对应商品库存队列
$goods = "activity_goods_".$val['goods_id'];
for ($i=0; $i < $val['sku_nums']; $i++) {
Redis::lpush($goods, 1);
}
}
}
//校验库存
public function checkStock(Request $request)
{
//获取token
$token = explode(' ',$request->header('authorization'))[1];
//进行查看
$userInfo = Cache::get($token);
//抢购用户id
$userID = $userInfo->id;
//商品id
$goodsID = $request->input("goods_id");
//对应商品库存队列
$goods = "activity_goods_".$goodsID;
//对应商品抢购成功用户集合 {1,3,4}
$robSuccessUser = "success_user".$goodsID;
//进行判断当前用户是否在抢成功的队列里面
$result = Redis::sismember($robSuccessUser,$userID);
//如果你在这里面,就抢完了
if ($result) {
//如果抢购成功 返回状态码,进行下单
return response()->json(['errorCode' => 20000, 'data' => '', 'msg' => '已经抢购过了']);
}
//减库存,把队列里面的数据从左边 头
$count = Redis::lpop($goods);
if (!$count) {
//如果抢购成功 返回状态码,进行下单
return response()->json(['errorCode' => 20001, 'data' => '', 'msg' => '已经抢光了哦']);
}
//把当前这个秒杀的uid存储到中奖的队列里set
$success = Redis::sadd($robSuccessUser, $userID);
if(!$success){
//已经在成功队列里了,加回库存,防止的是同个用户并发请求
Redis::lpush($goods, 1);
//如果抢购成功 返回状态码,进行下单
return response()->json(['errorCode' => 20002, 'data' => '', 'msg' => '已经抢购过了']);
}
//如果抢购成功 返回状态码,进行下单
return response()->json(['errorCode' => 0, 'data' => '', 'msg' => '秒杀成功']);
}
//创建订单
public function createOrder(Request $request)
{
//获取token
$token = explode(' ',$request->header('authorization'))[1];
//进行查看
$userInfo = Cache::get($token);
//抢购用户id
$userID = $userInfo->id;
//商品id
$goodsID = $request->input("goods_id");
//对应商品抢购成功用户集合 {1,3,4}
$robSuccessUser = "success_user".$goodsID;
//进行判断当前用户是否在抢成功的队列里面
$result = Redis::sismember($robSuccessUser,$userID);
//如果你在这里面,就抢完了
if (!$result) {
//如果抢购成功 返回状态码,进行下单
return response()->json(['errorCode' => 20003, 'data' => '', 'msg' => '手慢了!']);
}
DB::beginTransaction();
try{
//减库存
//生成订单
DB::commit();
//下单成功,跳转支付页面
return response()->json(['errorCode' => 0, 'data' => '', 'msg' => '下单成功!']);
}catch (\Exception $e){
DB::rollBack();
}
}
}
微信小程序页面
// pages/goods_detail/goods_detail.js
import {
debounce
} from "../../utils/util"
Page({
/**
* 页面的初始数据
*/
data: {
text:[],
expire_time:0,
btn_disable:false
},
/**
* 生命周期函数--监听页面加载
*/
onl oad: function (options) {
//商品id
let id =options.id;
console.log(id)
this.getGoodsDetail(id)
},
//商品详情获取
getGoodsDetail(id){
wx.request({
url: 'http://www.pyg.com/api/goods_list?id='+id,
success: res => {
let now_time = Math.round(new Date().getTime() / 1000).toString();
// let expire_time = res.data.result.start_time-now_time;
// console.log(expire_time)
console.log(res.data.data)
this.setData({
text:res.data.data,
// expire_time
})
// if(expire_time > 0){
// this.setData({
// btn_disable:true
// })
// }
}
})
},
//立即抢购
buyGoods:debounce(function (e) {
let id = e[0].currentTarget.dataset.id
console.log(id)
// var token = wx.getStorageSync('token')
wx.request({
url: 'http://www.zf.com/api/check_stock',
header: {
// 'Authorization': `Bearer ${token}`
},
method:"POST",
data:{
id
},
success: res => {
let code = res.statusCode.toString()
if (!code.startsWith('2')){
wx.showToast({
title: '异常!',
})
}
if(res.data.errorCode == 0){
wx.redirectTo({
url: '/pages/order/order',
})
}else{
wx.showToast({
title: res.data.msg,
})
}
console.log(res.data)
}
})
}),
})
<view>商品秒杀页面</view>
<l-countdown time-type="second" time="{{expire_time}}" />
<l-card type="primary" full="{{true}}" image="{{text.goods_image}}" title="{{text.name}}">
<view>
价格:{{text.price}}
</view>
<view>
<l-button disabled="{{ btn_disable }}" bind:lintap="buyGoods" type="error" data-id="{{ text.id }}">立即秒杀</l-button>
</view>
</l-card>