Files
fdesk/app/command/ImportCustomerCommand.php
T
2025-07-30 15:15:57 +08:00

167 lines
7.3 KiB
PHP

<?php
namespace app\command;
use app\crm\model\Country;
use app\crm\model\Customer;
use PhpOffice\PhpSpreadsheet\IOFactory;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
class ImportCustomerCommand extends Command
{
protected static $defaultName = 'import:customer';
protected static $defaultDescription = '导入Excel文件到crm_customer表';
protected function configure()
{
// $this->addArgument('file', InputArgument::REQUIRED, 'Excel文件路径')
// ->addOption('user-id', 'u', InputOption::VALUE_REQUIRED, '用户ID', 0)
// ->addOption('channel-id', 'c', InputOption::VALUE_REQUIRED, '渠道ID', 5)
// ->addOption('corp-abbr', 'a', InputOption::VALUE_REQUIRED, '公司缩写', 2);
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
// $filePath = $input->getArgument('file');
// $userId = $input->getOption('user-id');
// $channelId = $input->getOption('channel-id');
// $corpAbbr = $input->getOption('corp-abbr');
$filePath = 'C:\Users\16961\Downloads\中国制造 2023-2025-询盘导出.xls';
$userId = 0;
$channelId = 5;
$corpAbbr = 2;
// 检查文件是否存在
if (!file_exists($filePath)) {
$output->writeln("<error>文件不存在: {$filePath}</error>");
return self::FAILURE;
}
try {
$output->writeln("开始导入文件: {$filePath}");
// 加载Excel文件
$output->writeln("正在加载Excel文件...");
$spreadsheet = IOFactory::load($filePath);
$worksheet = $spreadsheet->getActiveSheet();
$output->writeln("Excel文件加载成功");
// 获取数据范围
$highestRow = $worksheet->getHighestRow();
$highestColumn = $worksheet->getHighestColumn();
$output->writeln("文件包含 {$highestRow} 行数据");
// 获取所有国家数据,用于匹配
$output->writeln("正在获取国家数据...");
$countries = Country::select('id', 'cn_addr', 'en_addr')->get()->keyBy(function($item) {
return strtolower(trim($item->cn_addr));
});
$output->writeln("获取到 " . $countries->count() . " 个国家数据");
$successCount = 0;
$errorCount = 0;
$errors = [];
// 从第二行开始读取数据(第一行是标题)
$output->writeln("开始读取Excel数据...");
for ($row = 2; $row <= $highestRow; $row++) {
try {
$output->writeln("正在处理第 {$row} 行...");
// 读取各列数据 - 使用坐标方法
try {
$countryName = trim($worksheet->getCell('B' . $row)->getValue() ?? '');
$customerName = trim($worksheet->getCell('C' . $row)->getValue() ?? '');
$inquiryProduct = trim($worksheet->getCell('E' . $row)->getValue() ?? '');
} catch (\Exception $cellError) {
$output->writeln("<error>读取第{$row}行单元格时出错: " . $cellError->getMessage() . "</error>");
continue;
}
$output->writeln("读取数据: 国家={$countryName}, 客户={$customerName}, 产品={$inquiryProduct}");
// 跳过空行
if (empty($customerName)) {
continue;
}
// 查找国家ID
$countryId = 0;
if (!empty($countryName)) {
$countryKey = strtolower($countryName);
if ($countries->has($countryKey)) {
$countryId = $countries->get($countryKey)->id;
} else {
// 尝试英文名称匹配
$countryByEn = $countries->first(function($item) use ($countryName) {
return strtolower(trim($item->en_addr)) === strtolower($countryName);
});
if ($countryByEn) {
$countryId = $countryByEn->id;
}
}
}
// 检查是否已存在相同客户名
// $existingCustomer = Customer::where('contacts', $customerName)->first();
// if ($existingCustomer) {
// $output->writeln("跳过已存在的客户: {$customerName}");
// continue;
// }
// 创建客户记录
$customerData = [
'user_id' => $userId,
'corp_abbr' => $corpAbbr,
'channel_id' => $channelId,
'country_id' => $countryId,
'contacts' => $customerName,
'desc_collect' => $inquiryProduct,
'grade' => 0, // 默认等级
'magnitude' => 1, // 默认商机
'type' => 1, // 默认类型
'sex' => 0, // 默认性别
'enter_user_id' => $userId,
];
$customer = Customer::create($customerData);
$successCount++;
$output->writeln("成功导入客户: {$customerName} (ID: {$customer->id})");
} catch (\Exception $e) {
$errorCount++;
$errorMsg = "第{$row}行导入失败: " . $e->getMessage();
$errorMsg .= "\n文件: " . $e->getFile() . " 行: " . $e->getLine();
$errorMsg .= "\n堆栈: " . $e->getTraceAsString();
$errors[] = $errorMsg;
$output->writeln("<error>{$errorMsg}</error>");
}
}
$output->writeln("\n导入完成!");
$output->writeln("成功导入: {$successCount} 条记录");
$output->writeln("失败: {$errorCount} 条记录");
if (!empty($errors)) {
$output->writeln("\n错误详情:");
foreach ($errors as $error) {
$output->writeln("<error>{$error}</error>");
}
}
return self::SUCCESS;
} catch (\Exception $e) {
$output->writeln("<error>导入过程中发生错误: " . $e->getMessage() . "</error>");
$output->writeln("<error>文件: " . $e->getFile() . " 行: " . $e->getLine() . "</error>");
$output->writeln("<error>堆栈: " . $e->getTraceAsString() . "</error>");
return self::FAILURE;
}
}
}