dashboard in better style

This commit is contained in:
2026-06-21 21:44:44 +03:30
parent 67f1b0ded0
commit eb4eff8002
6 changed files with 1471 additions and 36 deletions
+76 -10
View File
@@ -19,6 +19,11 @@ class ZaarboxPriceService
private const CACHE_TTL_MINUTES = 35;
/** بعد از خطای Zaarbox — TTL کوتاه تا با برگشت سرویس دوباره fetch شود */
private const FAILED_CACHE_TTL_MINUTES = 2;
private const LAST_GOOD_CACHE_SUFFIX = ':last_good';
/** TTL کش فید — کران هر ۳۰ث refresh می‌کند؛ list فقط از همین می‌خواند */
private const PRICE_LIST_CACHE_SECONDS = 15;
@@ -85,28 +90,71 @@ class ZaarboxPriceService
return self::CACHE_KEY . ':' . $this->historyId();
}
private function lastGoodCacheKey(): string
{
return $this->cacheKey() . self::LAST_GOOD_CACHE_SUFFIX;
}
/**
* @param array{DAILY?: array, WEEKLY?: array, MONTHLY?: array} $prices
*/
private function hasChartData(array $prices): bool
{
foreach (['DAILY', 'WEEKLY', 'MONTHLY'] as $period) {
if (! empty($prices[$period])) {
return true;
}
}
return false;
}
/**
* @return array{DAILY: array, WEEKLY: array, MONTHLY: array}|null
*/
private function resolveLastGoodPrices(): ?array
{
$lastGood = Cache::get($this->lastGoodCacheKey());
if (is_array($lastGood['prices'] ?? null) && $this->hasChartData($lastGood['prices'])) {
return $lastGood['prices'];
}
return null;
}
/**
* @return array{DAILY: array<int, array{timestamp: int, value: int}>, WEEKLY: array, MONTHLY: array}
*/
public function getAllPrices(): array
{
$snapshot = app(PriceSnapshotService::class);
$minRial = $snapshot->minValidChartPriceRialForExternalFeed();
if ($this->config->getBool('chart_use_local_data', false)) {
$local = $snapshot->chartFromDatabase();
if (! empty($local['DAILY'])) {
return $snapshot->sanitizeChartPrices($local);
$sanitizedLocal = $snapshot->sanitizeChartPrices($snapshot->chartFromDatabase());
if ($this->hasChartData($sanitizedLocal)) {
return $sanitizedLocal;
}
}
$minRial = $snapshot->minValidChartPriceRialForExternalFeed();
$cached = Cache::get($this->cacheKey());
if (is_array($cached) && isset($cached['prices'])) {
if (is_array($cached['prices'] ?? null) && $this->hasChartData($cached['prices'])) {
return $snapshot->sanitizeChartPrices($cached['prices'], $minRial);
}
return $snapshot->sanitizeChartPrices($this->refreshCache(), $minRial);
$fresh = $this->refreshCache();
$sanitized = $snapshot->sanitizeChartPrices($fresh, $minRial);
if ($this->hasChartData($sanitized)) {
return $sanitized;
}
$lastGood = $this->resolveLastGoodPrices();
if ($lastGood !== null) {
return $snapshot->sanitizeChartPrices($lastGood, $minRial);
}
return $sanitized;
}
/**
@@ -115,11 +163,29 @@ class ZaarboxPriceService
public function refreshCache(): array
{
$prices = $this->fetchChartPrices();
Cache::put($this->cacheKey(), [
$cacheKey = $this->cacheKey();
$payload = [
'prices' => $prices,
'refreshed_at' => now()->toIso8601String(),
], now()->addMinutes(self::CACHE_TTL_MINUTES));
];
if ($this->hasChartData($prices)) {
Cache::put($cacheKey, $payload, now()->addMinutes(self::CACHE_TTL_MINUTES));
Cache::put($this->lastGoodCacheKey(), $payload, now()->addHours(24));
return $prices;
}
Log::warning('Zaarbox chart refresh returned no data', [
'history_id' => $this->historyId(),
]);
$lastGood = $this->resolveLastGoodPrices();
if ($lastGood !== null) {
return $lastGood;
}
Cache::put($cacheKey, array_merge($payload, ['failed' => true]), now()->addMinutes(self::FAILED_CACHE_TTL_MINUTES));
return $prices;
}