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

223 lines
5.8 KiB

<?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;
class SeckillController extends Controller
{
use HasResourceActions;
/**
* Index interface.
*
* @param Content $content
* @return Content
*/
public function index(Content $content)
{
return $content
->header('秒杀列表')
->description('')
->body($this->grid());
}
/**
* Create interface.
*
* @param Content $content
* @return Content
*/
public function create(Content $content)
{
return $content
->header('新建秒杀')
->description('')
->body($this->form());
}
/**
* Make a grid builder.
*
* @return Grid
*/
protected function grid()
{
$grid = new Grid(new Seckill);
$grid->model()->latest();
$grid->column('id');
$grid->column('product.id', '商品ID');
$grid->column('product.name', '商品名字')->display(function ($name) {
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;
}
/**
* Make a form builder.
*
* @return Form
*/
protected function form()
{
$form = new Form(new 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);
$form->number('number', '秒杀数量')
->default(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'))
->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();
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
* @throws \Exception
*/
public function destroy($id)
{
/**
* @var $seckill Seckill
* @var $product Product
*/
$seckill = Seckill::query()->findOrFail($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' => false,
'message' => trans('admin.delete_succeeded'),
];
} catch (\Exception $e) {
$data = [
'status' => true,
'message' => trans('admin.delete_failed'),
];
DB::rollBack();
}
DB::commit();
return response()->json($data);
}
}