column('id', 'ID')->sortable(); // 关联服务 $grid->column('service.name', '服务名称')->sortable(); $grid->column('service.code', '服务代码'); // 配额类型 $grid->column('type', '配额类型')->display(function ($type) { $quotaType = QUOTA_TYPE::tryFrom($type); if ($quotaType) { $label = $quotaType->getLabel(); $color = $quotaType->getColor(); return "{$label}"; } return $type; }); // 配额限制 $grid->column('limit_value', '配额限制')->display(function ($limit) { return number_format($limit); })->sortable(); // 已使用量 $grid->column('used_value', '已使用')->display(function ($used) { return number_format($used); })->sortable(); // 使用率 $grid->column('usage_percentage', '使用率')->display(function () { $percentage = $this->limit_value > 0 ? ($this->used_value / $this->limit_value) * 100 : 0; $color = 'success'; if ($percentage >= 95) { $color = 'danger'; } elseif ($percentage >= 80) { $color = 'warning'; } elseif ($percentage >= 60) { $color = 'info'; } return "
" . number_format($percentage, 1) . "%
"; }); // 剩余配额 $grid->column('remaining', '剩余配额')->display(function () { $remaining = max(0, $this->limit_value - $this->used_value); $color = $remaining > 0 ? 'text-success' : 'text-danger'; return "" . number_format($remaining) . ""; }); // 时间窗口 $grid->column('window_start', '窗口开始')->display(function ($time) { return $time ? \Carbon\Carbon::parse($time)->format('m-d H:i') : '-'; }); $grid->column('window_end', '窗口结束')->display(function ($time) { return $time ? \Carbon\Carbon::parse($time)->format('m-d H:i') : '-'; }); // 重置时间 $grid->column('reset_at', '下次重置')->display(function ($time) { if (!$time) { return '-'; } $resetTime = \Carbon\Carbon::parse($time); if ($resetTime->isPast()) { return '待重置'; } else { return $resetTime->diffForHumans(); } }); // 告警阈值 $grid->column('alert_threshold', '告警阈值')->display(function ($threshold) { return $threshold . '%'; }); // 状态 $grid->column('is_active', '状态')->display(function ($active) { return $active ? ' 激活' : ' 未激活'; }); // 超限状态 $grid->column('is_exceeded', '超限状态')->display(function ($exceeded) { return $exceeded ? ' 已超限' : ' 正常'; }); // 过滤器 $grid->filter(function (Grid\Filter $filter) { $filter->equal('service_id', '服务')->select( ThirdPartyService::pluck('name', 'id')->toArray() ); $filter->equal('type', '配额类型')->select(QUOTA_TYPE::getOptions()); $filter->equal('is_active', '状态')->select([ 1 => '激活', 0 => '未激活', ]); $filter->equal('is_exceeded', '超限状态')->select([ 1 => '已超限', 0 => '正常', ]); $filter->between('alert_threshold', '告警阈值(%)'); $filter->between('used_value', '已使用量'); }); // 批量操作 $grid->batchActions(function (Grid\Tools\BatchActions $batch) { // TODO: 创建批量操作类 // $batch->add('批量重置', new \App\Module\ThirdParty\AdminActions\BatchResetQuotaAction()); // $batch->add('批量激活', new \App\Module\ThirdParty\AdminActions\BatchActivateQuotaAction()); // $batch->add('批量停用', new \App\Module\ThirdParty\AdminActions\BatchDeactivateQuotaAction()); }); // 工具栏 $grid->tools(function (Grid\Tools $tools) { $tools->append(' 超限配额'); $tools->append(' 重置所有'); $tools->append(' 使用统计'); }); // 行操作 $grid->actions(function (Grid\Displayers\Actions $actions) { $actions->append(' 重置'); if ($actions->row->is_exceeded) { $actions->append(' 增加配额'); } $actions->append(' 使用详情'); }); // 默认排序 $grid->model()->orderBy('service_id')->orderBy('type'); }); } /** * 详情页面 * * @return Show */ protected function detail($id): Show { return Show::make($id, new ThirdPartyQuotaRepository(), function (Show $show) { $show->field('id', 'ID'); $show->field('service.name', '服务名称'); $show->field('service.code', '服务代码'); $show->field('type', '配额类型')->as(function ($type) { $quotaType = QUOTA_TYPE::tryFrom($type); return $quotaType ? $quotaType->getLabel() : $type; }); $show->field('limit_value', '配额限制')->as(function ($limit) { return number_format($limit); }); $show->field('used_value', '已使用量')->as(function ($used) { return number_format($used); }); $show->field('usage_percentage', '使用率')->as(function () { $percentage = $this->limit_value > 0 ? ($this->used_value / $this->limit_value) * 100 : 0; return number_format($percentage, 2) . '%'; }); $show->field('remaining', '剩余配额')->as(function () { $remaining = max(0, $this->limit_value - $this->used_value); return number_format($remaining); }); $show->field('window_start', '时间窗口开始'); $show->field('window_end', '时间窗口结束'); $show->field('reset_at', '下次重置时间'); $show->field('alert_threshold', '告警阈值')->as(function ($threshold) { return $threshold . '%'; }); $show->field('is_active', '状态')->as(function ($active) { return $active ? '激活' : '未激活'; }); $show->field('is_exceeded', '超限状态')->as(function ($exceeded) { return $exceeded ? '已超限' : '正常'; }); $show->field('exceeded_at', '超限时间'); $show->field('created_at', '创建时间'); $show->field('updated_at', '更新时间'); }); } /** * 表单页面 * * @return Form */ protected function form(): Form { return Form::make(new ThirdPartyQuotaRepository(), function (Form $form) { $form->display('id', 'ID'); $form->select('service_id', '所属服务') ->options(ThirdPartyService::pluck('name', 'id')->toArray()) ->required() ->help('选择要配置配额的第三方服务'); $form->select('type', '配额类型') ->options(QUOTA_TYPE::getOptions()) ->required() ->help('选择配额的时间窗口类型'); $form->number('limit_value', '配额限制') ->required() ->min(1) ->help('在指定时间窗口内允许的最大调用次数'); $form->number('alert_threshold', '告警阈值(%)') ->default(80) ->min(1) ->max(100) ->help('当使用率达到此百分比时触发告警'); $form->switch('is_active', '是否激活')->default(1); $form->datetime('window_start', '时间窗口开始')->help('留空自动计算'); $form->datetime('window_end', '时间窗口结束')->help('留空自动计算'); $form->datetime('reset_at', '下次重置时间')->help('留空自动计算'); $form->display('used_value', '已使用量'); $form->display('is_exceeded', '超限状态'); $form->display('exceeded_at', '超限时间'); $form->display('created_at', '创建时间'); $form->display('updated_at', '更新时间'); // 保存前处理 $form->saving(function (Form $form) { // 自动计算时间窗口 if (empty($form->window_start) || empty($form->window_end)) { $quotaType = QUOTA_TYPE::from($form->type); $form->window_start = $quotaType->getCurrentWindowStart()->format('Y-m-d H:i:s'); $form->window_end = $quotaType->getCurrentWindowEnd()->format('Y-m-d H:i:s'); $form->reset_at = $form->window_end; } }); }); } }