CaiWuXiTong/app/Console/Commands/ImportVipshopMpBills.php
qiuxiang 37d4cb06a0 feat: 导入唯品会MP后台月度账单
新增唯品会MP明细导入命令,支持店铺名称映射和按账期幂等替换;补充导入及页面回归测试。
2026-11-06 17:17:48 +08:00

84 lines
2.9 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use InvalidArgumentException;
use Modules\EcommerceFinance\Services\VipshopMpBillImporter;
use RuntimeException;
use Throwable;
class ImportVipshopMpBills extends Command
{
protected $signature = 'vipshop-mp:import
{files* : 唯品会MP后台导出的订单明细 XLSX}
{--period= : 账单期间,格式 YYYY-MM}
{--store-map= : 后台店铺名到财务系统店铺全称的 JSON 映射}
{--company=1 : 公司 ID}
{--dry-run : 只校验,不写数据库}';
protected $description = '导入唯品会MP后台订单明细,按账期和店铺幂等替换';
public function handle(VipshopMpBillImporter $importer): int
{
$period = trim((string) $this->option('period'));
$mapPath = trim((string) $this->option('store-map'));
if ($period === '' || $mapPath === '') {
$this->error('缺少 --period 或 --store-map。');
return self::FAILURE;
}
$realMapPath = realpath($mapPath);
if ($realMapPath === false || ! is_file($realMapPath) || ! is_readable($realMapPath)) {
$this->error('店铺映射文件不存在或不可读。');
return self::FAILURE;
}
$storeMap = json_decode((string) file_get_contents($realMapPath), true, 512, JSON_THROW_ON_ERROR);
if (! is_array($storeMap)) {
$this->error('店铺映射文件必须是 JSON 对象。');
return self::FAILURE;
}
foreach ($storeMap as $source => $target) {
if (! is_string($source) || trim($source) === '' || ! is_string($target) || trim($target) === '') {
$this->error('店铺映射中存在无效名称。');
return self::FAILURE;
}
}
try {
$result = $importer->import(
array_values((array) $this->argument('files')),
$period,
$storeMap,
(int) $this->option('company'),
(bool) $this->option('dry-run'),
);
} catch (InvalidArgumentException|RuntimeException $exception) {
$this->error($exception->getMessage());
return self::FAILURE;
} catch (Throwable $exception) {
report($exception);
$this->error('唯品会MP账单导入失败,详细原因已记录到受保护日志。');
return self::FAILURE;
}
$this->table(['账期', '状态', '账单数', '店铺数', '明细行数', '收入', '支出', '商家应收'], [[
$result['period'],
$result['status'],
$result['bill_count'],
$result['store_count'],
$result['row_count'],
$result['income_total'],
$result['expense_total'],
$result['balance_total'],
]]);
return self::SUCCESS;
}
}