diff --git a/app/Http/Controllers/api/CurrencyController.php b/app/Http/Controllers/api/CurrencyController.php new file mode 100644 index 0000000..bc9345b --- /dev/null +++ b/app/Http/Controllers/api/CurrencyController.php @@ -0,0 +1,90 @@ +isToday(); + + // 2. If not updated today, call the API (Cache once per day) + if (!$isUpdatedToday) { + $this->fetchAndCacheGoldPrices(); + } + + // 3. Fetch data from our own database + $goldCurrencies = GoldCurrency::all()->map(function ($currency) { + return [ + 'change_percent' => $currency->change_percent, + 'change_value' => $currency->change_value, + 'date' => $currency->updated_at->format('Y-m-d'), // Format for the DTO + 'name' => $currency->name, + 'name_en' => $currency->name_en, + 'price' => $currency->price, + 'symbol' => $currency->symbol, + 'time' => $currency->updated_at->format('H:i:s'), // Format for the DTO + 'time_unix' => $currency->time_unix, + 'unit' => $currency->unit, + ]; + }); + + // 4. Return in the exact format your frontend expects! + // We nest it inside ['gold' => ...] to match your CurrencyListBrsDto + return $this->success([ + 'gold' => $goldCurrencies + ], 'موفق', 'لیست قیمت طلا و سکه دریافت شد.'); + } + + /** + * Private helper to fetch from the external API and save to DB + */ + private function fetchAndCacheGoldPrices() + { + try { + $url = 'https://Api.BrsApi.ir/Api/Market/Gold_Currency.php?key=B727Ue3kBrbtCwHR3BmSVZKRRNF1sllp'; + + // Timeout after 10 seconds so the user isn't stuck waiting if the API is down + $response = Http::timeout(10)->get($url); + + if ($response->successful()) { + $data = $response->json(); + + if (isset($data['gold']) && is_array($data['gold'])) { + foreach ($data['gold'] as $item) { + // updateOrCreate uses the 'name_en' as the unique key to update existing rows + GoldCurrency::updateOrCreate( + ['name_en' => $item['name_en']], + [ + 'name' => $item['name'], + 'price' => (int) $item['price'], + 'change_percent' => (float) $item['change_percent'], + 'change_value' => (int) $item['change_value'], + 'symbol' => $item['symbol'] ?? null, + 'unit' => $item['unit'] ?? null, + 'time_unix' => (int) $item['time_unix'], + ] + ); + } + } + } else { + Log::warning('BrsApi returned an error status: ' . $response->status()); + } + } catch (\Exception $e) { + // If the API completely dies (DNS issue, offline), we log it but don't crash. + // The controller will just safely return yesterday's prices from the DB! + Log::error('Failed to fetch from BrsApi: ' . $e->getMessage()); + } + } +} diff --git a/app/Models/GoldCurrency.php b/app/Models/GoldCurrency.php new file mode 100644 index 0000000..cbd002d --- /dev/null +++ b/app/Models/GoldCurrency.php @@ -0,0 +1,29 @@ + 'integer', + 'change_percent' => 'float', + 'change_value' => 'integer', + 'time_unix' => 'integer', + ]; +} diff --git a/routes/api.php b/routes/api.php index e612f89..babb01b 100644 --- a/routes/api.php +++ b/routes/api.php @@ -18,6 +18,7 @@ use App\Http\Controllers\api\SectionController; use App\Http\Controllers\api\SubscribePlanController; use App\Http\Controllers\api\VersionController; use App\Http\Controllers\api\VolumController; +use App\Http\Controllers\api\CurrencyController; use App\Http\Controllers\SuggestionController; use Illuminate\Support\Facades\Route; use App\Http\Controllers\api\QuizController; @@ -161,4 +162,8 @@ Route::prefix('v1')->middleware('auth:sanctum')->group(function () { Route::get('/quiz-attempts/{attempt}/result', [QuizController::class, 'result']); Route::get('/pvp-matches/{match}/result', [PvPQuizController::class, 'matchResult']); + + Route::get('market/gold', [CurrencyController::class, 'goldPrices']); + + });