fix channel price bug
This commit is contained in:
@@ -141,7 +141,20 @@ class ReportController extends Controller
|
||||
$payload['last_historical'] = app(ProductDisplayPriceService::class)->resolveHistoricalBasePrice();
|
||||
app(ProductDisplayPriceService::class)->cacheLivePricePayload($payload);
|
||||
|
||||
if ($saveFullCache || request()->boolean('force_refresh')) {
|
||||
$isFreshPrice = $saveFullCache || request()->boolean('force_refresh');
|
||||
|
||||
// ارسال قیمت به کانال فقط روی «لحظهٔ تغییر قیمت» = مسیر force_refresh (همان چیزی که سرورِ
|
||||
// حساس به قیمت صدا میزند و مبنای برادکست SSE است) — نه هر pulling عادی که کش برمیگرداند.
|
||||
// بعد از پاسخ اجرا میشود تا تاخیری برای فراخوان نباشد. در کنسول صدا نمیزنیم چون tick()
|
||||
// خودش مستقیماً broadcastIfEligible را اجرا میکند و afterResponse در دیمن اجرا نمیشود.
|
||||
// خودِ سرویس با price_channel_min_seconds و تشخیص تغییر قیمت گیت میکند.
|
||||
if ($isFreshPrice && (int) ($payload['price'] ?? 0) > 0 && ! app()->runningInConsole()) {
|
||||
dispatch(function () {
|
||||
app(\App\Services\PriceChannelBroadcastService::class)->broadcastIfEligible();
|
||||
})->afterResponse();
|
||||
}
|
||||
|
||||
if ($isFreshPrice) {
|
||||
$cache = app(LivePriceCacheService::class);
|
||||
$cache->markTick();
|
||||
|
||||
|
||||
@@ -48,22 +48,26 @@ class PriceChannelBroadcastService
|
||||
return;
|
||||
}
|
||||
|
||||
// شرط ۱ (ارزان): از آخرین «ارسال واقعی» حداقل price_channel_min_seconds گذشته باشد.
|
||||
// چون فقط روی ارسال واقعی markSent میکنیم، یک بررسیِ بیارسال تایمر را ریست نمیکند
|
||||
// و ارسالِ بعدی را عقب نمیاندازد.
|
||||
if (! $this->cooldownElapsed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$products = $this->eligibleProducts();
|
||||
if ($products === []) {
|
||||
Log::debug('PriceChannel: محصول واجد شرایطی نیست (active/قیمت/ساعت کاری)');
|
||||
return;
|
||||
}
|
||||
|
||||
// فقط وقتی قیمت واقعاً تغییر کرده باشد
|
||||
// شرط ۲: قیمت نسبت به آخرین ارسال واقعاً تغییر کرده باشد؛ وگرنه چیزی نفرست
|
||||
// و تایمر را هم دست نزن (تا سرِ اولین تغییرِ بعدی بلافاصله بفرستد).
|
||||
$signature = $this->priceSignature($products);
|
||||
if ($signature === Cache::get(self::SIGNATURE_CACHE_KEY)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (! $this->cooldownElapsed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$message = $this->buildMessage($products);
|
||||
if ($message === '') {
|
||||
return;
|
||||
@@ -74,6 +78,7 @@ class PriceChannelBroadcastService
|
||||
$results[$messenger] = $this->dispatchToMessenger($messenger, $target['token'], $target['chat_ids'], $message);
|
||||
}
|
||||
|
||||
// فقط بعد از ارسال واقعی: تایمر cooldown و امضای قیمت بهروزرسانی میشوند
|
||||
$this->markSent();
|
||||
Cache::put(self::SIGNATURE_CACHE_KEY, $signature, now()->addDay());
|
||||
|
||||
@@ -289,6 +294,16 @@ class PriceChannelBroadcastService
|
||||
->orderBy('id')
|
||||
->get();
|
||||
|
||||
// قیمت زنده را روی مدلها میگذارد (بدون UPDATE دیتابیس) تا پیام و تشخیص تغییر
|
||||
// مستقل از cron/tick و همیشه تازه باشد.
|
||||
try {
|
||||
$display = app(ProductDisplayPriceService::class);
|
||||
$display->warmLivePriceCache();
|
||||
$display->enrichForApi($products);
|
||||
} catch (\Throwable $e) {
|
||||
Log::debug('PriceChannel enrich live price failed', ['message' => $e->getMessage()]);
|
||||
}
|
||||
|
||||
$eligible = [];
|
||||
foreach ($products as $product) {
|
||||
if ((int) ($product->price ?? 0) <= 0) {
|
||||
|
||||
Reference in New Issue
Block a user