参考博客:

https://blog.csdn.net/m0_56487875/article/details/118603439

小程序登录:

https://www.cnblogs.com/xiaoyantongxue/p/15677256.html

小程序授权登录跳转至秒杀列表页

// pages/seckill/seckill.js
Page({ /**
* 页面的初始数据
*/
data: {
goods: []
}, /**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
var token=wx.getStorageSync('token')
wx.request({
url: 'http://www.yan.com/api/yk/goods', //仅为示例,并非真实的接口地址
header: {token},
method: "POST",
success: res => {
console.log(res.data);
this.setData({
goods: res.data.data
}) }
}) },
/**
* 开始抢购按钮
*/
start(e){
var id=e.target.dataset.id
wx.navigateTo({
url: '/pages/details/details?id='+id,
}) }, })

//数据进行渲染:

<!--pages/seckill/seckill.wxml-->
<view>秒杀</view> <view class="page-section-spacing">
<scroll-view scroll-y="true" class="page-scroll-style" bindscrolltolower="scroll">
<block wx:for="{{goods}}" wx:key="goods">
<view class="scroll-view-content">
<image src="{{item.goods.goods_image}}" class="scroll-view-image"></image>
<view class="scroll-view-text">
{{item.goods.goods_name}}
</view>
<view class="scroll-view-name">
¥{{item.goods.goods_price}}
</view>
<view class="scroll-view-text">
限量{{item.goods.goods_nums}}
</view>
<text bindtap="start" data-id="{{item.id}}">开始抢购</text>
</view>
</block>
</scroll-view>
</view>

wxss

/**index.wxss**/
.weui-search-bar {
position: relative;
padding: 8px 10px;
display: -webkit-box;
display: -webkit-flex;
display: flex;
box-sizing: border-box;
background-color: #EFEFF4;
border-top: 1rpx solid #D7D6DC;
border-bottom: 1rpx solid #D7D6DC;
}
.weui-icon-search_in-box {
position: absolute;
left: 10px;
top: 7px;
}
.weui-search-bar__form {
position: relative;
-webkit-box-flex: 1;
-webkit-flex: auto;
flex: auto;
border-radius: 5px;
background: #FFFFFF;
border: 1rpx solid #E6E6EA;
}
.weui-search-bar__box {
position: relative;
padding-left: 30px;
padding-right: 30px;
width: 100%;
box-sizing: border-box;
z-index: 1;
}
.weui-search-bar__input {
height: 28px;
line-height: 28px;
font-size: 14px;
}
.weui-search-bar__cancel-btn {
margin-left: 10px;
line-height: 28px;
color: #09BB07;
white-space: nowrap;
}
.swp{
height: 500rpx;
}
.page-section-spacing{
margin-top: 60rpx;
} .page-scroll-style{
height: 1000rpx;
background: aliceblue;
}
.scroll-view-content{
height: 230rpx;
margin: auto 10rpx;
background: white;
border: 1px solid gray;
}
.scroll-view-image{
width: 200rpx;
height: 200rpx;
margin-top: 15rpx;
margin-left: 20rpx;
float: left;
}
.scroll-view-text{
width: 400rpx;
float: left;
font-weight: 800;
margin-top: 15rpx;
margin-left: 20rpx;
}
.scroll-view-name{
float: left;
font-size: 30rpx;
color: gray;
margin-top: 20rpx;
margin-left: 20rpx;
color: red;
}
.scroll-view_H{
white-space: nowrap;
}
.scroll-view-item{
height: 300rpx;
}
.scroll-view-item_H{
display: inline-block;
width: 100%;
height: 300rpx;
}

php 后台请求的数据路由:

Route::group(['namespace' => 'YK','middleware'=>'jwt'], function () {
//列表展示
Route::post('yk/goods','YkController@goods');
// 详情
Route::post('yk/details','YkController@details');
// 秒杀
Route::post('yk/checkstock','YkController@checkStock');
// 订单的生成
Route::post('yk/order','YkController@createOrder'); });

控制器:

<?php

namespace App\Http\Controllers\YK;

use App\Http\Controllers\Controller;
use App\models\Seckill\Goods;
use App\Models\Seckill\SeckillOrder;
use App\Models\Seckill\SeckillTime;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
use Predis\Client; class YkController extends Controller
{ //列表展示
public function goods()
{
$result = SeckillTime::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);
} return response()->json(['code' => 200, 'message' => 'success', 'data' => $result]);
}
} // 详情
public function details(Request $request)
{
$id = $request->post('id');
$res = Goods::where('id', $id)->first();
if ($res) {
return response()->json(['code' => 200, 'message' => 'success', 'data' => $res]);
}
return response()->json(['code' => 500, 'message' => 'no', 'data' => '']);
} // 抢购:
public function checkStock(Request $request)
{
// 接受用户id
$userID=$request->post('userid');
// 商品id
$goodsID=$request->post('id');
$goods = "activity_goods_".$goodsID;
//对应商品抢购成功用户集合 {1,3,4}
$robSuccessUser = "success_user".$goodsID;
//进行判断当前用户是否在抢成功的队列里面
$result = Redis::sismember($robSuccessUser,$userID);
//如果你在这里面,就抢完了
if ($result) {
//如果抢购成功 返回状态码,进行下单
return response()->json(['code' => 201, 'data' => '', 'msg' => '已经抢购过了']);
}
//减库存,把队列里面的数据从左边 头
$count = Redis::lpop($goods);
if (!$count) {
//如果抢购成功 返回状态码,进行下单
return response()->json(['code' => 202, 'data' => '', 'msg' => '已经抢光了哦']);
}
//把当前这个秒杀的uid存储到中奖的队列里set
$success = Redis::sadd($robSuccessUser, $userID);
if(!$success){
//已经在成功队列里了,加回库存,防止的是同个用户并发请求
Redis::lpush($goods, 1);
//如果抢购成功 返回状态码,进行下单
return response()->json(['errorCode' => 203, 'data' => '', 'msg' => '已经抢购过了']);
} //如果抢购成功 返回状态码,进行下单
return response()->json(['errorCode' => 200, 'data' => '', 'msg' => '秒杀成功']); }
订单的生成
public function createOrder(Request $request)
{ //接受小程序用户id
$userID=$request->post('userid');
//抢购用户id
//商品id
$goodsID = $request->post("goods_id");
//对应商品抢购成功用户集合 {1,3,4}
$robSuccessUser = "success_user".$goodsID;
//进行判断当前用户是否在抢成功的队列里面
$result = Redis::sismember($robSuccessUser,$userID);
//如果你在这里面,就抢完了
if (!$result) {
//如果抢购成功 返回状态码,进行下单
return response()->json(['code' => 203, 'data' => '', 'msg' => '手慢了!']);
} DB::beginTransaction();
try{
//减库存 秒杀的商频库存减去一
SeckillTime::decrement('sku_nums');
Goods::decrement('goods_nums');
//生成订单
$order_no='YK'.date('YmdHis').sprintf("%'.09d",$goodsID).mt_rand(1000,9999);
// 将订单号和用户id,商品id添加至 订单明细表中
$data=[];
$data['user_id']=$userID;
$data['g_id']=$goodsID;
$data['order']=$order_no;
SeckillOrder::insertGetId($data);
DB::commit();
//下单成功,跳转支付页面
return response()->json(['code' => 200, 'data' => $order_no, 'msg' => '下单成功!']);
}catch (\Exception $e){
DB::rollBack();
} } }

小程序抢购,点击抢购进入详情页面:

详情wxjs的代码:

// pages/details/details.js
// 放抖的引入
import tool from "../../utils/tool.js";
Page({
/**
* 页面的初始数据
*/
data: {
goods_details:[]
}, /**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
var token=wx.getStorageSync('token')
var id=options.id
wx.request({
url: 'http://www.yan.com/api/yk/details', //仅为示例,并非真实的接口地址
header: {token},
data:{
id:id
},
method: "POST",
success: res => {
// console.log(res.data.data);
this.setData({
goods_details: res.data.data
}) }
}) },
//秒杀
buyGoods(e){
var token=wx.getStorageSync('token')
var id=e.target.dataset.id;
// 获取用户id
var userid=wx.getStorageSync('userid');
wx.request({
url: 'http://www.yan.com/api/yk/checkstock', //仅为示例,并非真实的接口地址
header: {token},
data:{
id:id,
userid:userid
},
method: "POST",
success: res => {
console.log(res.data);
if(res.data.code==201){
wx.switchTab({
url: '/pages/order/order?gid='+id,
})
wx.showToast({
title: '已经抢购过了,请支付',
}) }
if(res.data.code==202){
wx.showToast({
title: '已经抢光了哦',
}) }
if(res.data.code==203){
wx.showToast({
title: '已经抢购过了,请支付',
})
wx.switchTab({
url: '/pages/order/order?gid='+id,
}) }
if(res.data.code==200){
wx.showToast({
title: '秒杀成功,请支付',
})
// 跳转至订单页面
wx.switchTab({
url: '/pages/order/order?gid='+id,
})
} }
})
}, })

详情wxml代码:

<!--pages/details/details.wxml-->
<view class="page-section-spacing">
<scroll-view scroll-y="true" class="page-scroll-style" bindscrolltolower="scroll">
<view class="scroll-view-content">
<image src="{{goods_details.goods_image}}" class="scroll-view-image"></image>
<view class="scroll-view-text">
{{goods_details.goods_name}}
</view>
<view class="scroll-view-name">
¥{{goods_details.goods_price}}
</view>
<view class="scroll-view-text">
限量{{goods_details.goods_nums}}
</view>
<text bindtap="buyGoods" class="a" data-id="{{goods_details.id}}">开始秒杀</text>
</view> </scroll-view>
</view>

抢购完成进入订单页面:

<button type="primary" bindtap="pay">支付</button>
// pages/order/order.js
Page({ /**
* 页面的初始数据
*/
data: {
goods_id: ''
}, /**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
// 获取商品id用于订单的生成
var gid = options.gid;
this.setData({
goods_id: gid
})
},
// 支付
pay(e) {
// 获取用户id
var userid = wx.getStorageSync('userid');
var goods_id = this.data.goods_id,
var token=wx.getStorageSync('token')
// 将用户id发送至后台用于生成订单
wx.request({
url: 'http://www.yan.com/api/yk/order', //仅为示例,并非真实的接口地址
data: {
userid: userid,
goods_id: goods_id
},
header: {token},
method: "POST",
success(res) {
if (res.data.code == 203) {
wx.showToast({
title: '手慢啦',
})
}
if (res.data.code == 200) {
wx.showToast({
title: '下单成功',
})
} }
}) } })

小程序 laravel 实现秒杀的更多相关文章

  1. 微信小程序+laravel 7+ Redis +短信宝 实现手机号验证码登录

    以下代码可以进行优化和封装:这里我实现功能为主,就不封装啦.小伙伴可以自己试着封装一下. 1:书写登录表单 <view class="container"> <v ...

  2. 小程序实现sql插入语句转换成Laravel迁移语句

    sql的插入语句长这样: INSERT INTO `media` (`MediaID`, `type`, `filename`, `title`) VALUES (1, 'word', 'word1. ...

  3. 小程序应用的Python服务器部署高配,依然是腾讯云秒杀阿里云!

    上一篇文章,“小程序创业最低配置部署,腾讯云折扣秒杀阿里云!”介绍了小程序项目启动时的最低配置服务器选择,但当项目良好发展时,还是要把服务器配置调整到标准水平,承受住日益增长的流量访问. 随着Pyth ...

  4. 编程入门视频【 Python、PHP、ThinkPHP、Laravel、Mysql、微信小程序】

    免费分享 Python.PHP.ThinkPHP.Laravel.Mysql.微信小程序等学习视频 点击进入搜刮 免费分享 Python.PHP.ThinkPHP.Laravel.Mysql.微信小程 ...

  5. iBrand 开源电商小程序 (Laravel API+ webpack + gulp + 原生小程序)

    iBrand 社交电商产品正式进入开源过程中了,我们制定了详细的开源计划,目前已经发布了 V1 的版本,后续的版本也在陆续整理完善中. 各个版本功能明细如下图: 3 个版本计划在今年春节前全部完成,可 ...

  6. 微信小程序前台的用户数据入库(后台Laravel)

    首先 我们可以看到微信小程序官方 文档 wx.login   api-login.jpg 通过此图 我们知道 前台要传 一个 code给后台,后台拿到code 并结合appid和appsecret请求 ...

  7. Laravel wxxcx 微信小程序获取用户信息

    wxxcx 是Laravel5微信小程序登录获取用户信息扩展 部署 12345678 # 安装$ composer require iwanli/wxxcx# 注册服务# 在 /config/app. ...

  8. laravel 微信小程序登录 加密解密扩展包

    https://github.com/lanceWan/wxxcx 测试的时候一定要保证服务器的 appid  和客户端的appid一致 如果是切换测试 那么需要把本地的项目从微信小程序上面删除掉 再 ...

  9. 微信小程序----团购或秒杀的批量倒计时实现

    效果图 实现思路微信小程序实现倒计时,可以将倒计时的时间进行每一秒的计算和渲染! JS模拟商品列表数据 goodsList:在 onLoad 周期函数中对活动结束时间进行提取:建立时间格式化函数 ti ...

随机推荐

  1. vue中router与route区别

    1.$route对象 $route对象表示当前的路由信息,包含了当前 URL 解析得到的信息.包含当前的路径,参数,query对象等. 1.    $route.path      字符串,对应当前路 ...

  2. Swift数组

    数组的介绍 数组(Array)是一串有序的由相同类型元素构成的集合 数组中的集合元素是有序的,可以重复出现 Swift中的数组 swift数组类型是Array,是一个泛型集合 数组的初始化 数组分成: ...

  3. Java线程--BlockingQueue使用

    原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11871704.html Java线程--BlockingQueue使用 阻塞队列就是内容满了之 ...

  4. @property修饰符

    @property修饰符 修饰是否生成getter方法的 readonly 只生成setter方法,不生成getter方法 readwrite 既生成getter 又生成setter方法(默认) @p ...

  5. Java中stream的详细用法

    来自于:Java 8 stream的详细用法_旅行者-CSDN博客_java stream 一.概述 Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行 ...

  6. 对比redis的RDB、AOF模式的优缺点

    一.RDB模式 1.1 工作原理 RDB(Redis DataBase):基于时间的快照,其默认只保留当前最新的一次快照,特点是执行速度比较快,缺点是可 能会丢失从上次快照到当前时间点之间未做快照的数 ...

  7. 神奇小证明之——世界上只有5个正多面体+构造x3=2a3

    今天我彻底放飞自我了...作业还没写完...但就是要总结一些好玩的小性质...谁给我的勇气呢?

  8. Anacanda 与 jupyter 的使用

    内容概要 爬虫开发环境搭建 Anacanda 开发环境 jupyter jupyter 的基本使用 启动 基本使用 快捷键的使用 内容详细 一.爬虫开发环境搭建 1.Anacanda 开发环境 Ana ...

  9. Java并发杂谈(一):volatile的底层原理,从字节码到CPU

    volatile的特性 volatile是Java中用于修饰变量的关键字,其主要是保证了该变量的可见性以及顺序性,但是没有保证原子性:其是Java中最为轻量级的同步关键字: 接下来我将会一步步来分析v ...

  10. 数据分析用这样的报表工具,秒杀Excel!

    报表工具是为满足公司对报表数据的业务需求,弥补第三方报表平台给项目开发定制报表的工作而自主研发的一个通用性强易于维护的web报表工具. 报表工具以NPOI基础架构,通过公司的REAP开发框架运用到所有 ...