fix some handling 4
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user