error('文件未找到:' . $filePath); return 1; } $this->info('开始读取 Excel 文件...'); try { // 读取 Excel 文件 $data = Excel::toArray([], $filePath); if (empty($data) || empty($data[0])) { $this->error('Excel 文件为空或格式不正确'); return 1; } $rows = $data[0]; $headerRow = array_shift($rows); // 移除表头行 // 查找"流水号"列的索引 $serialIndex = array_search('流水号', $headerRow); if ($serialIndex === false) { $this->error('未找到"流水号"列'); return 1; } $this->info('找到 ' . count($rows) . ' 行数据'); $this->info('开始处理订单项...'); $successCount = 0; $errorCount = 0; $notFoundCount = 0; $totalRows = count($rows); DB::beginTransaction(); try { foreach ($rows as $index => $row) { $rowNumber = $index + 2; // Excel 行号(从2开始,因为第1行是表头) // 获取流水号(订单项ID) $orderItemId = $row[$serialIndex] ?? null; if (empty($orderItemId)) { $this->warn("第 {$rowNumber} 行:流水号为空,跳过"); $errorCount++; continue; } // 转换为整数 $orderItemId = (int) $orderItemId; // 查找订单项,并预先加载必要的关系 $orderItem = OrderItems::with(['order', 'product'])->find($orderItemId); if (!$orderItem) { $this->warn("第 {$rowNumber} 行:未找到 ID 为 {$orderItemId} 的订单项,跳过"); $notFoundCount++; continue; } // 解析 factors JSON $factors = json_decode($orderItem->factors, true); if (!$factors || !is_array($factors)) { $this->warn("第 {$rowNumber} 行:订单项 ID {$orderItemId} 的 factors 数据格式不正确,跳过"); $errorCount++; continue; } // 查找并更新管理费比例 $updated = false; foreach ($factors as &$factor) { if (!isset($factor['used_for_fee']) || !$factor['used_for_fee']) { continue; } // 直接将 fee_percent 修改为 15 if (isset($factor['fee_percent'])) { $factor['fee_percent'] = 15; $updated = true; } } if (!$updated) { $this->warn("第 {$rowNumber} 行:订单项 ID {$orderItemId} 没有找到用于管理费的因子,跳过"); $errorCount++; continue; } // 更新 factors $orderItem->factors = json_encode($factors); // 重新计算管理费 $orderItem->calculateFee(); // 移除非数据库字段(factor_texts 是动态属性,不是数据库字段) unset($orderItem->factor_texts); // 保存更新 $orderItem->save(); $successCount++; if ($successCount % 10 == 0) { $this->info("已处理 {$successCount} 条订单项..."); } } DB::commit(); $this->info(''); $this->info('处理完成!'); $this->info("成功:{$successCount} 条"); $this->info("未找到:{$notFoundCount} 条"); $this->info("错误/跳过:{$errorCount} 条"); $this->info("总计:{$totalRows} 行"); return 0; } catch (\Exception $e) { DB::rollBack(); $this->error('处理过程中发生错误:' . $e->getMessage()); $this->error('错误位置:' . $e->getFile() . ':' . $e->getLine()); return 1; } } catch (\Exception $e) { $this->error('读取 Excel 文件时发生错误:' . $e->getMessage()); return 1; } } }