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

Laravel中count()参数错误修复:动态表格多行数据提交问题

错误原因及解决方案

错误根源

错误出现在控制器第826行的count($categoryNames),因为后端期望$categoryNames是一个数组,但前端没有将表格中的多条数据以数组形式提交,反而只传递了单个商品的零散参数,导致$categoryNames为null或非可计数类型,触发count()参数错误。

另外前端代码存在逻辑矛盾:一边维护tableData数组存储表格数据,一边又直接操作DOM添加行,提交时完全没用到tableData,导致后端接收不到批量数据。


前端代码修复(核心修改submitForm函数)

修改submitForm,把tableData中的所有数据作为数组提交,替换原来的单个参数,同时统一用tableData维护数据,避免DOM与数组数据不一致:

function submitForm(event) {
    event.preventDefault();

    // 同步DOM中的编辑内容到tableData(比如可编辑的qty字段)
    $("#itemTableBody tr").each(function(index) {
        if (tableData[index]) {
            tableData[index].qty = parseFloat($(this).find("td:eq(5)").text()) || 1;
            tableData[index].netAmount = tableData[index].costPrice * tableData[index].qty;
        }
    });

    var formData = new FormData(document.getElementById('recognitionForm1'));
    // 将整个表格数据转成JSON字符串提交
    formData.append('tableData', JSON.stringify(tableData));
    // 提交全局参数
    formData.append('pay_method', $("#paymentMode").val());

    $.ajax({
        url: "{{ route('admin-recognition-save') }}",
        method: 'POST',
        headers: {
            'X-CSRF-TOKEN': '{{ csrf_token() }}'
        },
        data: formData,
        processData: false,
        contentType: false,
        success: function(response) {
            showCustomToast(response.message, 'success');
            clearFormFields();
            tableData = [];
            $("#itemTableBody").empty();
            setTimeout(function() {
                location.reload();
            }, 2000);
        },
        error: function(error) {
            showCustomToast('Error saving data. Please try again.', 'error');
        }
    });

    updateCalculations();
}

同时修改addRowToTable,加入商品ID到rowData,方便后端关联:

function addRowToTable() {
    var rowData = {
        itemId: $("#items").val(), // 新增:保存商品ID
        categoryName: $("#category option:selected").text(),
        itemName: $("#items option:selected").text(),
        costPrice: parseFloat($("#items option:selected").data('cost-price')) || 0,
        netAmount: parseFloat($("#amount").val()) || 0,
        qty: 1
    };

    tableData.push(rowData);
    // 后续渲染逻辑不变...
}

删除submitForm中原有的添加新行逻辑(由addRowToTable统一负责),并移除重复的removeRow函数,保留基于index的版本并同步DOM与数组:

function removeRow(index) {
    tableData.splice(index, 1);
    updateTable();
    updateCalculations();
    showCustomToast("✓ Data deleted successfully!", "success");
}

后端Laravel控制器修复

接收前端传来的批量数据,解码后循环处理,同时增加参数校验避免错误:

public function saveRecognition(Request $request)
{
    $referenceNumber = "RO-" . str_pad(mt_rand(0, 999), 4, '0', STR_PAD_LEFT);

    // 接收并解码表格数据
    $tableData = json_decode($request->input('tableData'), true);
    
    // 校验数据有效性
    if (!is_array($tableData) || count($tableData) === 0) {
        return response()->json(['message' => 'No valid data to save!'], 400);
    }

    // 循环处理每一行数据
    foreach ($tableData as $row) {
        // 创建库存识别主记录
        $recognitionInfo = new InvRecognitionInfo();
        $recognitionInfo->item_id = $row['itemId'];
        $recognitionInfo->qty = $row['qty'];
        $recognitionInfo->stock_status = 1;
        $recognitionInfo->total_cost = $row['netAmount'];
        $recognitionInfo->item_name = $row['itemName'];
        $recognitionInfo->recognition_no = $referenceNumber;
        $recognitionInfo->active_status = 1;
        $recognitionInfo->save();

        // 创建库存识别明细记录
        $recognitionDetail = new InvRecognitionDetail();
        $recognitionDetail->item_id = $row['itemId'];
        $recognitionDetail->item_name = $row['itemName'];
        $recognitionDetail->sale_price = $row['costPrice'];
        $recognitionDetail->qty = $row['qty'];
        $recognitionDetail->pay_method = $request->input('pay_method');
        $recognitionDetail->recognition_no = $referenceNumber;
        $recognitionDetail->active_status = 1;
        $recognitionDetail->save();
    }

    return response()->json(['message' => 'Data saved successfully!']);
}

额外注意事项

  • 统一数据维护逻辑:所有表格数据变更都通过tableData数组操作,DOM渲染完全依赖tableData,避免数据不一致。
  • 后端可添加Laravel表单验证规则,比如'tableData' => 'required|array',提前拦截非法请求。
  • 前端可优化编辑字段的同步逻辑,比如在用户编辑可编辑单元格时直接更新tableData,无需在提交时统一同步。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 16:17:03