fixed some bugs
This commit is contained in:
@@ -20,7 +20,7 @@ class PriceChannelTest extends Command
|
||||
$this->line('قابلیت روشن (price_channel_enabled): ' . ($info['enabled'] ? 'بله' : 'خیر'));
|
||||
$this->line('پیامرسانهای انتخابشده: ' . (implode(', ', $info['selected_messengers']) ?: '— (خالی)'));
|
||||
$this->line('حداقل فاصله ارسال (ثانیه): ' . $info['min_seconds']);
|
||||
$this->line('فاصله cooldown گذشته؟ ' . ($info['cooldown_elapsed'] ? 'بله' : 'خیر (هنوز زوده)'));
|
||||
$this->line('فاصله cooldown گذشته؟ ' . ($info['cooldown_elapsed'] ? 'بله' : 'خیر (هنوز ' . ($info['cooldown_seconds_remaining'] ?? 0) . ' ثانیه مانده)'));
|
||||
$this->line('منبع قالب: ' . ($info['template_source'] === 'db' ? 'تنظیمات ادمین' : 'پیشفرض داخلی'));
|
||||
if (! empty($info['live_trade_buy_rial'])) {
|
||||
$this->line('قیمت فروش اپ (buy API): ' . number_format((int) $info['live_trade_buy_rial']) . ' ریال');
|
||||
|
||||
@@ -76,9 +76,8 @@ TXT;
|
||||
}
|
||||
|
||||
try {
|
||||
// شرط ۱: از آخرین «ارسال واقعی» حداقل price_channel_min_seconds گذشته باشد.
|
||||
// چون فقط روی ارسال واقعی markSent میکنیم، یک بررسیِ بیارسال تایمر را ریست نمیکند.
|
||||
if (! $this->cooldownElapsed()) {
|
||||
// شرط ۱: حداقل price_channel_min_seconds از آخرین ارسال گذشته باشد (اتمی — جلوی race و چند worker)
|
||||
if (! $this->acquireSendCooldown()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -111,8 +110,7 @@ TXT;
|
||||
$results[$messenger] = $this->dispatchToMessenger($messenger, $target['token'], $target['chat_ids'], $message);
|
||||
}
|
||||
|
||||
// فقط بعد از ارسال واقعی: تایمر cooldown و امضای قیمت بهروزرسانی میشوند
|
||||
$this->markSent();
|
||||
// فقط بعد از ارسال واقعی: امضا بهروزرسانی میشود (cooldown در acquireSendCooldown ست شد)
|
||||
Cache::put(self::SIGNATURE_CACHE_KEY, $signature, now()->addDay());
|
||||
|
||||
Log::info('PriceChannel: قیمت به کانال ارسال شد', [
|
||||
@@ -176,6 +174,11 @@ TXT;
|
||||
return;
|
||||
}
|
||||
|
||||
if (! $this->acquireSendCooldown()) {
|
||||
Log::debug('PriceChannel: قالب عوض شد ولی cooldown هنوز تمام نشده');
|
||||
return;
|
||||
}
|
||||
|
||||
$message = $this->buildMessage($products, $boardProduct);
|
||||
if ($message === '') {
|
||||
return;
|
||||
@@ -187,10 +190,9 @@ TXT;
|
||||
}
|
||||
|
||||
$signature = $this->broadcastSignature();
|
||||
$this->markSent();
|
||||
Cache::put(self::SIGNATURE_CACHE_KEY, $signature, now()->addDay());
|
||||
|
||||
Log::info('PriceChannel: قالب پیام تغییر کرد — ارسال فوری به کانال', [
|
||||
Log::info('PriceChannel: قالب پیام تغییر کرد — ارسال به کانال', [
|
||||
'targets' => array_keys($targets),
|
||||
'results' => $results,
|
||||
]);
|
||||
@@ -221,10 +223,8 @@ TXT;
|
||||
}
|
||||
|
||||
if ($message !== '' && $targets !== []) {
|
||||
$this->markSent();
|
||||
if ($this->resolveLiveTradePrices() !== null) {
|
||||
Cache::put(self::SIGNATURE_CACHE_KEY, $this->broadcastSignature(), now()->addDay());
|
||||
}
|
||||
$this->acquireSendCooldown(true);
|
||||
Cache::put(self::SIGNATURE_CACHE_KEY, $this->broadcastSignature(), now()->addDay());
|
||||
}
|
||||
|
||||
return [
|
||||
@@ -266,6 +266,7 @@ TXT;
|
||||
'selected_messengers' => $selected,
|
||||
'min_seconds' => $this->config->getInt('price_channel_min_seconds', 120),
|
||||
'cooldown_elapsed' => $this->cooldownElapsed(),
|
||||
'cooldown_seconds_remaining' => $this->cooldownSecondsRemaining(),
|
||||
'eligible_products' => count($this->eligibleProducts()),
|
||||
'messengers' => $messengers,
|
||||
'active_targets' => array_keys($this->resolveActiveTargets()),
|
||||
@@ -718,25 +719,39 @@ TXT;
|
||||
]);
|
||||
}
|
||||
|
||||
/** حداقل فاصلهی مجاز بین دو ارسال — جلوگیری از سیل پیام در هر تیک ۱۰ثانیهای */
|
||||
private function cooldownElapsed(): bool
|
||||
/** حداقل فاصلهٔ مجاز بین دو ارسال — Cache::add اتمی (TTL = min_seconds) */
|
||||
private function acquireSendCooldown(bool $force = false): bool
|
||||
{
|
||||
$minSeconds = max(0, $this->config->getInt('price_channel_min_seconds', 120));
|
||||
if ($minSeconds === 0) {
|
||||
if ($minSeconds === 0 || $force) {
|
||||
if ($minSeconds > 0) {
|
||||
Cache::put(self::COOLDOWN_CACHE_KEY, now()->timestamp, $minSeconds);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$lastSent = Cache::get(self::COOLDOWN_CACHE_KEY);
|
||||
if ($lastSent === null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return now()->timestamp - (int) $lastSent >= $minSeconds;
|
||||
return Cache::add(self::COOLDOWN_CACHE_KEY, now()->timestamp, $minSeconds);
|
||||
}
|
||||
|
||||
private function markSent(): void
|
||||
private function cooldownElapsed(): bool
|
||||
{
|
||||
Cache::put(self::COOLDOWN_CACHE_KEY, now()->timestamp, now()->addDay());
|
||||
return $this->cooldownSecondsRemaining() === 0;
|
||||
}
|
||||
|
||||
private function cooldownSecondsRemaining(): int
|
||||
{
|
||||
$minSeconds = max(0, $this->config->getInt('price_channel_min_seconds', 120));
|
||||
if ($minSeconds === 0 || ! Cache::has(self::COOLDOWN_CACHE_KEY)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$lastSent = (int) Cache::get(self::COOLDOWN_CACHE_KEY, 0);
|
||||
if ($lastSent <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return max(0, $minSeconds - (now()->timestamp - $lastSent));
|
||||
}
|
||||
|
||||
/** @return array<int, string> */
|
||||
|
||||
@@ -42,7 +42,22 @@ SET @invite_link_desc = 'متن پیام اشتراکگذاری دعوت در
|
||||
SET @deposit_guide_desc = 'متن راهنمای واریز در مودال شارژ حساب. متغیرها: ٪نام یا %نام = نام صاحب حساب؛ ٪کارت یا %کارت = شماره کارت؛ ٪شبا یا %شبا = شبا. فاصله بعد از ٪ اختیاری است. اگر خالی باشد از متن پیشفرض اپ استفاده میشود.';
|
||||
SET @deposit_support_msg_desc = 'متن پیام هنگام کلیک روی «پیام به پشتیبانی» و «پیام به پشتیبانی (sms)» در مودال واریز. فقط متغیر ٪نام یا %نام = نام صاحب حساب (deposit_account_holder). پیشفرض: «شماره حساب».';
|
||||
|
||||
SET @price_channel_message_desc = 'قالب متن پیام ارسالی به کانال. متغیرهای قیمت تابلو: ٪گرم_خرید ٪گرم_فروش ٪مثقال_خرید ٪مثقال_فروش (یا با %). زمان: ٪تاریخ ٪ساعت. اپ: ٪اسم_اپ یا ٪نام (نام فارسی)؛ ٪عنوان = خط «📊 قیمت لحظهای + نام». تماس جدا: ٪آیدی ٪شماره ٪لینک. اختیاری: ٪محصولات (لیست همه محصولات)؛ ٪فوتر (ترکیب آیدی+شماره+لینک). فاصله بعد از ٪ اختیاری است. خالی = قالب پیشفرض.';
|
||||
SET @price_channel_message_desc = CONCAT(
|
||||
'متن پیامی که با تغییر قیمت به کانال فرستاده میشود. هر متغیر را دقیقاً همینطور بنویسید (با ٪ یا %).', CHAR(10),
|
||||
CHAR(10),
|
||||
'قیمت تابلو — مثل اپ:', CHAR(10),
|
||||
'• %گرم_فروش = عدد بزرگ صفحهٔ اصلی اپ (فروش هر گرم)', CHAR(10),
|
||||
'• %گرم_خرید = خرید هر گرم', CHAR(10),
|
||||
'• %مثقال_فروش = فروش هر مثقال', CHAR(10),
|
||||
'• %مثقال_خرید = خرید هر مثقال', CHAR(10),
|
||||
CHAR(10),
|
||||
'زمان: %تاریخ (شمسی) • %ساعت', CHAR(10),
|
||||
'نام: %نام (فقط نام فروشگاه) • %عنوان (خط آماده 📊 قیمت لحظهای + نام)', CHAR(10),
|
||||
'تماس: %شماره • %آیدی • %لینک (از فیلدهای پایین همین بخش)', CHAR(10),
|
||||
'اختیاری: %محصولات • %فوتر', CHAR(10),
|
||||
CHAR(10),
|
||||
'خالی = قالب پیشفرض.'
|
||||
);
|
||||
SET @price_channel_default_text = CONCAT(
|
||||
'سلام 👋', CHAR(10),
|
||||
'%عنوان', CHAR(10),
|
||||
|
||||
@@ -41,7 +41,22 @@ SET @invite_link_desc = 'متن پیام اشتراکگذاری دعوت در
|
||||
SET @deposit_guide_desc = 'متن راهنمای واریز در مودال شارژ حساب. متغیرها: ٪نام یا %نام = نام صاحب حساب؛ ٪کارت یا %کارت = شماره کارت؛ ٪شبا یا %شبا = شبا. فاصله بعد از ٪ اختیاری است. اگر خالی باشد از متن پیشفرض اپ استفاده میشود.';
|
||||
SET @deposit_support_msg_desc = 'متن پیام هنگام کلیک روی «پیام به پشتیبانی» و «پیام به پشتیبانی (sms)» در مودال واریز. فقط متغیر ٪نام یا %نام = نام صاحب حساب (deposit_account_holder). پیشفرض: «شماره حساب».';
|
||||
|
||||
SET @price_channel_message_desc = 'قالب متن پیام ارسالی به کانال. متغیرهای قیمت تابلو: ٪گرم_خرید ٪گرم_فروش ٪مثقال_خرید ٪مثقال_فروش (یا با %). زمان: ٪تاریخ ٪ساعت. اپ: ٪اسم_اپ یا ٪نام (نام فارسی)؛ ٪عنوان = خط «📊 قیمت لحظهای + نام». تماس جدا: ٪آیدی ٪شماره ٪لینک. اختیاری: ٪محصولات (لیست همه محصولات)؛ ٪فوتر (ترکیب آیدی+شماره+لینک). فاصله بعد از ٪ اختیاری است. خالی = قالب پیشفرض.';
|
||||
SET @price_channel_message_desc = CONCAT(
|
||||
'متن پیامی که با تغییر قیمت به کانال فرستاده میشود. هر متغیر را دقیقاً همینطور بنویسید (با ٪ یا %).', CHAR(10),
|
||||
CHAR(10),
|
||||
'قیمت تابلو — مثل اپ:', CHAR(10),
|
||||
'• %گرم_فروش = عدد بزرگ صفحهٔ اصلی اپ (فروش هر گرم)', CHAR(10),
|
||||
'• %گرم_خرید = خرید هر گرم', CHAR(10),
|
||||
'• %مثقال_فروش = فروش هر مثقال', CHAR(10),
|
||||
'• %مثقال_خرید = خرید هر مثقال', CHAR(10),
|
||||
CHAR(10),
|
||||
'زمان: %تاریخ (شمسی) • %ساعت', CHAR(10),
|
||||
'نام: %نام (فقط نام فروشگاه) • %عنوان (خط آماده 📊 قیمت لحظهای + نام)', CHAR(10),
|
||||
'تماس: %شماره • %آیدی • %لینک (از فیلدهای پایین همین بخش)', CHAR(10),
|
||||
'اختیاری: %محصولات • %فوتر', CHAR(10),
|
||||
CHAR(10),
|
||||
'خالی = قالب پیشفرض.'
|
||||
);
|
||||
SET @price_channel_default_text = CONCAT(
|
||||
'سلام 👋', CHAR(10),
|
||||
'%عنوان', CHAR(10),
|
||||
|
||||
@@ -11,7 +11,22 @@
|
||||
START TRANSACTION;
|
||||
SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
SET @price_channel_message_desc = 'قالب متن پیام ارسالی به کانال. متغیرهای قیمت تابلو: ٪گرم_خرید ٪گرم_فروش ٪مثقال_خرید ٪مثقال_فروش (یا با %). زمان: ٪تاریخ ٪ساعت. اپ: ٪اسم_اپ یا ٪نام (نام فارسی)؛ ٪عنوان = خط «📊 قیمت لحظهای + نام». تماس جدا: ٪آیدی ٪شماره ٪لینک. اختیاری: ٪محصولات (لیست همه محصولات)؛ ٪فوتر (ترکیب آیدی+شماره+لینک). فاصله بعد از ٪ اختیاری است. خالی = قالب پیشفرض.';
|
||||
SET @price_channel_message_desc = CONCAT(
|
||||
'متن پیامی که با تغییر قیمت به کانال فرستاده میشود. هر متغیر را دقیقاً همینطور بنویسید (با ٪ یا %).', CHAR(10),
|
||||
CHAR(10),
|
||||
'قیمت تابلو — مثل اپ:', CHAR(10),
|
||||
'• %گرم_فروش = عدد بزرگ صفحهٔ اصلی اپ (فروش هر گرم)', CHAR(10),
|
||||
'• %گرم_خرید = خرید هر گرم', CHAR(10),
|
||||
'• %مثقال_فروش = فروش هر مثقال', CHAR(10),
|
||||
'• %مثقال_خرید = خرید هر مثقال', CHAR(10),
|
||||
CHAR(10),
|
||||
'زمان: %تاریخ (شمسی) • %ساعت', CHAR(10),
|
||||
'نام: %نام (فقط نام فروشگاه) • %عنوان (خط آماده 📊 قیمت لحظهای + نام)', CHAR(10),
|
||||
'تماس: %شماره • %آیدی • %لینک (از فیلدهای پایین همین بخش)', CHAR(10),
|
||||
'اختیاری: %محصولات • %فوتر', CHAR(10),
|
||||
CHAR(10),
|
||||
'خالی = قالب پیشفرض.'
|
||||
);
|
||||
SET @price_channel_default_text = CONCAT(
|
||||
'سلام 👋', CHAR(10),
|
||||
'%عنوان', CHAR(10),
|
||||
|
||||
Reference in New Issue
Block a user