fix: 询盘导入命令 notify-only 改为从 manifest 读分配结果

问题:--no-notify 建档后号码/邮箱已入库,--notify-only 重新解析时会被
去重逻辑全部判为重复,导致补发邮件变"共 0 条"。
修复:建档成功即把每人分配明细存入 manifest(groups),notify-only 从
manifest 读取补发(无 manifest 则报错提示先跑 --no-notify/完整命令)。
顺带修复重跑场景:无新建档时沿用已有 manifest 结果,不会误发空邮件。

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
mzl
2026-08-19 10:14:40 +08:00
parent 37e63637a4
commit 09fdd7a5d5
2 changed files with 120 additions and 48 deletions
+60 -24
View File
@@ -262,25 +262,55 @@ class HesuGoogleInquiryImportCommand extends Command
$output->writeln('<comment>[notify-only] 跳过写库。</comment>');
}
if ($noNotify) {
$output->writeln('<comment>[no-notify] 已建档,跳过发邮件。核对库后用 --notify-only 补发。</comment>');
return self::SUCCESS;
$manifestPath = $this->manifestPath($date);
if ($notifyOnly) {
// 建档后号码/邮箱已入库,重新解析会被去重清空——补发必须用 manifest 保存的分配结果
$manifest = is_file($manifestPath) ? (json_decode((string)@file_get_contents($manifestPath), true) ?: []) : [];
if (empty($manifest['groups'])) {
$output->writeln('<error>manifest 不存在或无分配数据: ' . $manifestPath . ';请先执行 --no-notify 或完整命令生成</error>');
return self::FAILURE;
}
$digestGroups = $manifest['groups'];
} else {
$totalRows = array_sum(array_map('count', $groups));
if ($totalRows > 0) {
$digestGroups = [];
foreach ($targetUserIds as $uid) {
$digestGroups[(string)$uid] = [];
}
foreach ($groups as $uid => $rows) {
foreach ($rows as $row) {
$digestGroups[(string)$uid][] = $this->digestRow($row);
}
}
$this->saveManifest($manifestPath, $targetUserIds, $digestGroups);
} else {
$manifest = is_file($manifestPath) ? (json_decode((string)@file_get_contents($manifestPath), true) ?: []) : [];
if (!empty($manifest['groups'])) {
$digestGroups = $manifest['groups'];
$output->writeln('<comment>本次无新建档(可能已导入过),沿用已有 manifest 的分配结果。</comment>');
} else {
$output->writeln('<comment>没有可建档数据,结束。</comment>');
return self::SUCCESS;
}
}
if ($noNotify) {
$output->writeln('<comment>[no-notify] 已建档,跳过发邮件。核对库后用 --notify-only 补发。</comment>');
return self::SUCCESS;
}
}
$manifestPath = $this->manifestPath($date);
$this->initManifest($manifestPath, $targetUserIds, $groups);
$this->sendDigests($groups, $targetUserIds, $manifestPath, $onlyUser, $output);
$this->sendDigests($digestGroups, $targetUserIds, $manifestPath, $onlyUser, $output);
return self::SUCCESS;
}
private function initManifest(string $path, array $targetUserIds, array $groups): void
private function saveManifest(string $path, array $targetUserIds, array $digestGroups): void
{
if (is_file($path)) {
return;
}
$perUser = []; $emailed = [];
foreach ($targetUserIds as $uid) {
$perUser[(string)$uid] = count($groups[$uid] ?? []);
$perUser[(string)$uid] = count($digestGroups[(string)$uid] ?? []);
$emailed[(string)$uid] = false;
}
$data = [
@@ -288,12 +318,29 @@ class HesuGoogleInquiryImportCommand extends Command
'imported_at' => time(),
'target_users' => $targetUserIds,
'per_user_counts' => $perUser,
'groups' => $digestGroups,
'emailed' => $emailed,
];
file_put_contents($path, json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
}
private function sendDigests(array $groups, array $targetUserIds, string $manifestPath, int $onlyUser, OutputInterface $output): void
/**
* 建档行 -> 邮件汇总行
*/
private function digestRow(array $row): array
{
return [
'code' => $row['code'] ?? '',
'contact' => $row['contacts'],
'email' => $row['email'],
'phone' => $row['phone'],
'country_cn' => '',
'channel' => self::CHANNEL_NAME,
'remark' => $row['message'],
];
}
private function sendDigests(array $digestGroups, array $targetUserIds, string $manifestPath, int $onlyUser, OutputInterface $output): void
{
$users = Db::table('user')->whereIn('id', $targetUserIds)->get(['id', 'name', 'email']);
$userMap = [];
@@ -316,18 +363,7 @@ class HesuGoogleInquiryImportCommand extends Command
$output->writeln('<error>user ' . $uid . ' 无邮箱,跳过</error>');
continue;
}
$inquiries = [];
foreach ($groups[$uid] ?? [] as $row) {
$inquiries[] = [
'code' => $row['code'] ?? '',
'contact' => $row['contacts'],
'email' => $row['email'],
'phone' => $row['phone'],
'country_cn' => '',
'channel' => self::CHANNEL_NAME,
'remark' => $row['message'],
];
}
$inquiries = array_values($digestGroups[(string)$uid] ?? []);
$html = InquiryDigestMail::build((string)$u->name, $inquiries, $date);
$subject = '新询盘分配汇总(共 ' . count($inquiries) . ' 条)- ' . $u->name . ' - ' . $date;
+60 -24
View File
@@ -298,25 +298,55 @@ class HesuGoogleWhatsAppImportCommand extends Command
$output->writeln('<comment>[notify-only] 跳过上传与写库。</comment>');
}
if ($noNotify) {
$output->writeln('<comment>[no-notify] 已建档,跳过发邮件。核对库后用 --notify-only 补发。</comment>');
return self::SUCCESS;
$manifestPath = $this->manifestPath($date);
if ($notifyOnly) {
// 建档后号码已入库,重新解析会被去重清空——补发必须用 manifest 保存的分配结果
$manifest = is_file($manifestPath) ? (json_decode((string)@file_get_contents($manifestPath), true) ?: []) : [];
if (empty($manifest['groups'])) {
$output->writeln('<error>manifest 不存在或无分配数据: ' . $manifestPath . ';请先执行 --no-notify 或完整命令生成</error>');
return self::FAILURE;
}
$digestGroups = $manifest['groups'];
} else {
$totalRows = array_sum(array_map('count', $groups));
if ($totalRows > 0) {
$digestGroups = [];
foreach ($targetUserIds as $uid) {
$digestGroups[(string)$uid] = [];
}
foreach ($groups as $uid => $rows) {
foreach ($rows as $row) {
$digestGroups[(string)$uid][] = $this->digestRow($row);
}
}
$this->saveManifest($manifestPath, $targetUserIds, $digestGroups);
} else {
$manifest = is_file($manifestPath) ? (json_decode((string)@file_get_contents($manifestPath), true) ?: []) : [];
if (!empty($manifest['groups'])) {
$digestGroups = $manifest['groups'];
$output->writeln('<comment>本次无新建档(可能已导入过),沿用已有 manifest 的分配结果。</comment>');
} else {
$output->writeln('<comment>没有可建档数据,结束。</comment>');
return self::SUCCESS;
}
}
if ($noNotify) {
$output->writeln('<comment>[no-notify] 已建档,跳过发邮件。核对库后用 --notify-only 补发。</comment>');
return self::SUCCESS;
}
}
$manifestPath = $this->manifestPath($date);
$this->initManifest($manifestPath, $targetUserIds, $groups);
$this->sendDigests($groups, $targetUserIds, $manifestPath, $onlyUser, $output);
$this->sendDigests($digestGroups, $targetUserIds, $manifestPath, $onlyUser, $output);
return self::SUCCESS;
}
private function initManifest(string $path, array $targetUserIds, array $groups): void
private function saveManifest(string $path, array $targetUserIds, array $digestGroups): void
{
if (is_file($path)) {
return;
}
$perUser = []; $emailed = [];
foreach ($targetUserIds as $uid) {
$perUser[(string)$uid] = count($groups[$uid] ?? []);
$perUser[(string)$uid] = count($digestGroups[(string)$uid] ?? []);
$emailed[(string)$uid] = false;
}
$data = [
@@ -324,12 +354,29 @@ class HesuGoogleWhatsAppImportCommand extends Command
'imported_at' => time(),
'target_users' => $targetUserIds,
'per_user_counts' => $perUser,
'groups' => $digestGroups,
'emailed' => $emailed,
];
file_put_contents($path, json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
}
private function sendDigests(array $groups, array $targetUserIds, string $manifestPath, int $onlyUser, OutputInterface $output): void
/**
* 建档行 -> 邮件汇总行(联系人/电话列显示 WhatsApp 号)
*/
private function digestRow(array $row): array
{
return [
'code' => $row['code'] ?? '',
'contact' => $row['number'],
'email' => '',
'phone' => $row['number'],
'country_cn' => '',
'channel' => self::CHANNEL_NAME,
'remark' => $row['message'],
];
}
private function sendDigests(array $digestGroups, array $targetUserIds, string $manifestPath, int $onlyUser, OutputInterface $output): void
{
$users = Db::table('user')->whereIn('id', $targetUserIds)->get(['id', 'name', 'email']);
$userMap = [];
@@ -352,18 +399,7 @@ class HesuGoogleWhatsAppImportCommand extends Command
$output->writeln('<error>user ' . $uid . ' 无邮箱,跳过</error>');
continue;
}
$inquiries = [];
foreach ($groups[$uid] ?? [] as $row) {
$inquiries[] = [
'code' => $row['code'] ?? '',
'contact' => $row['number'],
'email' => '',
'phone' => $row['number'], // 邮件里电话列显示 WhatsApp 号
'country_cn' => '',
'channel' => self::CHANNEL_NAME,
'remark' => $row['message'],
];
}
$inquiries = array_values($digestGroups[(string)$uid] ?? []);
$html = InquiryDigestMail::build((string)$u->name, $inquiries, $date);
$subject = 'WhatsApp新询盘分配汇总(共 ' . count($inquiries) . ' 条)- ' . $u->name . ' - ' . $date;