laravel 微信小程序 秒杀

<?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>

上一篇:mysql学习-数据统计分析


下一篇:16、迭代器