当前位置:网站首页 >  教程

商城预售核心模块实操指南:从0到1落地可复用预售功能

时间:2026年06月01日 07:18:15 来源:易频IT社区

一、前置环境准备

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

二、预售核心数据库表设计

1. 商品表新增预售专属字段

直接执行以下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;

2. 订单表新增预售标记

执行以下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`;

三、核心功能逻辑开发

1. 商品列表显示预售状态

修改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,显示【预售中】红色标签。

2. 预售商品下单核心校验

商城预售核心模块实操指南:从0到1落地可复用预售功能

修改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);
}

3. 未付款预售订单库存自动回滚

用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号 网站地图