1. 安装Composer(PHP依赖管理工具),执行官方校验后的命令:
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');";
php -r "if (hash_file('sha384', 'composer-setup.php') === 'e21205b207c3ff031996cf357fc1925d505d0a9420e37a4e20b68458103368597633451b32140b5b8a9867012486f945') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php'); sudo mv composer.phar /usr/local/bin/composer
2. 创建Laravel项目(零门槛框架,直接复用代码),执行:
composer create-project laravel/laravel mall-predeposit 10.
3. 配置数据库:修改项目根目录的.env文件,替换为本地数据库参数(必须填写真实信息):
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=你的数据库名
DB_USERNAME=你的数据库用户名
DB_PASSWORD=你的数据库密码
4. 安装Redis依赖(用于防止预售超卖),执行:
composer require predis/predis
直接执行以下SQL,无需修改表结构,一键完成扩展:
CREATE TABLE `products` (
`id` int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` varchar(255) NOT NULL,
`price` decimal(10,2) NOT NULL,
`stock` int unsigned NOT NULL DEFAULT '0',
`is_pre_sale` tinyint(1) NOT NULL DEFAULT '0',
`pre_sale_start` datetime DEFAULT NULL,
`pre_sale_end` datetime DEFAULT NULL,
`pre_sale_stock` int unsigned NOT NULL DEFAULT '0',
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
执行以下SQL,为订单表添加预售相关属性:
ALTER TABLE `orders` ADD `is_pre_sale` tinyint(1) NOT NULL DEFAULT '0' AFTER `total_amount`, ADD `pay_deadline` datetime DEFAULT NULL AFTER `is_pre_sale`;
修改app/Http/Controllers/ProductController.php的index方法,添加预售时间校验逻辑,直接替换原有方法:
public function index()
{
$products = \App\Models\Product::select('id', 'name', 'price', 'stock', 'is_pre_sale', 'pre_sale_start', 'pre_sale_end', 'pre_sale_stock')
->get()
->map(function ($product) {
if ($product->is_pre_sale && now()->between($product->pre_sale_start, $product->pre_sale_end)) {
$product->is_available = true;
$product->current_stock = $product->pre_sale_stock;
} else {
$product->is_available = $product->stock > 0;
$product->current_stock = $product->stock;
}
return $product;
});
return response()->json($products);
}
前端渲染时,若is_pre_sale为true,显示【预售中】红色标签。

修改app/Http/Controllers/OrderController.php的store方法,添加预售时间拦截、库存校验及Redis锁(防止超卖),核心代码如下:
public function store(Request $request)
{
$validated = $request->validate([
'product_id' => 'required|exists:products,id',
'quantity' => 'required|integer|min:1',
]);
$product = \App\Models\Product::findOrFail($validated['product_id']);
// 【重点】预售商品专属校验
if ($product->is_pre_sale) {
if (!now()->between($product->pre_sale_start, $product->pre_sale_end)) {
return response()->json(['message' => '商品未开启预售'], 400);
}
$availableStock = $product->pre_sale_stock;
} else {
$availableStock = $product->stock;
}
if ($validated['quantity'] > $availableStock) {
return response()->json(['message' => '库存不足'], 400);
}
// 【重点】Redis锁锁定库存,防止超卖(锁15分钟,对应付款截止时间)
$redis = new \Redis();
$redis->connect('127.0.0.1', 6379);
$lockKey = "pre_sale_lock:{$product->id}";
if (!$redis->set($lockKey, $validated['quantity'], ['NX', 'EX' => 900])) {
return response()->json(['message' => '下单频繁,请15分钟后重试'], 400);
}
// 创建订单,标记预售属性
$order = \App\Models\Order::create([
'user_id' => auth()->id(),
'product_id' => $product->id,
'quantity' => $validated['quantity'],
'total_amount' => $product->price $validated['quantity'],
'is_pre_sale' => $product->is_pre_sale,
'pay_deadline' => $product->is_pre_sale ? now()->addMinutes(15) : null,
]);
// 释放Redis锁
$redis->del($lockKey);
return response()->json(['order_id' => $order->id], 201);
}
用Laravel队列处理超时订单,执行以下命令启动队列:
php artisan queue:work --daemon --tries=3
创建库存回滚任务,执行命令:
php artisan make:job ReleasePreSaleStock
在生成的任务类app/Jobs/ReleasePreSaleStock.php的handle方法中添加逻辑:查询15分钟内未付款的预售订单,恢复对应库存,无需修改其他文件。
1. 后台测试:访问商品管理,创建预售商品,设置预售时间(当前时间前后各10分钟)、预售库存为10;
2. 前端下单:访问商品列表,点击预售商品,下单1个,检查订单的「预售标记」及「15分钟付款截止时间」;
3. 超卖测试:用ab压测工具模拟100个用户同时下单,执行命令(需提前准备post_data.txt,内容为product_id=1&quantity=1):
ab -n 100 -c 10 -p post_data.txt -T application/x-www-form-urlencoded http://你的域名/api/orders
验证最终订单数≤10,无超卖;
4. 上线配置:修改Nginx/Apache允许API访问,执行php artisan config:cache清除配置缓存,用supervisor守护队列进程(保证任务自动运行)。
易频IT社区是综合性互联网IT技术门户网站,专注分享网络技术、服务器运维、网络安全、编程开发、系统架构、云计算、大数据等行业干货,实时更新IT行业资讯、零基础教程、实战案例,为IT从业者、技术爱好者提供专业的学习交流平台。
Copyright © 2021-2026 易频IT社区. All Rights Reserved. 备案号:闽ICP备2023013482号 网站地图