You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
aquaculture/app/Admin/Controllers/SeckillController.php

221 lines
7.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?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 响应
}
}