You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Nova中创建发票创建视图资源的技术指导请求

实现Nova 4中Invoice资源的动态发票项功能

1. 前置准备(若未完成)

如果还没有创建发票项模型,先执行以下命令生成模型和迁移文件:

php artisan make:model InvoiceItem -m

在InvoiceItem的迁移文件中添加字段(示例):

Schema::create('invoice_items', function (Blueprint $table) {
    $table->id();
    $table->foreignId('invoice_id')->constrained()->cascadeOnDelete();
    $table->foreignId('product_id')->constrained();
    $table->integer('quantity');
    $table->decimal('unit_price', 10, 2);
    $table->timestamps();
});

执行迁移:

php artisan migrate

2. 生成Nova资源

生成Invoice和InvoiceItem对应的Nova资源:

php artisan nova:resource Invoice
php artisan nova:resource InvoiceItem

3. 配置Invoice资源核心字段

在app/Nova/Invoice.php中配置基础字段和动态发票项关联:

use Laravel\Nova\Fields\BelongsTo;
use Laravel\Nova\Fields\Date;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Number;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Http\Requests\NovaRequest;

class Invoice extends Resource
{
    public static $model = \App\Models\Invoice::class;
    public static $title = 'invoice_number';
    public static $search = ['invoice_number', 'user.name'];

    public function fields(NovaRequest $request)
    {
        return [
            ID::make()->sortable(),

            // 关联客户User模型
            BelongsTo::make('客户', 'user', \App\Nova\User::class)
                ->rules('required'),

            // 发票基础信息
            Text::make('发票编号', 'invoice_number')
                ->rules('required', 'unique:invoices'),

            Date::make('发票日期', 'invoice_date')
                ->rules('required'),

            // 动态添加发票项核心配置
            \Laravel\Nova\Fields\HasMany::make('发票项', 'invoiceItems', \App\Nova\InvoiceItem::class)
                ->inlineCreate(function (NovaRequest $request, $parentResource) {
                    // 自定义弹窗内的创建字段
                    return [
                        BelongsTo::make('商品', 'product', \App\Nova\Product::class)
                            ->rules('required'),
                        Number::make('数量', 'quantity')
                            ->rules('required', 'integer', 'min:1'),
                        Number::make('单价', 'unit_price')
                            ->rules('required', 'numeric', 'min:0.01')
                            ->currency('CNY'),
                    ];
                })
                ->inlineEdit() // 支持在详情页直接编辑发票项
                ->sortable(),

            // 动态计算总金额(仅在详情页显示)
            Number::make('总金额', function () {
                return $this->invoiceItems->sum(fn($item) => $item->quantity * $item->unit_price);
            })->onlyOnDetail()->currency('CNY'),
        ];
    }
}

4. 配置InvoiceItem资源(可选)

若需要独立管理发票项,在app/Nova/InvoiceItem.php中配置字段:

use Laravel\Nova\Fields\BelongsTo;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Number;
use Laravel\Nova\Http\Requests\NovaRequest;

class InvoiceItem extends Resource
{
    public static $model = \App\Models\InvoiceItem::class;
    public static $title = 'id';
    public static $search = ['invoice.invoice_number', 'product.name'];

    public function fields(NovaRequest $request)
    {
        return [
            ID::make()->sortable(),

            BelongsTo::make('发票', 'invoice', \App\Nova\Invoice::class)
                ->rules('required'),

            BelongsTo::make('商品', 'product', \App\Nova\Product::class)
                ->rules('required'),

            Number::make('数量', 'quantity')
                ->rules('required', 'integer', 'min:1'),

            Number::make('单价', 'unit_price')
                ->rules('required', 'numeric', 'min:0.01')
                ->currency('CNY'),

            // 动态计算小计
            Number::make('小计', function () {
                return $this->quantity * $this->unit_price;
            })->currency('CNY'),
        ];
    }
}

5. 关键验证与说明

  • 确保模型关联正确:Invoice模型需定义public function invoiceItems() { return $this->hasMany(InvoiceItem::class); };InvoiceItem模型需定义public function invoice() { return $this->belongsTo(Invoice::class); }和public function product() { return $this->belongsTo(Product::class); }。
  • inlineCreate实现了在创建Invoice页面直接弹窗添加发票项,无需跳转;inlineEdit支持在详情页快速编辑已有项。
  • 所有字段添加了验证规则,保障数据合法性。

额外优化建议

  • 给发票编号添加自动生成逻辑:在Invoice模型的creating事件中生成唯一编号,避免手动输入。
  • 若需要前端实时计算小计,可自定义Nova字段实现(Nova官方暂不支持原生实时计算)。
  • 添加发票状态字段(如「已开票」「已支付」),用Select字段实现状态切换。

内容的提问来源于stack exchange,提问作者Aseef Ahmed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 06:21:03