## 完成内容 - 提现管理展示所选余额日及前两天余额。 - 连续3个自然日余额一致且均严格高于预留标准时显示预警。 - 余额导入成功后自动生成或更新待处理事项,同一店铺不重复创建。 - 导出文件同步包含三天余额和预警状态。 ## 验证 - 新增预警测试:3 项通过,30 个断言。 - 提现管理导入导出测试:12 项通过,96 个断言。 - 管理页面回归:1 项通过,56 个断言。 - 余额仓库测试:11 项通过,46 个断言。 - 本地页面已验证:39 家店铺触发预警,待办事项生成 39 条。 ## 风险 - 无数据库结构迁移。 - 不改上游数据;仅在成功导入余额后读取共享镜像并写入待办。 Reviewed-on: #519 Co-authored-by: 92451 <924518135@qq.com> Co-committed-by: 92451 <924518135@qq.com>
79 lines
2.8 KiB
PHP
79 lines
2.8 KiB
PHP
<?php
|
||
|
||
namespace App\Console\Commands;
|
||
|
||
use App\Business\WithdrawalBalanceAlertSynchronizer;
|
||
use App\Models\Business\StoreReceivingAccount;
|
||
use Illuminate\Console\Command;
|
||
use Modules\EcommerceFinance\Services\JushuitanShopBalanceImporter;
|
||
use Throwable;
|
||
|
||
class ImportJushuitanShopBalances extends Command
|
||
{
|
||
protected $signature = 'business:import-jushuitan-shop-balances
|
||
{path : 聚水潭店铺余额接口 JSON 或 XLSX/XLS 导出文件}
|
||
{--balance-date= : 导入日期,格式 YYYY-MM-DD;多日期导出必须指定}
|
||
{--scope=all : 来源范围,同一日期同一范围会被原子替换}
|
||
{--dry-run : 只校验和统计,不写入共享业务库}';
|
||
|
||
protected $description = '校验并导入聚水潭平台原始账单中的店铺余额快照';
|
||
|
||
public function handle(
|
||
JushuitanShopBalanceImporter $importer,
|
||
WithdrawalBalanceAlertSynchronizer $alertSynchronizer,
|
||
): int
|
||
{
|
||
try {
|
||
$result = $importer->import(
|
||
(string) $this->argument('path'),
|
||
$this->option('balance-date') === null ? null : (string) $this->option('balance-date'),
|
||
(string) $this->option('scope'),
|
||
(bool) $this->option('dry-run'),
|
||
);
|
||
} catch (Throwable $exception) {
|
||
report($exception);
|
||
$this->error($exception->getMessage());
|
||
|
||
return self::FAILURE;
|
||
}
|
||
|
||
$this->info(sprintf(
|
||
'%s:%s 共 %d 条,替换原有 %d 条。',
|
||
$result['dry_run'] ? '校验完成' : '导入完成',
|
||
$result['balance_date'],
|
||
$result['total'],
|
||
$result['replaced'],
|
||
));
|
||
|
||
if (! $result['dry_run']) {
|
||
$companyIds = StoreReceivingAccount::withoutGlobalScopes()
|
||
->whereNull('deleted_at')
|
||
->distinct()
|
||
->pluck('company_id')
|
||
->filter()
|
||
->map(static fn (mixed $id): int => (int) $id)
|
||
->unique()
|
||
->values();
|
||
|
||
foreach ($companyIds as $companyId) {
|
||
try {
|
||
$alerts = $alertSynchronizer->syncLatest($companyId);
|
||
if ($alerts['created'] > 0 || $alerts['updated'] > 0) {
|
||
$this->info(sprintf(
|
||
'余额预警待办:公司 %d 新增 %d 条、更新 %d 条。',
|
||
$companyId,
|
||
$alerts['created'],
|
||
$alerts['updated'],
|
||
));
|
||
}
|
||
} catch (Throwable $exception) {
|
||
report($exception);
|
||
$this->warn("余额预警待办生成失败(公司 {$companyId}),余额快照已保留。");
|
||
}
|
||
}
|
||
}
|
||
|
||
return self::SUCCESS;
|
||
}
|
||
}
|