> /tmp/alibaba_today_import.log 2>&1 * * 分润设置(写死): * - extension_type: 1(开启分润) * - concession_pri: 售价 × 15%(商家让利金额) * - extension_one: 15(SKU级分润比例) * - plate_mer_profit: 0(平台商户利润) * - commission: 保持原样(不修改) * * 原价计算规则(根据SKU售价阶梯加价): * 1-20元 => 固定加5元 * 21-50元 => 固定加20元 * 51-120元 => 固定加40元 * 121-200元 => 固定加45元 * 201-300元 => 固定加50元 */ class AlibabaTodayImport extends Command { protected function configure() { $this->setName('alibaba:today-import') ->setDescription('从alibaba_import_goods获取今日创建的商品,调用importStore接口正式入库') ->addOption('mer_id', null, \think\console\input\Option::VALUE_OPTIONAL, '商户ID', '3447') ->addOption('date', null, \think\console\input\Option::VALUE_OPTIONAL, '指定日期 (Y-m-d),默认今天', '') ->addOption('batch', null, \think\console\input\Option::VALUE_OPTIONAL, '每批处理数量', '50') ->addOption('skip', null, \think\console\input\Option::VALUE_OPTIONAL, '跳过前N条(断点续传)', '0'); } protected function execute(Input $input, Output $output) { // 解除时间限制 set_time_limit(0); $output->writeln('========================================'); $output->writeln(' 1688今日商品自动入库 开始'); $output->writeln('========================================'); // 1. 解析参数 $merId = (int)$input->getOption('mer_id'); $date = $input->getOption('date'); $batch = (int)$input->getOption('batch'); $skip = (int)$input->getOption('skip'); if ($batch < 1) $batch = 50; if ($skip < 0) $skip = 0; if (empty($date)) { $date = date('Y-m-d'); } // ============================================================ // 分润配置(写死) // ============================================================ $profitConfig = [ 'extension_type' => 1, // 1=开启分润 'concession_rate' => 0.15, // 商家让利比例15%(concession_pri = 售价 × 15%) 'extension_one' => 15, // SKU级分润比例15% ]; $output->writeln("商户ID: {$merId}"); $output->writeln("查询日期: {$date}"); $output->writeln("每批数量: {$batch}"); $output->writeln("跳过前N条: {$skip}"); $output->writeln('分润设置:'); $output->writeln(" extension_type: {$profitConfig['extension_type']} (开启分润)"); $output->writeln(" concession_rate: {$profitConfig['concession_rate']} (售价×{$profitConfig['concession_rate']})"); $output->writeln(" extension_one: {$profitConfig['extension_one']}%"); // 2. 查询今日创建的 alibaba_import_goods 记录(只查ID,不查全字段,节省内存) $todayStart = $date . ' 00:00:00'; $todayEnd = $date . ' 23:59:59'; $output->write('正在查询今日待入库商品... '); $allIds = Db::name('alibaba_import_goods') ->where('status', 1) ->where('create_time', '>=', $todayStart) ->where('create_time', '<=', $todayEnd) ->order('id', 'ASC') ->column('id'); $total = count($allIds); $output->writeln("共 {$total} 条"); if ($total === 0) { $output->writeln("{$date} 没有需要入库的商品"); $output->writeln('========================================'); $output->writeln(' 1688今日商品自动入库 结束 (无商品)'); $output->writeln('========================================'); return; } // 3. 应用 skip 跳过已处理的 if ($skip > 0) { $allIds = array_slice($allIds, $skip); $output->writeln("跳过前 {$skip} 条,剩余 " . count($allIds) . " 条"); } // 4. 分批处理 /** @var ProductService $productService */ $productService = app()->make(ProductService::class); $chunks = array_chunk($allIds, $batch); $totalChunks = count($chunks); $output->writeln("共分 {$totalChunks} 批执行"); $output->writeln(''); $globalSuccess = 0; $globalFail = 0; $globalProfitSet = 0; $startTime = time(); foreach ($chunks as $chunkIndex => $idBatch) { $batchStartTime = time(); $batchNum = $chunkIndex + 1; $processedCount = $skip + ($chunkIndex * $batch) + 1; $output->writeln("--- 第 {$batchNum}/{$totalChunks} 批 (已处理 {$processedCount}/{$total}) ---"); foreach ($idBatch as $importId) { $output->write(" [{$processedCount}/{$total}] import_goods_id={$importId} ... "); try { // 4a. 调用原始入库方法 $result = $productService->importToStoreProduct($importId, $merId); if ($result['code'] === 200) { $productId = $result['product_id']; $globalSuccess++; // 4b. 根据SKU售价阶梯计算原价(ot_price) try { // 获取所有SKU的售价(用 unique 字段唯一标识每个SKU) $skuValues = Db::name('store_product_attr_value') ->where('product_id', $productId) ->field('unique, price') ->select() ->toArray(); $skuPrices = []; $skuOtPrices = []; foreach ($skuValues as $sku) { $salePrice = (float)$sku['price']; $skuPrices[] = $salePrice; // 根据售价区间计算原价 $otPrice = self::calcOtPrice($salePrice); $skuOtPrices[] = $otPrice; // 通过 unique 字段更新当前SKU的 ot_price Db::name('store_product_attr_value') ->where('unique', $sku['unique']) ->update(['ot_price' => $otPrice]); } // 更新 store_product 表的 price(最低售价)和 ot_price(最高原价) $minPrice = !empty($skuPrices) ? min($skuPrices) : 0; $maxOtPrice = !empty($skuOtPrices) ? max($skuOtPrices) : 0; Db::name('store_product') ->where('product_id', $productId) ->update([ 'price' => $minPrice, 'ot_price' => $maxOtPrice, ]); $output->write("[原价已计算] "); } catch (\Throwable $priceE) { $output->write("[原价计算失败: {$priceE->getMessage()}] "); } // 4c. 设置分润(写死15%) try { // 获取商品最低售价 $storeProduct = Db::name('store_product') ->where('product_id', $productId) ->field('price') ->find(); $salePrice = $storeProduct ? (float)$storeProduct['price'] : 0; // 计算 concession_pri = 售价 × 15%,使用 bc 函数保留两位小数 $concessionPri = '0.00'; if ($salePrice > 0) { $concessionPri = bcmul((string)$salePrice, (string)$profitConfig['concession_rate'], 2); } // 更新 store_product 表的分润字段(commission保持原样不修改) Db::name('store_product') ->where('product_id', $productId) ->update([ 'extension_type' => $profitConfig['extension_type'], 'concession_pri' => $concessionPri, ]); // 更新 store_product_attr_value 表的 SKU 分润比例 Db::name('store_product_attr_value') ->where('product_id', $productId) ->update([ 'extension_one' => $profitConfig['extension_one'], ]); $globalProfitSet++; $output->write("[分润15%已设置] "); } catch (\Throwable $profitE) { $output->write("[分润设置失败: {$profitE->getMessage()}] "); } $output->writeln("成功 => product_id={$productId}"); } else { $globalFail++; $output->writeln("跳过: {$result['msg']}"); } } catch (\Throwable $e) { $globalFail++; $output->writeln("异常: {$e->getMessage()}"); } $processedCount++; } // 每批结束后输出当前进度和耗时 $batchElapsed = time() - $batchStartTime; $totalElapsed = time() - $startTime; $output->writeln(" 本批耗时: {$batchElapsed}s | 累计耗时: {$totalElapsed}s | 累计成功: {$globalSuccess} | 累计失败: {$globalFail} | 分润设置: {$globalProfitSet}"); $output->writeln(''); // 每批之间短暂休眠,避免数据库压力过大 if ($chunkIndex < $totalChunks - 1) { $output->writeln(" 等待 1 秒后继续下一批..."); sleep(1); } } // 5. 输出汇总结果 $totalElapsed = time() - $startTime; $output->writeln(''); $output->writeln('========================================'); $output->writeln(' 入库完成'); $output->writeln('========================================'); $output->writeln("总耗时: {$totalElapsed}s"); $output->writeln("总处理: {$total} 条"); $output->writeln("成功: {$globalSuccess} 条"); $output->writeln("失败: {$globalFail} 条"); $output->writeln("已设置分润15%: {$globalProfitSet} 条"); if ($globalFail > 0) { $output->writeln(''); $output->writeln('提示: 失败的商品可以查看 alibaba 日志通道获取详细信息'); $output->writeln(" 重跑时可加 --skip={$skip} 跳过已处理的商品"); } $output->writeln('========================================'); $output->writeln(' 1688今日商品自动入库 结束'); $output->writeln('========================================'); } /** * 根据售价计算原价(阶梯加价) * * @param float $salePrice SKU售价 * @return float 计算后的原价 */ protected static function calcOtPrice(float $salePrice): float { if ($salePrice <= 0) { return 0; } if ($salePrice >= 1 && $salePrice <= 20) { return $salePrice + 5; } elseif ($salePrice >= 21 && $salePrice <= 50) { return $salePrice + 20; } elseif ($salePrice >= 51 && $salePrice <= 120) { return $salePrice + 40; } elseif ($salePrice >= 121 && $salePrice <= 200) { return $salePrice + 45; } else { // 201元以上(含201-300及超过300),统一加50元 return $salePrice + 50; } } }