CaiWuXiTong/app/Console/Commands/PushSupplierNegativeAlertDingTalkTasks.php
苏木 79fad431df feat: 自动推送负数预警并支持处理截图 (#742)
每日自动推送未处理供应商,增加处理截止时间和截图上传。
Co-authored-by: 苏木 <594326199@qq.com>
Co-committed-by: 苏木 <594326199@qq.com>
2026-10-28 16:32:21 +08:00

100 lines
3.8 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 App\Models\Common\Company;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Cache;
use Modules\EcommerceFinance\Services\SupplierNegativeAlertDingTalkWorkflow;
use Modules\EcommerceFinance\View\SupplierNegativeAlertPageData;
use Throwable;
class PushSupplierNegativeAlertDingTalkTasks extends Command
{
protected $signature = 'supplier-negative-alert:push-dingtalk
{--date= : 推送日期,格式 Y-m-d,默认今天}
{--force : 忽略当天已推送标记}';
protected $description = '每天推送最新账期内尚未处理的供应商负数预警任务';
public function handle(
SupplierNegativeAlertPageData $pageData,
SupplierNegativeAlertDingTalkWorkflow $workflow,
): int {
$date = trim((string) $this->option('date')) ?: now()->toDateString();
if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $date) !== 1) {
$this->error('推送日期格式无效。');
return self::FAILURE;
}
$failed = false;
foreach (Company::enabled()->orderBy('id')->get() as $company) {
$company->makeCurrent();
$rows = $pageData->rowsForFilters([]);
$periods = array_values(array_unique(array_filter(array_map(
static fn (array $row): string => trim((string) ($row['summary_month'] ?? '')),
$rows,
))));
if ($periods === []) {
$this->line("#{$company->id} {$company->name}: 没有负数预警数据");
continue;
}
rsort($periods);
$period = $periods[0];
$latestRows = array_values(array_filter(
$rows,
static fn (array $row): bool => trim((string) ($row['summary_month'] ?? '')) === $period,
));
$handled = array_fill_keys(
$workflow->handledSuppliersForPeriod((int) $company->id, $period),
true,
);
$unhandledRows = array_values(array_filter(
$latestRows,
static fn (array $row): bool => ! isset($handled[trim((string) ($row['supplier'] ?? ''))]),
));
if ($unhandledRows === []) {
$this->line("#{$company->id} {$company->name} {$period}: 供应商均已处理");
continue;
}
$lockKey = sprintf(
'supplier-negative-alert:auto-push:%d:%s:%s',
$company->id,
$period,
$date,
);
if (! $this->option('force') && ! Cache::add($lockKey, true, now()->addDays(2))) {
$this->line("#{$company->id} {$company->name} {$period}: 今天已经自动推送");
continue;
}
try {
$result = $workflow->sendGrouped(
$unhandledRows,
['month' => $period, 'automatic' => true],
(int) $company->id,
null,
);
$this->info(sprintf(
'#%d %s %s: 已推送 %d 位采购、%d 家供应商、%d 条未处理预警',
$company->id,
$company->name,
$period,
$result['purchaser_count'],
$result['supplier_count'],
$result['row_count'],
));
} catch (Throwable $exception) {
Cache::forget($lockKey);
report($exception);
$this->error("#{$company->id} {$company->name} {$period}: 自动推送失败:" . $exception->getMessage());
$failed = true;
}
}
return $failed ? self::FAILURE : self::SUCCESS;
}
}