fix some handling 4

This commit is contained in:
2026-07-08 13:15:29 +03:30
parent a4e98d8047
commit 771080d68c
3 changed files with 74 additions and 8 deletions
@@ -21,6 +21,7 @@ class PriceChannelTest extends Command
$this->line('پیام‌رسان‌های انتخاب‌شده: ' . (implode(', ', $info['selected_messengers']) ?: '— (خالی)'));
$this->line('حداقل فاصله ارسال (ثانیه): ' . $info['min_seconds']);
$this->line('فاصله cooldown گذشته؟ ' . ($info['cooldown_elapsed'] ? 'بله' : 'خیر (هنوز زوده)'));
$this->line('منبع قالب: ' . ($info['template_source'] === 'db' ? 'تنظیمات ادمین' : 'پیش‌فرض داخلی'));
$this->line('تعداد محصولات واجد شرایط: ' . $info['eligible_products']);
$this->line('مقصدهای فعال (آماده ارسال): ' . (implode(', ', $info['active_targets']) ?: '— (هیچ)'));
@@ -4,6 +4,7 @@ namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Setting;
use App\Services\PriceChannelBroadcastService;
use Illuminate\Http\Request;
class SettingsController extends Controller
@@ -59,6 +60,8 @@ class SettingsController extends Controller
return response()->json(['message' => 'Forbidden'], 403);
}
$previousValue = $setting->exists ? (string) ($setting->value ?? '') : null;
$setting->value = $request->value;
$setting->description = $request->description;
if ($request->has('is_active')) {
@@ -72,6 +75,15 @@ class SettingsController extends Controller
}
$setting->save();
if (
$request->key === 'price_channel_message_text'
&& $previousValue !== (string) ($request->value ?? '')
) {
dispatch(function () {
app(PriceChannelBroadcastService::class)->broadcastAfterTemplateChange();
})->afterResponse();
}
if ($isNew && $isSystemDeploy) {
$projectName = Setting::where('key', 'name_fa')->value('value') ?: 'پروژه';
$settingTitle = trim($request->title_fa ?? '') ?: $request->key;
+61 -8
View File
@@ -89,8 +89,8 @@ TXT;
return;
}
// شرط ۲: قیمت تابلو نسبت به آخرین ارسال واقعاً تغییر کرده باشد
$signature = $this->priceSignature($boardProduct);
// شرط ۲: قیمت تابلو یا قالب پیام نسبت به آخرین ارسال واقعاً تغییر کرده باشد
$signature = $this->broadcastSignature($boardProduct);
if ($signature === Cache::get(self::SIGNATURE_CACHE_KEY)) {
return;
}
@@ -123,12 +123,9 @@ TXT;
}
/**
* امضای قیمت — روی «بدنهٔ نمایشیِ» پیام (بدون هدر/ساعت) گرفته می‌شود تا دقیقاً همان چیزی
* که کاربر می‌بیند مبنای تشخیص تغییر باشد؛ اختلاف چند ریالیِ زیرِ آستانهٔ نمایش پیام تکراری نمی‌سازد.
*
* @param array<int, Product> $products
* امضای ارسال — قیمت تابلو + قالب پیام؛ تغییر هر کدام باید ارسال بعدی را مجاز کند.
*/
private function priceSignature(Product $boardProduct): string
private function broadcastSignature(Product $boardProduct): string
{
$prices = $this->computeDisplayPrices($boardProduct);
@@ -137,9 +134,63 @@ TXT;
$prices['gram_sell'],
$prices['mesghal_buy'],
$prices['mesghal_sell'],
$this->messageTemplate(),
]));
}
/**
* پس از ذخیرهٔ قالب در ادمین — یک بار فوری ارسال (بدون cooldown و بدون چک امضا).
*/
public function broadcastAfterTemplateChange(): void
{
try {
if (! $this->config->getBool('price_channel_enabled', false)) {
return;
}
$targets = $this->resolveActiveTargets();
if ($targets === []) {
return;
}
$lock = Cache::lock(self::SEND_LOCK_KEY, 30);
if (! $lock->get()) {
return;
}
try {
$products = $this->eligibleProducts();
$boardProduct = $this->resolveBoardProduct($products);
if ($boardProduct === null || (int) ($boardProduct->price ?? 0) <= 0) {
return;
}
$message = $this->buildMessage($products, $boardProduct);
if ($message === '') {
return;
}
$results = [];
foreach ($targets as $messenger => $target) {
$results[$messenger] = $this->dispatchToMessenger($messenger, $target['token'], $target['chat_ids'], $message);
}
$signature = $this->broadcastSignature($boardProduct);
$this->markSent();
Cache::put(self::SIGNATURE_CACHE_KEY, $signature, now()->addDay());
Log::info('PriceChannel: قالب پیام تغییر کرد — ارسال فوری به کانال', [
'targets' => array_keys($targets),
'results' => $results,
]);
} finally {
$lock->release();
}
} catch (\Throwable $e) {
Log::warning('PriceChannel template broadcast failed', ['message' => $e->getMessage()]);
}
}
/**
* ارسال دستی (عیب‌یابی) — cooldown و شرط تغییر قیمت را نادیده می‌گیرد.
* وضعیت روشن/خاموش، انتخاب پیام‌رسان، توکن و مقصد همچنان لازم است.
@@ -163,7 +214,7 @@ TXT;
$products = $this->eligibleProducts();
$boardProduct = $this->resolveBoardProduct($products);
if ($boardProduct !== null) {
Cache::put(self::SIGNATURE_CACHE_KEY, $this->priceSignature($boardProduct), now()->addDay());
Cache::put(self::SIGNATURE_CACHE_KEY, $this->broadcastSignature($boardProduct), now()->addDay());
}
}
@@ -197,6 +248,7 @@ TXT;
}
$message = $this->buildMessage();
$fromConfig = trim((string) $this->config->getString('price_channel_message_text', ''));
return [
'enabled' => $this->config->getBool('price_channel_enabled', false),
@@ -206,6 +258,7 @@ TXT;
'eligible_products' => count($this->eligibleProducts()),
'messengers' => $messengers,
'active_targets' => array_keys($this->resolveActiveTargets()),
'template_source' => $fromConfig !== '' ? 'db' : 'default',
'message_preview' => $message,
];
}