这几年做哪些网站能致富,中国室内设计大赛官网,wordpress文章后面评论,做网站需要网页嵌套吗一、商品秒杀涉及的知识点
鉴权策略封装掊口访问频次限制小程序设计页面防抖接口调用订单创建事务使用超卖防御
二、订单库存系统方案#xff08;3种#xff09; 下单减库存 优点是库存和订单的强一致性#xff0c;商品不会卖超#xff0c;但是可能导致恶意下单#xff…一、商品秒杀涉及的知识点
鉴权策略封装掊口访问频次限制小程序设计页面防抖接口调用订单创建事务使用超卖防御
二、订单库存系统方案3种 下单减库存 优点是库存和订单的强一致性商品不会卖超但是可能导致恶意下单影响正常流程支付减库存 优点是避免恶意下单支付和库存强一致性但是可能出现订单无法支付商品库存不足等问题。预扣库存 预扣库存是指用户请求之后预扣库存生成订单在时效内支付否则订单失效库存还原代码itshujia.com 或者wx搜《IT书架》 回复秒杀
三、小程序秒杀页面
商品秒杀详情页面页面该商品秒杀时间未到则上方进行提醒秒杀商品倒计时并且立即抢购禁用按钮置灰 商品秒杀时间开始则把立即秒杀按钮禁用状态改为可以点击点击立即秒杀按钮要考虑页面防抖不能重复在同一秒中重复发起N次网络请求
四、小程序部分代码展示
小程序wxml代码
view商品秒杀页面/view
l-countdown time-typesecond time{{expire_time}} bind:linendchangeBtn /
l-card typeprimary full{{true}} image{{goods.goods.goods_image}} title{{goods.goods.goods_name}}view价格{{goods.goods.goods_price}}/viewview!-- button disabledtrue bindtapbuyGoods 抢购/button --l-button disabled{{ btn_disable }} bind:lintapbuyGoods typeerror data-goods_id{{ goods.goods.id }}立即秒杀/l-button/view/l-card小程序js代码
// pages/goods_detail/goods_detail.js
import {debounce
} from ../../utils/utilPage({/*** 页面的初始数据*/data: {goods:{},expire_time:0,btn_disable:false},/*** 生命周期函数--监听页面加载*/onLoad: function (e) {//商品idlet 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_idgoods_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_idvar 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})}
})小程序json代码引入的自定义组件
{usingComponents: {l-card:/miniprogram_npm/lin-ui/card,l-button:/miniprogram_npm/lin-ui/button,l-countdown:/miniprogram_npm/lin-ui/countdown}
}五、后台业务逻辑
要考虑订单超卖这次代码使用的redis队列实现的
?phpnamespace 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 ($i0; $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();}}
}