|
|
<?php
|
|
|
|
|
|
namespace App\Admin\Controllers;
|
|
|
|
|
|
use App\Http\Controllers\Controller; // 引入控制器基类
|
|
|
use App\Http\Requests\StoreSeckillRequest; // 引入秒杀请求验证类
|
|
|
use App\Models\Category; // 引入分类模型
|
|
|
use App\Models\Product; // 引入商品模型
|
|
|
use App\Models\Seckill; // 引入秒杀模型
|
|
|
use Carbon\Carbon; // 引入日期时间处理库
|
|
|
use Encore\Admin\Controllers\HasResourceActions; // 引入资源操作特性
|
|
|
use Encore\Admin\Form; // 引入表单构建器
|
|
|
use Encore\Admin\Grid; // 引入网格构建器
|
|
|
use Encore\Admin\Layout\Content; // 引入内容布局
|
|
|
use Illuminate\Http\Request; // 引入请求处理
|
|
|
use Illuminate\Support\Facades\DB; // 引入数据库操作
|
|
|
use Illuminate\Support\Facades\Redis; // 引入 Redis 操作
|
|
|
|
|
|
class SeckillController extends Controller
|
|
|
{
|
|
|
use HasResourceActions; // 使用资源操作特性,提供 CRUD 操作
|
|
|
|
|
|
/**
|
|
|
* 列表界面.
|
|
|
*
|
|
|
* @param Content $content
|
|
|
* @return Content
|
|
|
*/
|
|
|
public function index(Content $content)
|
|
|
{
|
|
|
return $content
|
|
|
->header('秒杀列表') // 设置页面标题
|
|
|
->description('') // 设置页面描述
|
|
|
->body($this->grid()); // 设置页面主体为网格
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 创建界面.
|
|
|
*
|
|
|
* @param Content $content
|
|
|
* @return Content
|
|
|
*/
|
|
|
public function create(Content $content)
|
|
|
{
|
|
|
return $content
|
|
|
->header('新建秒杀') // 设置页面标题
|
|
|
->description('') // 设置页面描述
|
|
|
->body($this->form()); // 设置页面主体为创建表单
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 创建网格构建器.
|
|
|
*
|
|
|
* @return Grid
|
|
|
*/
|
|
|
protected function grid()
|
|
|
{
|
|
|
$grid = new Grid(new Seckill); // 创建新的网格实例,基于 Seckill 模型
|
|
|
|
|
|
$grid->model()->latest(); // 按照创建时间降序排列数据
|
|
|
|
|
|
// 定义网格的列
|
|
|
$grid->column('id'); // 显示秒杀 ID
|
|
|
|
|
|
$grid->column('product.id', '商品ID'); // 显示商品 ID
|
|
|
$grid->column('product.name', '商品名字')->display(function ($name) {
|
|
|
// 显示商品名字,限制显示长度为30个字符
|
|
|
return str_limit($name, 30);
|
|
|
});
|
|
|
$grid->column('product.thumb', '商品图')->display(function ($thumb) {
|
|
|
// 显示商品缩略图
|
|
|
return image($thumb);
|
|
|
});
|
|
|
|
|
|
$grid->column('price', '秒杀价'); // 显示秒杀价格
|
|
|
$grid->column('number', '秒杀数量'); // 显示秒杀数量
|
|
|
$grid->column('start_at', '开始时间'); // 显示开始时间
|
|
|
$grid->column('end_at', '结束时间'); // 显示结束时间
|
|
|
$grid->column('rollback_count', '回滚量'); // 显示回滚量
|
|
|
$grid->column('is_rollback', '是否回滚数量')->display(function ($is) {
|
|
|
// 显示是否回滚数量
|
|
|
return $is ? '是' : '否';
|
|
|
});
|
|
|
$grid->column('created_at', '创建时间'); // 显示创建时间
|
|
|
$grid->column('updated_at', '修改时间'); // 显示修改时间
|
|
|
|
|
|
// 定义行操作
|
|
|
$grid->actions(function (Grid\Displayers\Actions $actions) {
|
|
|
$actions->disableView(); // 禁用查看按钮
|
|
|
$actions->disableEdit(); // 禁用编辑按钮
|
|
|
});
|
|
|
|
|
|
return $grid; // 返回构建好的网格
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 创建表单构建器.
|
|
|
*
|
|
|
* @return Form
|
|
|
*/
|
|
|
protected function form()
|
|
|
{
|
|
|
$form = new Form(new Seckill); // 创建新的表单实例,基于 Seckill 模型
|
|
|
|
|
|
// 获取所有分类
|
|
|
$categories = Category::selectOrderAll();
|
|
|
// 选择分类,加载商品
|
|
|
$form->select('category_id', '分类')
|
|
|
->options($categories)
|
|
|
->load('product_id', admin_url('api/products')); // 根据分类动态加载商品
|
|
|
|
|
|
$form->select('product_id', '秒杀商品'); // 选择秒杀商品
|
|
|
|
|
|
$form->number('price', '秒杀价') // 输入秒杀价
|
|
|
->default(1); // 默认值为1
|
|
|
$form->number('number', '秒杀数量') // 输入秒杀数量
|
|
|
->default(1) // 默认值为1
|
|
|
->help('保证商品的库存数量大于此数量,会从库存中减去'); // 提示用户
|
|
|
|
|
|
$now = Carbon::now(); // 获取当前时间
|
|
|
$form->datetime('start_at', '开始时间') // 输入开始时间
|
|
|
->default($now->format('Y-m-d H:00:00')); // 默认值为当前时间整点
|
|
|
$form->datetime('end_at', '结束时间') // 输入结束时间
|
|
|
->default($now->addHour(2)->format('Y-m-d H:00:00')) // 默认值为当前时间后2小时
|
|
|
->rules('required|date|after_or_equal:start_at'); // 验证规则
|
|
|
|
|
|
return $form; // 返回构建好的表单
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 存储秒杀信息.
|
|
|
*
|
|
|
* @param Request $request
|
|
|
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
|
|
* @throws \Exception
|
|
|
*/
|
|
|
public function store(Request $request)
|
|
|
{
|
|
|
$number = $request->input('number', 0); // 获取秒杀数量
|
|
|
$product = Product::query()->findOrFail($request->input('product_id')); // 查找商品
|
|
|
|
|
|
// 验证秒杀数量不能大于库存数量
|
|
|
if ($number > $product->count) {
|
|
|
return back()->withInput()->withErrors(['number' => '秒杀数量不能大于库存数量']);
|
|
|
}
|
|
|
|
|
|
DB::beginTransaction(); // 开始数据库事务
|
|
|
|
|
|
try {
|
|
|
// 获取请求中的相关属性
|
|
|
$attributes = $request->only(['category_id', 'product_id', 'price', 'number', 'start_at', 'end_at']);
|
|
|
Seckill::create($attributes); // 创建新的秒杀记录
|
|
|
|
|
|
// 减去库存数量
|
|
|
$product->decrement('count', $number); // 从商品库存中减去秒杀数量
|
|
|
|
|
|
} catch (\Error $e) {
|
|
|
DB::rollBack(); // 回滚事务
|
|
|
return back()->withInput()->withErrors(['category_id' => $e->getMessage()]); // 返回错误信息
|
|
|
}
|
|
|
|
|
|
DB::commit(); // 提交事务
|
|
|
|
|
|
admin_toastr('添加成功'); // 显示成功消息
|
|
|
return back(); // 返回上一个页面
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 从存储中删除指定资源.
|
|
|
*
|
|
|
* @param int $id
|
|
|
* @return \Illuminate\Http\Response
|
|
|
* @throws \Exception
|
|
|
*/
|
|
|
public function destroy($id)
|
|
|
{
|
|
|
/**
|
|
|
* @var $seckill Seckill
|
|
|
* @var $product Product
|
|
|
*/
|
|
|
$seckill = Seckill::query()->findOrFail($id); // 查找指定 ID 的秒杀记录
|
|
|
|
|
|
// 获取当前时间和秒杀的开始和结束时间
|
|
|
$now = Carbon::now();
|
|
|
$startTime = Carbon::make($seckill->start_at);
|
|
|
$endTime = Carbon::make($seckill->end_at);
|
|
|
|
|
|
// 如果正处于抢购的时间,不允许删除
|
|
|
if ($now->gte($startTime) && $now->lte($endTime)) {
|
|
|
return response()->json([
|
|
|
'status' => false,
|
|
|
'message' => '秒杀已经开始,不能删除', // 返回错误信息
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
DB::beginTransaction(); // 开始数据库事务
|
|
|
|
|
|
try {
|
|
|
// 删除 Redis 中的秒杀数据
|
|
|
\Redis::connection()->del([$seckill->getRedisModelKey(), $seckill->getRedisQueueKey()]);
|
|
|
|
|
|
$seckill->delete(); // 删除秒杀记录
|
|
|
|
|
|
$data = [
|
|
|
'status' => true,
|
|
|
'message' => trans('admin.delete_succeeded'), // 返回成功信息
|
|
|
];
|
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
$data = [
|
|
|
'status' => false,
|
|
|
'message' => trans('admin.delete_failed'), // 返回失败信息
|
|
|
];
|
|
|
DB::rollBack(); // 回滚事务
|
|
|
}
|
|
|
|
|
|
DB::commit(); // 提交事务
|
|
|
return response()->json($data); // 返回 JSON 响应
|
|
|
}
|
|
|
}
|