下面这里是后台列表,详情页展示,以及秒杀的实现
这里要用到两个表一个是商品(goods表) 另一个是(artivity_goods表)
需要进行关联
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class ActivityGoods extends Base
{
use HasFactory;
public function goods()
{
return $this->belongsTo(Goods::class,'goods_id');
}
}
<?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();
}
}
}
以上就是小程序实现秒杀的全过程了,有不对的不懂的欢迎来交流探讨
谢谢!
|