fix channel price bug
This commit is contained in:
@@ -141,7 +141,20 @@ class ReportController extends Controller
|
|||||||
$payload['last_historical'] = app(ProductDisplayPriceService::class)->resolveHistoricalBasePrice();
|
$payload['last_historical'] = app(ProductDisplayPriceService::class)->resolveHistoricalBasePrice();
|
||||||
app(ProductDisplayPriceService::class)->cacheLivePricePayload($payload);
|
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 = app(LivePriceCacheService::class);
|
||||||
$cache->markTick();
|
$cache->markTick();
|
||||||
|
|
||||||
|
|||||||
@@ -48,22 +48,26 @@ class PriceChannelBroadcastService
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// شرط ۱ (ارزان): از آخرین «ارسال واقعی» حداقل price_channel_min_seconds گذشته باشد.
|
||||||
|
// چون فقط روی ارسال واقعی markSent میکنیم، یک بررسیِ بیارسال تایمر را ریست نمیکند
|
||||||
|
// و ارسالِ بعدی را عقب نمیاندازد.
|
||||||
|
if (! $this->cooldownElapsed()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$products = $this->eligibleProducts();
|
$products = $this->eligibleProducts();
|
||||||
if ($products === []) {
|
if ($products === []) {
|
||||||
Log::debug('PriceChannel: محصول واجد شرایطی نیست (active/قیمت/ساعت کاری)');
|
Log::debug('PriceChannel: محصول واجد شرایطی نیست (active/قیمت/ساعت کاری)');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// فقط وقتی قیمت واقعاً تغییر کرده باشد
|
// شرط ۲: قیمت نسبت به آخرین ارسال واقعاً تغییر کرده باشد؛ وگرنه چیزی نفرست
|
||||||
|
// و تایمر را هم دست نزن (تا سرِ اولین تغییرِ بعدی بلافاصله بفرستد).
|
||||||
$signature = $this->priceSignature($products);
|
$signature = $this->priceSignature($products);
|
||||||
if ($signature === Cache::get(self::SIGNATURE_CACHE_KEY)) {
|
if ($signature === Cache::get(self::SIGNATURE_CACHE_KEY)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! $this->cooldownElapsed()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$message = $this->buildMessage($products);
|
$message = $this->buildMessage($products);
|
||||||
if ($message === '') {
|
if ($message === '') {
|
||||||
return;
|
return;
|
||||||
@@ -74,6 +78,7 @@ class PriceChannelBroadcastService
|
|||||||
$results[$messenger] = $this->dispatchToMessenger($messenger, $target['token'], $target['chat_ids'], $message);
|
$results[$messenger] = $this->dispatchToMessenger($messenger, $target['token'], $target['chat_ids'], $message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// فقط بعد از ارسال واقعی: تایمر cooldown و امضای قیمت بهروزرسانی میشوند
|
||||||
$this->markSent();
|
$this->markSent();
|
||||||
Cache::put(self::SIGNATURE_CACHE_KEY, $signature, now()->addDay());
|
Cache::put(self::SIGNATURE_CACHE_KEY, $signature, now()->addDay());
|
||||||
|
|
||||||
@@ -289,6 +294,16 @@ class PriceChannelBroadcastService
|
|||||||
->orderBy('id')
|
->orderBy('id')
|
||||||
->get();
|
->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 = [];
|
$eligible = [];
|
||||||
foreach ($products as $product) {
|
foreach ($products as $product) {
|
||||||
if ((int) ($product->price ?? 0) <= 0) {
|
if ((int) ($product->price ?? 0) <= 0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user