diff --git a/app/Http/Controllers/Business/Pages.php b/app/Http/Controllers/Business/Pages.php
index 9172eda1..769756eb 100644
--- a/app/Http/Controllers/Business/Pages.php
+++ b/app/Http/Controllers/Business/Pages.php
@@ -13,6 +13,7 @@ use Illuminate\Routing\Controller;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Pagination\Paginator;
use Illuminate\Support\Collection;
+use Modules\EcommerceFinance\Exceptions\UpstreamSnapshotPendingException;
use Modules\EcommerceFinance\Repositories\AlibabaBillRepository;
use Modules\EcommerceFinance\Repositories\EdgeBandingRepository;
use Modules\EcommerceFinance\Repositories\InventoryRepository;
@@ -248,6 +249,7 @@ class Pages extends Controller
'platform' => $tab,
'balances' => collect(),
'error' => null,
+ 'pending' => false,
];
if (! in_array($tab, ['taobao-alipay', 'pinduoduo'], true)) {
@@ -282,6 +284,9 @@ class Pages extends Controller
$pageSize,
),
);
+ } catch (UpstreamSnapshotPendingException $exception) {
+ $content['pending'] = true;
+ $result = ['rows' => [], 'total' => 0];
} catch (ServiceUnavailableHttpException $exception) {
$content['error'] = $exception->getMessage();
$result = ['rows' => [], 'total' => 0];
diff --git a/modules/EcommerceFinance/Exceptions/UpstreamSnapshotPendingException.php b/modules/EcommerceFinance/Exceptions/UpstreamSnapshotPendingException.php
new file mode 100644
index 00000000..cd472f11
--- /dev/null
+++ b/modules/EcommerceFinance/Exceptions/UpstreamSnapshotPendingException.php
@@ -0,0 +1,16 @@
+register($scope, $parameters, true);
if (! (bool) config('upstreams.snapshots.allow_inline_refresh', false)) {
- throw new ServiceUnavailableHttpException(
- 15,
- '数据同步请求已登记,后台正在准备首份共享数据,请稍后刷新。'
- );
+ throw new UpstreamSnapshotPendingException();
}
$resolved = $this->resolve($scope, $parameters, $resolver, false);
diff --git a/resources/views/banking/marketing_account_balances/partials/embedded-table.blade.php b/resources/views/banking/marketing_account_balances/partials/embedded-table.blade.php
index ad0f28a4..007e67d5 100644
--- a/resources/views/banking/marketing_account_balances/partials/embedded-table.blade.php
+++ b/resources/views/banking/marketing_account_balances/partials/embedded-table.blade.php
@@ -24,6 +24,8 @@
.marketing-balance-pagination .page-item.disabled .page-link { color: #595959; cursor: not-allowed; }
.marketing-balance-pagination div.lg\:flex > div:first-child { display: none !important; }
.marketing-balance-pagination div.lg\:flex { justify-content: center; }
+ .marketing-balance-status { display: flex; align-items: center; gap: 10px; margin: 0 0 16px; border: 1px solid var(--vip-border, #D8D2C7); border-radius: 12px; background: var(--vip-content-accent-soft, #F7F0DE); padding: 12px 14px; color: #513E21; font-size: 0.875rem; line-height: 1.5; }
+ .marketing-balance-status .material-icons-outlined { flex: 0 0 auto; color: var(--vip-content-accent-dark, #856632); font-size: 14px; }
@@ -71,6 +73,11 @@
@if (! empty($error))
{{ $error }}
+@elseif (! empty($pending))
+
+ sync
+ 同步请求已进入后台队列,页面会自动检查首份共享数据,无需重复操作。
+
@endif
@if ($supportsBalances)
@@ -104,3 +111,32 @@
该平台余额数据表尚未配置。
@endif
+
+@if (! empty($pending))
+
+@elseif ($supportsBalances)
+
+@endif
diff --git a/tests/Feature/Business/MarketingAccountBillsTabsTest.php b/tests/Feature/Business/MarketingAccountBillsTabsTest.php
index e5b0c98e..d12be030 100644
--- a/tests/Feature/Business/MarketingAccountBillsTabsTest.php
+++ b/tests/Feature/Business/MarketingAccountBillsTabsTest.php
@@ -4,6 +4,7 @@ namespace Tests\Feature\Business;
use App\Models\Auth\Permission;
use Mockery;
+use Modules\EcommerceFinance\Exceptions\UpstreamSnapshotPendingException;
use Modules\EcommerceFinance\Repositories\JdWalletBillRepository;
use Modules\EcommerceFinance\Repositories\PinduoduoSpreadBillRepository;
use Modules\EcommerceFinance\Repositories\TmallTaobaoSpreadBillRepository;
@@ -196,6 +197,38 @@ class MarketingAccountBillsTabsTest extends FeatureTestCase
->assertSessionHas('error', '首份共享快照正在准备,系统已登记刷新请求;请稍后刷新页面后再导出。');
}
+ public function testMarketingAccountBalanceColdStartShowsProcessingStateAndAutomaticCheck(): void
+ {
+ $this->allowMarketingAccountBalancePage();
+ $cache = Mockery::mock(UpstreamQueryCache::class);
+ $cache->shouldReceive('remember')
+ ->once()
+ ->withArgs(fn (string $scope): bool => $scope === 'taobao-alipay-bills.list')
+ ->andThrow(new UpstreamSnapshotPendingException());
+ $cache->shouldReceive('remember')
+ ->once()
+ ->withArgs(fn (string $scope): bool => $scope === 'taobao-alipay-bills.options')
+ ->andReturn([]);
+
+ $factory = Mockery::mock(UpstreamQueryCacheFactory::class);
+ $factory->shouldReceive('forSource')->once()->with('jiansun')->andReturn($cache);
+
+ $this->app->instance(UpstreamQueryCacheFactory::class, $factory);
+ $this->app->instance(TmallTaobaoSpreadBillRepository::class, Mockery::mock(TmallTaobaoSpreadBillRepository::class));
+
+ $this->loginAs()
+ ->get(route('business.pages.show', [
+ 'section' => 'billing-transactions',
+ 'page' => 'marketing-account-balance',
+ 'tab' => 'taobao-alipay',
+ ]))
+ ->assertOk()
+ ->assertSeeText('同步请求已进入后台队列,页面会自动检查首份共享数据,无需重复操作。')
+ ->assertSee('data-marketing-balance-pending', false)
+ ->assertSee('window.location.reload()', false)
+ ->assertDontSee('', false);
+ }
+
public function testMarketingAccountBalanceExportUnexpectedFailureReturnsRedactedRedirect(): void
{
$this->allowMarketingAccountBalancePage();
diff --git a/tests/Unit/EcommerceFinance/UpstreamQueryCacheTest.php b/tests/Unit/EcommerceFinance/UpstreamQueryCacheTest.php
index 03644657..dd100b40 100644
--- a/tests/Unit/EcommerceFinance/UpstreamQueryCacheTest.php
+++ b/tests/Unit/EcommerceFinance/UpstreamQueryCacheTest.php
@@ -5,6 +5,7 @@ namespace Tests\Unit\EcommerceFinance;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Cache;
use InvalidArgumentException;
+use Modules\EcommerceFinance\Exceptions\UpstreamSnapshotPendingException;
use Modules\EcommerceFinance\Services\UpstreamOdbcConnection;
use Modules\EcommerceFinance\Services\UpstreamQueryCacheFactory;
use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
@@ -103,9 +104,10 @@ class UpstreamQueryCacheTest extends TestCase
return ['total' => 1];
});
$this->fail('页面冷查询不应直接访问上游数据库。');
- } catch (ServiceUnavailableHttpException $exception) {
+ } catch (UpstreamSnapshotPendingException $exception) {
$this->assertSame(0, $calls);
$this->assertStringContainsString('后台正在准备', $exception->getMessage());
+ $this->assertSame(15, $exception->getHeaders()['Retry-After']);
$this->assertNotEmpty(Cache::get('source_a:snapshots:active:v2'));
}
}