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

Filament关联管理器中Livewire数据损坏错误排查求助

问题

在Filament关联管理器中实现了如下表单,希望根据选中的费用字段动态更新价格、子价格及总计字段:

Select::make('fees_description')
    ->label('الرسوم')
    ->preload()
    ->multiple()
    ->live()
    ->options(Fee::all()->pluck('name', 'id'))
    ->afterStateUpdated(function (Set $set, Get $get, $state) {
        if (count($state)) {
            $set('price', Fee::findMany($state)->sum('price'));
            $set('sub_price', $this->getOwnerRecord()->addons()->sum('qty') * Fee::where('type', FeeTypeAttribute::MONTHLY->value)->findMany($get('fees_description'))->count());
            $set('total', $get('price') + $this->getOwnerRecord()?->addons()->sum('qty') * Fee::where('type', FeeTypeAttribute::MONTHLY->value)->findMany($state)->count());
        } else {
            $set    ('price', 0);
            $set    ('sub_price', 0);
            $set    ('total', 0);
        }
    }),

但当选择非月度类型的费用时,组件抛出错误:

Livewire encountered corrupt data when trying to hydrate a component. Ensure that the [name, id, data] of the Livewire component wasn't tampered with between requests.
解决方案

问题根源

  • 使用findMany($state)会返回完整的模型集合,而Livewire无法安全序列化包含关联关系、未加载属性的模型对象,触发数据损坏错误。
  • 重复调用$get('fees_description')属于冗余操作,且可能导致状态不一致,加剧序列化异常风险。
  • 未对$this->getOwnerRecord()做空值处理,当父记录不存在时会引发隐性错误。

修复后的代码

Select::make('fees_description')
    ->label('الرسوم')
    ->preload()
    ->multiple()
    ->live()
    ->options(Fee::all()->pluck('name', 'id'))
    ->afterStateUpdated(function (Set $set, Get $get, $state) {
        $ownerRecord = $this->getOwnerRecord();
        $addonsQtySum = $ownerRecord?->addons()->sum('qty') ?? 0;
        
        if (!empty($state)) {
            // 直接在数据库层面计算总价,避免加载完整模型
            $price = Fee::whereIn('id', $state)->sum('price');
            // 统计选中项中月度费用的数量,同样在数据库完成计算
            $monthlyFeeCount = Fee::whereIn('id', $state)
                ->where('type', FeeTypeAttribute::MONTHLY->value)
                ->count();
            
            $subPrice = $addonsQtySum * $monthlyFeeCount;
            $total = $price + $subPrice;
            
            $set('price', $price);
            $set('sub_price', $subPrice);
            $set('total', $total);
        } else {
            $set('price', 0);
            $set('sub_price', 0);
            $set('total', 0);
        }
    }),

优化说明

  • 用whereIn('id', $state)配合sum/count直接在数据库完成计算,避免加载模型集合,彻底解决序列化问题。
  • 提前获取父记录和附加项数量,减少重复数据库查询,提升性能。
  • 给$addonsQtySum加空值兜底,避免父记录不存在时的报错。

内容的提问来源于stack exchange,提问作者Muhammad Essam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 06:41:11