本文目录导读:

在 Laravel Nova 中实现动作的批量操作,可以通过以下步骤来完成:
创建自定义动作
创建一个 Nova 动作:
php artisan nova:action UpdateStatus
定义动作类
<?php
namespace App\Nova\Actions;
use Illuminate\Bus\Queueable;
use Laravel\Nova\Actions\Action;
use Illuminate\Support\Collection;
use Laravel\Nova\Fields\ActionFields;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Laravel\Nova\Fields\Select;
use Laravel\Nova\Fields\Text;
class UpdateStatus extends Action
{
use InteractsWithQueue, Queueable, SerializesModels;
public $name = '更新状态';
/**
* 执行动作
*/
public function handle(ActionFields $fields, Collection $models)
{
// 处理选中的多个模型
foreach ($models as $model) {
// 批量更新状态
$model->update([
'status' => $fields->status
]);
}
return Action::message('状态更新成功!');
}
/**
* 定义动作的字段
*/
public function fields()
{
return [
Select::make('状态', 'status')
->options([
'active' => '启用',
'inactive' => '禁用',
'pending' => '待审核',
])
->rules('required'),
];
}
}
在资源中注册动作
<?php
namespace App\Nova;
use App\Nova\Actions\UpdateStatus;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Resource;
class User extends Resource
{
public static $model = \App\Models\User::class;
public function actions(Request $request)
{
return [
(new UpdateStatus)
->canSee(fn ($request) => $request->user()->hasPermissionTo('update-status'))
->canRun(fn ($request, $user) => $request->user()->hasPermissionTo('update-status')),
(new SendEmail)
->onlyOnDetail(), // 只在详情页显示
(new ExportUsers)
->exceptOnIndex(), // 不在列表页显示
(new DeleteUsers)
->canRun(function ($request, $user) {
return $request->user()->isAdmin();
})
->confirmText('确定要删除选中的用户吗?')
->confirmButtonText('删除')
->cancelButtonText('取消'),
];
}
}
动作的高级配置
批量操作与队列
<?php
namespace App\Nova\Actions;
use Illuminate\Bus\Queueable;
use Laravel\Nova\Actions\Action;
use Illuminate\Support\Collection;
use Laravel\Nova\Fields\ActionFields;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
class ProcessLargeData extends Action
{
use InteractsWithQueue, Queueable, SerializesModels;
public $timeout = 120; // 超时时间(秒)
public $tries = 3; // 重试次数
public function handle(ActionFields $fields, Collection $models)
{
foreach ($models as $model) {
// 处理大量数据时,可以使用队列
dispatch(new ProcessModelJob($model));
}
return Action::message('数据已在后台处理中');
}
public function fields()
{
return [];
}
// 使动作可以在队列中运行
public function shouldQueue(ActionFields $fields, Collection $models)
{
return count($models) > 10; // 当模型数量大于10时使用队列
}
}
前端批量操作配置
在资源中启用批量操作
public function actions(Request $request)
{
return [
(new UpdateStatus)
->sole() // 只能选择单个记录时使用
->showOnIndex() // 在索引页显示
->showOnDetail() // 在详情页显示
->showOnCreation() // 在创建页显示
->confirmText('确定要执行此操作吗?')
->confirmButtonText('确认执行')
->cancelButtonText('取消'),
];
}
自定义按钮行为
<?php
namespace App\Nova\Actions;
class ExportData extends Action
{
public function handle(ActionFields $fields, Collection $models)
{
// 导出选中数据
$selectedIds = $models->pluck('id')->toArray();
// 导出处理逻辑
$exportUrl = route('export.data', ['ids' => implode(',', $selectedIds)]);
return Action::redirect($exportUrl);
}
public function fields()
{
return [
Text::make('导出文件名', 'filename')
->default('export_' . date('Ymd_His')),
];
}
}
权限控制示例
public function actions(Request $request)
{
return [
(new UpdateStatus)
->canSee(function ($request) {
return $request->user()->isAdmin() || $request->user()->role === 'manager';
})
->canRun(function ($request, $user) {
return $request->user()->isAdmin() ||
($request->user()->role === 'manager' && $user->department_id === $request->user()->department_id);
}),
];
}
前端模板中的按钮
在资源的 index 或 detail 视图中:
{{-- 在资源索引表格中 --}}
<div class="flex items-center">
<input type="checkbox" class="action-select-all">
<button @click="selectedResources.length > 0" class="btn btn-primary">
批量操作
</button>
</div>
常见问题处理
处理大量数据
public function handle(ActionFields $fields, Collection $models)
{
if ($models->count() > 50) {
// 批量处理时限制数量
return Action::danger('每次最多只能处理50条记录');
}
// 使用 chunk 分批处理
$models->chunk(100)->each(function ($chunk) {
foreach ($chunk as $model) {
// 处理逻辑
}
});
}
记录操作日志
public function handle(ActionFields $fields, Collection $models)
{
$user = auth()->user();
foreach ($models as $model) {
ActivityLog::create([
'user_id' => $user->id,
'action' => 'bulk_update',
'model_type' => get_class($model),
'model_id' => $model->id,
'changes' => json_encode($fields->toArray()),
]);
}
}
这样,你就可以在 Laravel Nova 中实现强大的批量操作功能了,记得在 NovaServiceProvider 或资源模型中注册这些动作。