Laravel8.5+微信小程序实现京东商城秒杀方案

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 一、商品秒杀涉及的知识点鉴权策略封装接口访问频次限制小程序设计页面防抖接口调用订单创建事务使用超卖防御

Laravel8.5+微信小程序实现京东商城秒杀方案


一、商品秒杀涉及的知识点


  • 鉴权策略封装
  • 接口访问频次限制
  • 小程序设计
  • 页面防抖
  • 接口调用
  • 订单创建事务使用
  • 超卖防御


二、订单库存系统方案(3种)


网络异常,图片无法展示
|


  1. 下单减库存 优点是库存和订单的强一致性,商品不会卖超,但是可能导致恶意下单,影响正常流程


  1. 支付减库存 优点是避免恶意下单,支付和库存强一致性,但是可能出现订单无法支付,商品库存不足等问题。


  1. 预扣库存 预扣库存是指用户请求之后预扣库存,生成订单,在时效内支付,否则订单失效,库存还原


三、小程序秒杀页面


  • 商品秒杀详情页面页面
  • 该商品秒杀时间未到,则上方进行提醒秒杀商品倒计时,并且立即抢购禁用(按钮置灰)

网络异常,图片无法展示
|


  • 商品秒杀时间开始,则把立即秒杀按钮禁用状态改为可以点击
  • 点击立即秒杀按钮要考虑页面防抖,不能重复在同一秒中重复发起N次网络请求

网络异常,图片无法展示
|


四、小程序部分代码展示


  1. 小程序wxml代码


<view>商品秒杀页面</view>
<l-countdown time-type="second" time="{{expire_time}}" bind:linend="changeBtn" />
<l-card type="primary" full="{{true}}" image="{{goods.goods.goods_image}}" title="{{goods.goods.goods_name}}">
     <view>
       价格:{{goods.goods.goods_price}}
     </view>
     <view>
     <!-- <button disabled="true" bindtap="buyGoods" >抢购</button> -->
      <l-button disabled="{{ btn_disable }}" bind:lintap="buyGoods" type="error" data-goods_id="{{ goods.goods.id }}">立即秒杀</l-button>
     </view>
  </l-card>
复制代码


  1. 小程序js代码
// pages/goods_detail/goods_detail.js
import {
  debounce
} from "../../utils/util"
Page({
  /**
   * 页面的初始数据
   */
  data: {
   goods:{},
   expire_time:0,
   btn_disable:false
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (e) {
     //商品id
     let goods_id = e.goods_id;
     this.getGoodsDetail(goods_id)
  },
  //获取商品详情
  getGoodsDetail(goods_id){
    var token = wx.getStorageSync('token')
    wx.request({
      url: 'http://www.zfw.com/api/v1/goods_detail?goods_id='+goods_id,
      header: {
        'Authorization': `Bearer ${token}`
      },
      success: res => {
        //当前的时间戳
        let now_time = Math.round(new Date().getTime() / 1000).toString();
        let expire_time = res.data.data.start_time-now_time;
        this.setData({
          goods:res.data.data,
          expire_time
        })
        if(expire_time > 0){
          this.setData({
            btn_disable:true
          })
        }
        console.log(this.data.goods)
      }
    })
  },
  //立即抢购   debounce此方法是引入的util工具类的页面防抖函数
  buyGoods:debounce(function (e) {
    let goods_id = e[0].currentTarget.dataset.goods_id
    var token = wx.getStorageSync('token')
    wx.request({
      url: 'http://www.zfw.com/api/v1/snap_up',
      header: {
        'Authorization': `Bearer ${token}`
      },
      method:"POST",
      data:{
        goods_id
      },
      success: res => {
        let code = res.statusCode.toString()
        if (!code.startsWith('2')){
           wx.showToast({
             title: '异常!',
             icon:1
           })
        }
        if(res.data.errorCode == 0){
            wx.redirectTo({
              url: '/pages/order/order',
            })
        }else{
          wx.showToast({
            title: res.data.msg,
          })
        }
        console.log(res.data)
      }
    })
  }),
  changeBtn(){
    this.setData({
      btn_disable:false
    })
  }
})
复制代码


  1. 小程序json代码,引入的自定义组件
{
  "usingComponents": {
    "l-card":"/miniprogram_npm/lin-ui/card",
    "l-button":"/miniprogram_npm/lin-ui/button",
    "l-countdown":"/miniprogram_npm/lin-ui/countdown"
  }
}
复制代码


五、后台业务逻辑


要考虑订单超卖,这次代码使用的redis队列实现的

<?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()
    {
        //查出所有参与秒杀活动列表
        $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();
        }
    }
}


相关文章
|
3月前
|
缓存 小程序 前端开发
商城/点餐/家政类小程序源码合集_微信抖音小程序源码开发从入门到精通实战
本文系统讲解如何利用现有源码快速开发商城、点餐、家政类微信/抖音小程序,涵盖环境搭建、核心功能实现、多平台部署与优化,提供完整技术方案。实战导向,助力开发者高效入门与落地。
|
3月前
|
人工智能 监控 小程序
【快递鸟】选择对接你的物流商城/小程序的物流API平台
在电商竞争日益激烈的今天,物流体验已成为影响用户留存和复购的关键因素。一个高效、透明、稳定的物流系统,对于物流商城或小程序来说至关重要。然而,自建物流查询系统需要对接众多快递公司,开发周期长、维护成本高、数据整合困难。
201 0
|
5月前
|
供应链 小程序 API
微信小程序API集成京东库存,移动端销量暴涨!
在数字化时代,微信小程序与京东库存系统集成成为提升移动端销量的关键策略。本文详解如何通过API实现库存实时同步、优化用户体验,推动销量增长50%以上,并结合实际案例与代码示例,为企业提供可落地的解决方案。
168 0
|
8月前
|
人工智能 开发框架 小程序
工会成立100周年纪念,开发职工健身AI运动小程序、APP方案推荐
为庆祝中华全国总工会成立100周年,特推出基于AI技术的智能健身系统,以小程序和APP形式呈现,助力职工健康生活。方案包括:1) 小程序插件,支持多种运动识别,开箱即用;2) APP插件,提供更高精度的运动检测;3) 成熟的「AI乐运动」系统,支持赛事活动管理。这些方案满足不同需求,推动全民健身体验升级,彰显工会对职工健康的关怀。
|
11月前
|
移动开发 小程序
thinkphp+uniapp开发的多端商城系统源码/H5/小程序/APP支持DIY模板直播分销
thinkphp+uniapp开发的多端商城系统源码/H5/小程序/APP支持DIY模板直播分销
504 0
|
vr&ar 图形学 UED
电子沙盘VR模型大屏平板手机微信使用方案
数字孪生电子沙盘和VR模型被广泛应用在房地产等行业,为不同设备定制不同版本的模型是常见做法。然而,通过实时云渲染技术,可以将PC端的VR模型转化为网页版,使用户能够在平板或手机上流畅浏览详细信息,无需开发多个版本。这不仅提升了用户体验,还简化了模型提供商的工作流程,降低了成本。尤其在新楼盘发布时,可通过公众号或广告链接快速吸引潜在客户。成本主要取决于并发用户数及显卡性能要求,但该技术显著提高了跨设备访问的便利性。
264 1
|
小程序 数据可视化 API
低代码可视化-uniapp商城首页小程序-代码生成器
低代码可视化-uniapp商城首页小程序-代码生成器
230 0
|
小程序 前端开发 数据可视化
微信商城小程序WeiMall
微信商城小程序WeiMall
239 0
|
小程序 前端开发
微信小程序商城,微信小程序微店 【毕业设计参考项目】
文章推荐了一个微信小程序商城项目作为毕业设计参考,该项目在Github上获得18.2k星,提供了详细的使用教程和前端页面实现,适合学习微信小程序开发和作为毕业设计项目。
微信小程序商城,微信小程序微店 【毕业设计参考项目】
|
JavaScript
vue尚品汇商城项目-day06【43.微信支付业务】
vue尚品汇商城项目-day06【43.微信支付业务】
141 0