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

Laravel关联对象中带$符号的qty字符串转为整数的实现方法

解决方案

你之前的尝试失败是因为with()预加载是独立的关联查询,主表OpenorderImportTemp的查询阶段并不会关联shipment对应的数据表,所以直接在主查询的DB::raw里引用shipment.qty无法获取到对应字段,自然没法完成求和。以下是3种可行方案:

方案1:在Shipment模型中定义访问器(推荐,全局生效)

该方案属于Laravel最佳实践,定义一次后所有获取qty字段的场景都会自动转换为数值类型,无需修改其他业务代码。
在你的Shipment模型中添加如下代码:

// Laravel 9+ 写法
use Illuminate\Database\Eloquent\Casts\Attribute;

protected function qty(): Attribute
{
    return Attribute::make(
        get: function ($value) {
            // 移除$符号和千分位逗号后转整数
            $cleanValue = str_replace(['$', ','], '', $value);
            return (int) $cleanValue;
        }
    );
}

// Laravel 8及更早版本写法
public function getQtyAttribute($value)
{
    $cleanValue = str_replace(['$', ','], '', $value);
    return (int) $cleanValue;
}

添加后你原本的查询代码不需要任何修改,返回的shipment->qty就已经是整数类型,可直接用于求和计算。

方案2:查询后通过集合处理(适合临时单次场景)

如果不想修改模型,仅需要在当前接口处理该字段,可以在拿到查询结果后调用集合的map方法遍历处理:

$openorder_data = OpenorderImportTemp::select('id', 'controlNumber', 'ItemNumber')
    ->with('shipment:id,Item,ColorCode,qty')
    ->orderBy('id', 'desc')
    ->where('ControlNumber', '!=', '0')
    ->get()
    ->map(function ($item) {
        if ($item->shipment) {
            $cleanQty = str_replace(['$', ','], '', $item->shipment->qty);
            $item->shipment->qty = (int) $cleanQty;
            // 可按需把求和值挂到主对象上
            $item->qtysum = (int) $cleanQty;
        }
        return $item;
    });

如果需要按controlNumber分组求和,直接调用集合内置方法即可:

$groupedSum = $openorder_data->groupBy('controlNumber')
    ->map(fn($group) => $group->sum('shipment.qty'));

方案3:SQL层面直接求和(适用于大数据量场景)

如果数据量较大,不想把全量数据查出来再计算,可以把预加载改为join关联,在SQL层处理字段格式后直接求和:

$openorder_data = OpenorderImportTemp::select(
        'id', 
        'controlNumber', 
        'ItemNumber',
        DB::raw("SUM(CAST(REPLACE(REPLACE(shipments.qty, '$', ''), ',', '') AS UNSIGNED)) as qtysum")
    )
    ->join('shipments', 'shipments.Item', '=', 'openorder_import_temps.ItemNumber')
    ->orderBy('id', 'desc')
    ->where('ControlNumber', '!=', '0')
    ->groupBy('controlNumber') // 需分组求和时放开该行
    ->get();

注意把上述代码中的shipments、openorder_import_temps替换为你实际对应的表名即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 04:06:02