fix some handling 3
This commit is contained in:
@@ -611,29 +611,32 @@ class ProductController extends SuperController
|
||||
|
||||
if (!Product::hasOrderLimitColumns()) {
|
||||
unset($data['order_limit_enabled'], $data['min_order_cash'], $data['max_order_cash']);
|
||||
} elseif (empty($data['order_limit_enabled'])) {
|
||||
$data['order_limit_enabled'] = false;
|
||||
$data['min_order_cash'] = null;
|
||||
$data['max_order_cash'] = null;
|
||||
} else {
|
||||
$min = $data['min_order_cash'] ?? null;
|
||||
$max = $data['max_order_cash'] ?? null;
|
||||
$hasMin = $min !== null && $min !== '';
|
||||
$hasMax = $max !== null && $max !== '';
|
||||
$min = $this->normalizeOrderLimitCash($data['min_order_cash'] ?? null);
|
||||
$max = $this->normalizeOrderLimitCash($data['max_order_cash'] ?? null);
|
||||
$orderLimitEnabled = filter_var($data['order_limit_enabled'] ?? false, FILTER_VALIDATE_BOOLEAN)
|
||||
|| $min !== null
|
||||
|| $max !== null;
|
||||
|
||||
if (!$hasMin && !$hasMax) {
|
||||
throw new UnprocessableEntityHttpException(
|
||||
'با فعال بودن محدودیت مبلغ سفارش، حداقل یکی از حداقل یا حداکثر مبلغ باید وارد شود'
|
||||
);
|
||||
if (!$orderLimitEnabled) {
|
||||
$data['order_limit_enabled'] = false;
|
||||
$data['min_order_cash'] = null;
|
||||
$data['max_order_cash'] = null;
|
||||
} else {
|
||||
if ($min === null && $max === null) {
|
||||
throw new UnprocessableEntityHttpException(
|
||||
'با فعال بودن محدودیت مبلغ سفارش، حداقل یکی از حداقل یا حداکثر مبلغ باید وارد شود'
|
||||
);
|
||||
}
|
||||
|
||||
if ($min !== null && $max !== null && $min > $max) {
|
||||
throw new UnprocessableEntityHttpException('حداقل مبلغ نمیتواند بیشتر از حداکثر باشد');
|
||||
}
|
||||
|
||||
$data['order_limit_enabled'] = true;
|
||||
$data['min_order_cash'] = $min;
|
||||
$data['max_order_cash'] = $max;
|
||||
}
|
||||
|
||||
if ($hasMin && $hasMax && (float) $min > (float) $max) {
|
||||
throw new UnprocessableEntityHttpException('حداقل مبلغ نمیتواند بیشتر از حداکثر باشد');
|
||||
}
|
||||
|
||||
$data['order_limit_enabled'] = true;
|
||||
$data['min_order_cash'] = $hasMin ? (int) $min : null;
|
||||
$data['max_order_cash'] = $hasMax ? (int) $max : null;
|
||||
}
|
||||
|
||||
if (!Product::hasShowInAssetsColumn()) {
|
||||
@@ -704,4 +707,39 @@ class ProductController extends SuperController
|
||||
|
||||
return (float) $value;
|
||||
}
|
||||
|
||||
private function normalizeOrderLimitCash(mixed $value): ?int
|
||||
{
|
||||
if ($value === null || $value === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (is_int($value)) {
|
||||
return $value >= 0 ? $value : null;
|
||||
}
|
||||
|
||||
if (is_float($value)) {
|
||||
return $value >= 0 ? (int) $value : null;
|
||||
}
|
||||
|
||||
if (! is_string($value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$value = $this->normalizeAsciiDigits(trim(str_replace([' ', ',', '٬'], '', $value)));
|
||||
if ($value === '' || ! ctype_digit($value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (int) $value;
|
||||
}
|
||||
|
||||
private function normalizeAsciiDigits(string $value): string
|
||||
{
|
||||
$persian = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'];
|
||||
$arabic = ['٠', '١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩'];
|
||||
$latin = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
|
||||
|
||||
return str_replace(array_merge($persian, $arabic), array_merge($latin, $latin), $value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,10 +146,10 @@ class Product extends Model
|
||||
}
|
||||
|
||||
try {
|
||||
static::$orderLimitColumnsExist = Schema::hasColumn(
|
||||
(new static)->getTable(),
|
||||
'order_limit_enabled'
|
||||
);
|
||||
$table = (new static)->getTable();
|
||||
static::$orderLimitColumnsExist = Schema::hasColumn($table, 'order_limit_enabled')
|
||||
&& Schema::hasColumn($table, 'min_order_cash')
|
||||
&& Schema::hasColumn($table, 'max_order_cash');
|
||||
} catch (\Throwable) {
|
||||
static::$orderLimitColumnsExist = false;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Services;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Product;
|
||||
use Hekmatinasser\Verta\Verta;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
@@ -29,6 +30,22 @@ class PriceChannelBroadcastService
|
||||
/** وزن هر مثقال به گرم — ضریب تبدیل قیمت هر گرم به هر مثقال (مثقال = گرم × این عدد) */
|
||||
private const DEFAULT_CHANGE_MESGHAL = 4.3318;
|
||||
|
||||
/** قالب پیشفرض پیام کانال — وقتی price_channel_message_text خالی باشد */
|
||||
private const DEFAULT_MESSAGE_TEMPLATE = <<<'TXT'
|
||||
سلام 👋
|
||||
%عنوان
|
||||
📅 %تاریخ 🕐 %ساعت
|
||||
|
||||
🔴 خرید گرم: %گرم_خرید
|
||||
🟢 فروش گرم: %گرم_فروش
|
||||
🔴 خرید مثقال: %مثقال_خرید
|
||||
🟢 فروش مثقال: %مثقال_فروش
|
||||
|
||||
📞 %شماره
|
||||
%آیدی
|
||||
%لینک
|
||||
TXT;
|
||||
|
||||
public function __construct(private readonly ConfigService $config)
|
||||
{
|
||||
}
|
||||
@@ -66,19 +83,19 @@ class PriceChannelBroadcastService
|
||||
}
|
||||
|
||||
$products = $this->eligibleProducts();
|
||||
if ($products === []) {
|
||||
Log::debug('PriceChannel: محصول واجد شرایطی نیست (active/قیمت/ساعت کاری)');
|
||||
$boardProduct = $this->resolveBoardProduct($products);
|
||||
if ($boardProduct === null || (int) ($boardProduct->price ?? 0) <= 0) {
|
||||
Log::debug('PriceChannel: محصول تابلو (آبشده) واجد شرایطی نیست');
|
||||
return;
|
||||
}
|
||||
|
||||
// شرط ۲: قیمتِ نمایشی نسبت به آخرین ارسال واقعاً تغییر کرده باشد؛ وگرنه چیزی نفرست
|
||||
// و تایمر را هم دست نزن (تا سرِ اولین تغییرِ بعدی بلافاصله بفرستد).
|
||||
$signature = $this->priceSignature($products);
|
||||
// شرط ۲: قیمت تابلو نسبت به آخرین ارسال واقعاً تغییر کرده باشد
|
||||
$signature = $this->priceSignature($boardProduct);
|
||||
if ($signature === Cache::get(self::SIGNATURE_CACHE_KEY)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$message = $this->buildMessage($products);
|
||||
$message = $this->buildMessage($products, $boardProduct);
|
||||
if ($message === '') {
|
||||
return;
|
||||
}
|
||||
@@ -111,9 +128,16 @@ class PriceChannelBroadcastService
|
||||
*
|
||||
* @param array<int, Product> $products
|
||||
*/
|
||||
private function priceSignature(array $products): string
|
||||
private function priceSignature(Product $boardProduct): string
|
||||
{
|
||||
return md5($this->buildPriceBody($products));
|
||||
$prices = $this->computeDisplayPrices($boardProduct);
|
||||
|
||||
return md5(implode('|', [
|
||||
$prices['gram_buy'],
|
||||
$prices['gram_sell'],
|
||||
$prices['mesghal_buy'],
|
||||
$prices['mesghal_sell'],
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -137,8 +161,9 @@ class PriceChannelBroadcastService
|
||||
if ($message !== '' && $targets !== []) {
|
||||
$this->markSent();
|
||||
$products = $this->eligibleProducts();
|
||||
if ($products !== []) {
|
||||
Cache::put(self::SIGNATURE_CACHE_KEY, $this->priceSignature($products), now()->addDay());
|
||||
$boardProduct = $this->resolveBoardProduct($products);
|
||||
if ($boardProduct !== null) {
|
||||
Cache::put(self::SIGNATURE_CACHE_KEY, $this->priceSignature($boardProduct), now()->addDay());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,27 +264,135 @@ class PriceChannelBroadcastService
|
||||
}
|
||||
|
||||
/**
|
||||
* ساخت متن پیام قیمت — مرتب و بر اساس دادهی هر محصول.
|
||||
* ساخت متن پیام قیمت — قالب از price_channel_message_text (یا پیشفرض داخلی).
|
||||
*/
|
||||
public function buildMessage(?array $products = null): string
|
||||
public function buildMessage(?array $products = null, ?Product $boardProduct = null): string
|
||||
{
|
||||
$products = $products ?? $this->eligibleProducts();
|
||||
$body = $this->buildPriceBody($products);
|
||||
if ($body === '') {
|
||||
$boardProduct = $boardProduct ?? $this->resolveBoardProduct($products);
|
||||
if ($boardProduct === null || (int) ($boardProduct->price ?? 0) <= 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return trim($this->header() . "\n\n" . $body);
|
||||
return $this->renderMessageTemplate($this->messageTemplate(), $products, $boardProduct);
|
||||
}
|
||||
|
||||
private function messageTemplate(): string
|
||||
{
|
||||
$fromConfig = trim((string) $this->config->getString('price_channel_message_text', ''));
|
||||
|
||||
return $fromConfig !== '' ? $fromConfig : self::DEFAULT_MESSAGE_TEMPLATE;
|
||||
}
|
||||
|
||||
/**
|
||||
* بدنهٔ قیمت (بدون هدر/ساعت) — همان چیزی که «تغییر قیمت» را میسازد.
|
||||
* امضای تشخیص تغییر روی همین بدنهی نمایشیِ رُندشده گرفته میشود تا اختلاف چند ریالی
|
||||
* که به یک عدد نمایشیِ یکسان میرسد، پیام تکراری نفرستد.
|
||||
* جایگزینی متغیرهای قالب.
|
||||
* قیمت تابلو: %گرم_خرید %گرم_فروش %مثقال_خرید %مثقال_فروش
|
||||
* زمان: %تاریخ %ساعت — اپ: %اسم_اپ %نام %عنوان
|
||||
* تماس: %آیدی %شماره %لینک — اختیاری: %محصولات %فوتر
|
||||
*
|
||||
* @param array<int, Product> $products
|
||||
*/
|
||||
private function buildPriceBody(array $products): string
|
||||
private function renderMessageTemplate(string $template, array $products, Product $boardProduct): string
|
||||
{
|
||||
$name = trim((string) $this->config->getString('name_fa', ''));
|
||||
$title = $name !== '' ? "📊 قیمت لحظهای {$name}" : '📊 قیمت لحظهای';
|
||||
$prices = $this->computeDisplayPrices($boardProduct);
|
||||
|
||||
$message = $this->applyTemplatePlaceholders($template, [
|
||||
'مثقال_فروش' => $prices['mesghal_sell'],
|
||||
'مثقال_خرید' => $prices['mesghal_buy'],
|
||||
'گرم_فروش' => $prices['gram_sell'],
|
||||
'گرم_خرید' => $prices['gram_buy'],
|
||||
'اسم_اپ' => $name,
|
||||
'محصولات' => $this->buildProductLines($products),
|
||||
'عنوان' => $title,
|
||||
'تاریخ' => Verta::now()->format('Y/n/j'),
|
||||
'ساعت' => now()->format('H:i'),
|
||||
'آیدی' => trim((string) $this->config->getString('price_channel_footer_id', '')),
|
||||
'شماره' => trim((string) $this->config->getString('price_channel_footer_phone', '')),
|
||||
'لینک' => trim((string) $this->config->getString('price_channel_footer_link', '')),
|
||||
'فوتر' => $this->buildFooterBlock(),
|
||||
'نام' => $name,
|
||||
]);
|
||||
|
||||
return preg_replace("/\n{3,}/", "\n\n", trim($message)) ?? trim($message);
|
||||
}
|
||||
|
||||
/** @param array<string, string> $replacements */
|
||||
private function applyTemplatePlaceholders(string $template, array $replacements): string
|
||||
{
|
||||
$keys = array_keys($replacements);
|
||||
usort($keys, static fn (string $a, string $b): int => mb_strlen($b) <=> mb_strlen($a));
|
||||
|
||||
$message = $template;
|
||||
foreach ($keys as $key) {
|
||||
$message = preg_replace(
|
||||
'/[%٪]\s*' . preg_quote($key, '/') . '/u',
|
||||
$replacements[$key],
|
||||
$message
|
||||
) ?? $message;
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* محصول مرجع قیمت تابلو — اول آبشده (گرم)، بعد اولین محصول گرم، بعد اولین واجد شرایط.
|
||||
*
|
||||
* @param array<int, Product> $products
|
||||
*/
|
||||
private function resolveBoardProduct(array $products): ?Product
|
||||
{
|
||||
if ($products === []) {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach ($products as $product) {
|
||||
if (trim((string) ($product->group_type ?? '')) === 'آبشده' && $this->isGramUnit($product)) {
|
||||
return $product;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($products as $product) {
|
||||
if ($this->isGramUnit($product)) {
|
||||
return $product;
|
||||
}
|
||||
}
|
||||
|
||||
return $products[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* قیمتهای نمایشی تابلو (گرم + مثقال) — همان منطق اپ + price_channel_diff.
|
||||
*
|
||||
* @return array{gram_buy: string, gram_sell: string, mesghal_buy: string, mesghal_sell: string}
|
||||
*/
|
||||
private function computeDisplayPrices(Product $product): array
|
||||
{
|
||||
$channelDiff = (float) $this->config->getInt('price_channel_diff', 0);
|
||||
$diffBuy = (float) $this->config->displayBuyPriceDiffRial();
|
||||
$diffSell = (float) $this->config->displaySellPriceDiffRial();
|
||||
$mesghal = $this->changeMesghal();
|
||||
$base = (float) ($product->price ?? 0);
|
||||
|
||||
// 🔴 خرید (مشتری میفروشد، پایینتر) — 🟢 فروش (مشتری میخرد، بالاتر)
|
||||
$gramBuy = $base - $diffSell - $channelDiff;
|
||||
$gramSell = $base + $diffBuy + $channelDiff;
|
||||
|
||||
return [
|
||||
'gram_buy' => $this->formatPrice($gramBuy),
|
||||
'gram_sell' => $this->formatPrice($gramSell),
|
||||
'mesghal_buy' => $mesghal > 0 ? $this->formatPrice($gramBuy * $mesghal) : '',
|
||||
'mesghal_sell' => $mesghal > 0 ? $this->formatPrice($gramSell * $mesghal) : '',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* بدنهٔ قیمت محصولات (بدون فوتر) — مبنای تشخیص تغییر قیمت.
|
||||
*
|
||||
* @param array<int, Product> $products
|
||||
*/
|
||||
private function buildProductLines(array $products): string
|
||||
{
|
||||
if ($products === []) {
|
||||
return '';
|
||||
@@ -283,7 +416,6 @@ class PriceChannelBroadcastService
|
||||
$lines[] = '🔴 خرید ' . $this->formatPrice($low) . ' 🟢 فروش ' . $this->formatPrice($high);
|
||||
|
||||
if ($this->isGramUnit($product) && $mesghal > 0) {
|
||||
// قیمت پایه «هر گرم» است؛ مثقال = گرم × ضریب (کنوانسیون اپ: مثقال = گرم × 4.3318)
|
||||
$lines[] = '💰 هر مثقال: ' . $this->formatPrice($low * $mesghal)
|
||||
. ' / ' . $this->formatPrice($high * $mesghal);
|
||||
}
|
||||
@@ -291,25 +423,22 @@ class PriceChannelBroadcastService
|
||||
$lines[] = '';
|
||||
}
|
||||
|
||||
$footer = $this->footerLines();
|
||||
if ($footer !== []) {
|
||||
$lines[] = '➖➖➖➖➖➖';
|
||||
foreach ($footer as $line) {
|
||||
$lines[] = $line;
|
||||
}
|
||||
}
|
||||
|
||||
return trim(implode("\n", $lines));
|
||||
}
|
||||
|
||||
private function header(): string
|
||||
private function buildFooterBlock(): string
|
||||
{
|
||||
$name = trim((string) $this->config->getString('name_fa', ''));
|
||||
$time = now()->format('H:i');
|
||||
$footer = $this->footerLines();
|
||||
if ($footer === []) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$title = $name !== '' ? "📊 قیمت لحظهای {$name}" : '📊 قیمت لحظهای';
|
||||
$lines = ['➖➖➖➖➖➖'];
|
||||
foreach ($footer as $line) {
|
||||
$lines[] = $line;
|
||||
}
|
||||
|
||||
return $title . "\n🕐 ساعت " . $time;
|
||||
return implode("\n", $lines);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -42,6 +42,22 @@ SET @invite_link_desc = 'متن پیام اشتراکگذاری دعوت در
|
||||
SET @deposit_guide_desc = 'متن راهنمای واریز در مودال شارژ حساب. متغیرها: ٪نام یا %نام = نام صاحب حساب؛ ٪کارت یا %کارت = شماره کارت؛ ٪شبا یا %شبا = شبا. فاصله بعد از ٪ اختیاری است. اگر خالی باشد از متن پیشفرض اپ استفاده میشود.';
|
||||
SET @deposit_support_msg_desc = 'متن پیام هنگام کلیک روی «پیام به پشتیبانی» و «پیام به پشتیبانی (sms)» در مودال واریز. همان متغیرهای ٪نام، ٪کارت و ٪شبا. پیشفرض: «شماره حساب».';
|
||||
|
||||
SET @price_channel_message_desc = 'قالب متن پیام ارسالی به کانال. متغیرهای قیمت تابلو: ٪گرم_خرید ٪گرم_فروش ٪مثقال_خرید ٪مثقال_فروش (یا با %). زمان: ٪تاریخ ٪ساعت. اپ: ٪اسم_اپ یا ٪نام (نام فارسی)؛ ٪عنوان = خط «📊 قیمت لحظهای + نام». تماس جدا: ٪آیدی ٪شماره ٪لینک. اختیاری: ٪محصولات (لیست همه محصولات)؛ ٪فوتر (ترکیب آیدی+شماره+لینک). فاصله بعد از ٪ اختیاری است. خالی = قالب پیشفرض.';
|
||||
SET @price_channel_default_text = CONCAT(
|
||||
'سلام 👋', CHAR(10),
|
||||
'%عنوان', CHAR(10),
|
||||
'📅 %تاریخ 🕐 %ساعت', CHAR(10),
|
||||
CHAR(10),
|
||||
'🔴 خرید گرم: %گرم_خرید', CHAR(10),
|
||||
'🟢 فروش گرم: %گرم_فروش', CHAR(10),
|
||||
'🔴 خرید مثقال: %مثقال_خرید', CHAR(10),
|
||||
'🟢 فروش مثقال: %مثقال_فروش', CHAR(10),
|
||||
CHAR(10),
|
||||
'📞 %شماره', CHAR(10),
|
||||
'%آیدی', CHAR(10),
|
||||
'%لینک'
|
||||
);
|
||||
|
||||
-- ستونهای اختیاری settings (بعضی DBهای قدیمی ندارند)
|
||||
SET @sql = IF(
|
||||
(SELECT COUNT(*) FROM information_schema.COLUMNS
|
||||
@@ -379,6 +395,10 @@ SELECT 'price_channel_min_seconds', '120', 'حداقل فاصله ارسال (ث
|
||||
'حداقل فاصله بین دو ارسال به کانال؛ جلوی سیل پیام را میگیرد. صفر = هر تغییر قیمت.', 'number'
|
||||
WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'price_channel_min_seconds' LIMIT 1);
|
||||
|
||||
INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`, `type`)
|
||||
SELECT 'price_channel_message_text', @price_channel_default_text, 'قالب متن پیام کانال', 1, 1, @price_channel_message_desc, 'longtext'
|
||||
WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'price_channel_message_text' LIMIT 1);
|
||||
|
||||
INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`, `type`)
|
||||
SELECT 'price_channel_footer_id', '', 'آیدی کانال در پیام', 1, 1,
|
||||
'اگر پر باشد در انتهای پیام نمایش داده میشود (مثلاً یوزرنیم کانال). خالی = نمایش داده نمیشود.', 'text'
|
||||
@@ -706,7 +726,7 @@ WHERE `key` = 'main_product';
|
||||
-- longtext
|
||||
UPDATE `settings` SET `type` = 'longtext' WHERE `key` IN (
|
||||
'text_rule', 'text_about', 'support_messenger_text', 'invite_link_text',
|
||||
'deposit_support_message_text',
|
||||
'deposit_support_message_text', 'price_channel_message_text',
|
||||
'montzar_order_response', 'montzar_last_product_log'
|
||||
);
|
||||
|
||||
@@ -1127,6 +1147,13 @@ UPDATE `settings` SET `description` = 'نوع پیامرسان برای دک
|
||||
UPDATE `settings` SET `description` = 'شناسه تماس پشتیبانی: یوزرنیم (تلگرام)، شماره (واتساپ/بله) یا آیدی بسته به پیامرسان انتخابشده.' WHERE `key` = 'support_messenger_id';
|
||||
UPDATE `settings` SET `description` = @deposit_guide_desc WHERE `key` = 'support_messenger_text';
|
||||
UPDATE `settings` SET `description` = @deposit_support_msg_desc WHERE `key` = 'deposit_support_message_text';
|
||||
UPDATE `settings` SET `description` = @price_channel_message_desc WHERE `key` = 'price_channel_message_text';
|
||||
UPDATE `settings` SET
|
||||
`title_fa` = 'قالب متن پیام کانال',
|
||||
`type` = 'longtext',
|
||||
`can_edit` = 1,
|
||||
`description` = @price_channel_message_desc
|
||||
WHERE `key` = 'price_channel_message_text';
|
||||
UPDATE `settings` SET `description` = 'متن پیام اشتراکگذاری دعوت در اپ کاربر (دکمه «اشتراک با دوستان» در صفحه اصلی، بخش معرف در پروفایل، صفحه کسب درآمد و مودال اشتراک). متغیرهای جایگزین: ٪نام یا %نام = نام کامل کاربر دعوتکننده؛ ٪لینک یا %لینک = آدرس کامل صفحه ثبتنام همراه با کد معرف (بر اساس تنظیم app_url یا دامنه فعلی مرورگر). فاصله اختیاری بعد از ٪ یا % مجاز است (مثلاً ٪ نام). اگر این فیلد خالی باشد، اپ از متن پیشفرض داخلی استفاده میکند.' WHERE `key` = 'invite_link_text';
|
||||
UPDATE `settings` SET `description` = 'شماره تماس پشتیبانی؛ در صفحه واریز، درباره ما و قوانین نمایش داده میشود. متن پیامک/پشتیبانی از «متن پیام به پشتیبانی (واریز)» خوانده میشود.' WHERE `key` = 'deposit_sms_support_number';
|
||||
|
||||
@@ -1166,10 +1193,21 @@ UPDATE `settings` SET
|
||||
`description` = @deposit_support_msg_desc
|
||||
WHERE `key` = 'deposit_support_message_text';
|
||||
|
||||
INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`, `type`)
|
||||
SELECT 'price_channel_message_text', @price_channel_default_text, 'قالب متن پیام کانال', 1, 1, @price_channel_message_desc, 'longtext'
|
||||
WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'price_channel_message_text' LIMIT 1);
|
||||
|
||||
UPDATE `settings` SET
|
||||
`title_fa` = 'قالب متن پیام کانال',
|
||||
`type` = 'longtext',
|
||||
`can_edit` = 1,
|
||||
`description` = @price_channel_message_desc
|
||||
WHERE `key` = 'price_channel_message_text';
|
||||
|
||||
UPDATE `settings` SET `type` = 'longtext'
|
||||
WHERE `key` IN (
|
||||
'text_rule', 'text_about', 'support_messenger_text', 'invite_link_text',
|
||||
'deposit_support_message_text',
|
||||
'deposit_support_message_text', 'price_channel_message_text',
|
||||
'montzar_order_response', 'montzar_last_product_log'
|
||||
);
|
||||
|
||||
@@ -1360,7 +1398,8 @@ UPDATE `settings` SET `can_edit` = 1 WHERE `key` IN (
|
||||
'deposit_support_message_text', 'deposit_account_holder', 'deposit_card_number', 'deposit_sheba',
|
||||
'text_about', 'text_rule',
|
||||
'price_channel_enabled', 'price_channel_messengers', 'price_channel_diff',
|
||||
'price_channel_min_seconds', 'price_channel_footer_id', 'price_channel_footer_phone',
|
||||
'price_channel_min_seconds', 'price_channel_message_text',
|
||||
'price_channel_footer_id', 'price_channel_footer_phone',
|
||||
'price_channel_footer_link', 'change_mesghal'
|
||||
);
|
||||
|
||||
|
||||
@@ -41,6 +41,22 @@ SET @invite_link_desc = 'متن پیام اشتراکگذاری دعوت در
|
||||
SET @deposit_guide_desc = 'متن راهنمای واریز در مودال شارژ حساب. متغیرها: ٪نام یا %نام = نام صاحب حساب؛ ٪کارت یا %کارت = شماره کارت؛ ٪شبا یا %شبا = شبا. فاصله بعد از ٪ اختیاری است. اگر خالی باشد از متن پیشفرض اپ استفاده میشود.';
|
||||
SET @deposit_support_msg_desc = 'متن پیام هنگام کلیک روی «پیام به پشتیبانی» و «پیام به پشتیبانی (sms)» در مودال واریز. همان متغیرهای ٪نام، ٪کارت و ٪شبا. پیشفرض: «شماره حساب».';
|
||||
|
||||
SET @price_channel_message_desc = 'قالب متن پیام ارسالی به کانال. متغیرهای قیمت تابلو: ٪گرم_خرید ٪گرم_فروش ٪مثقال_خرید ٪مثقال_فروش (یا با %). زمان: ٪تاریخ ٪ساعت. اپ: ٪اسم_اپ یا ٪نام (نام فارسی)؛ ٪عنوان = خط «📊 قیمت لحظهای + نام». تماس جدا: ٪آیدی ٪شماره ٪لینک. اختیاری: ٪محصولات (لیست همه محصولات)؛ ٪فوتر (ترکیب آیدی+شماره+لینک). فاصله بعد از ٪ اختیاری است. خالی = قالب پیشفرض.';
|
||||
SET @price_channel_default_text = CONCAT(
|
||||
'سلام 👋', CHAR(10),
|
||||
'%عنوان', CHAR(10),
|
||||
'📅 %تاریخ 🕐 %ساعت', CHAR(10),
|
||||
CHAR(10),
|
||||
'🔴 خرید گرم: %گرم_خرید', CHAR(10),
|
||||
'🟢 فروش گرم: %گرم_فروش', CHAR(10),
|
||||
'🔴 خرید مثقال: %مثقال_خرید', CHAR(10),
|
||||
'🟢 فروش مثقال: %مثقال_فروش', CHAR(10),
|
||||
CHAR(10),
|
||||
'📞 %شماره', CHAR(10),
|
||||
'%آیدی', CHAR(10),
|
||||
'%لینک'
|
||||
);
|
||||
|
||||
-- ستونهای اختیاری settings (بعضی DBهای قدیمی ندارند)
|
||||
SET @sql = IF(
|
||||
(SELECT COUNT(*) FROM information_schema.COLUMNS
|
||||
|
||||
@@ -11,6 +11,22 @@
|
||||
START TRANSACTION;
|
||||
SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
SET @price_channel_message_desc = 'قالب متن پیام ارسالی به کانال. متغیرهای قیمت تابلو: ٪گرم_خرید ٪گرم_فروش ٪مثقال_خرید ٪مثقال_فروش (یا با %). زمان: ٪تاریخ ٪ساعت. اپ: ٪اسم_اپ یا ٪نام (نام فارسی)؛ ٪عنوان = خط «📊 قیمت لحظهای + نام». تماس جدا: ٪آیدی ٪شماره ٪لینک. اختیاری: ٪محصولات (لیست همه محصولات)؛ ٪فوتر (ترکیب آیدی+شماره+لینک). فاصله بعد از ٪ اختیاری است. خالی = قالب پیشفرض.';
|
||||
SET @price_channel_default_text = CONCAT(
|
||||
'سلام 👋', CHAR(10),
|
||||
'%عنوان', CHAR(10),
|
||||
'📅 %تاریخ 🕐 %ساعت', CHAR(10),
|
||||
CHAR(10),
|
||||
'🔴 خرید گرم: %گرم_خرید', CHAR(10),
|
||||
'🟢 فروش گرم: %گرم_فروش', CHAR(10),
|
||||
'🔴 خرید مثقال: %مثقال_خرید', CHAR(10),
|
||||
'🟢 فروش مثقال: %مثقال_فروش', CHAR(10),
|
||||
CHAR(10),
|
||||
'📞 %شماره', CHAR(10),
|
||||
'%آیدی', CHAR(10),
|
||||
'%لینک'
|
||||
);
|
||||
|
||||
-- توکن روبیکا (توکن بله/تلگرام از قبل موجودند) — سیستمی (can_edit=0)
|
||||
INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`)
|
||||
SELECT 'rubika_bot_token', '', 'توکن بات روبیکا', 0, 1, NULL
|
||||
@@ -39,6 +55,17 @@ SELECT 'price_channel_min_seconds', '120', 'حداقل فاصله ارسال (ث
|
||||
'حداقل فاصله بین دو ارسال به کانال؛ جلوی سیل پیام را میگیرد. صفر = هر تغییر قیمت.', 'number'
|
||||
WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'price_channel_min_seconds' LIMIT 1);
|
||||
|
||||
INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`, `type`)
|
||||
SELECT 'price_channel_message_text', @price_channel_default_text, 'قالب متن پیام کانال', 1, 1, @price_channel_message_desc, 'longtext'
|
||||
WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'price_channel_message_text' LIMIT 1);
|
||||
|
||||
UPDATE `settings` SET
|
||||
`title_fa` = 'قالب متن پیام کانال',
|
||||
`type` = 'longtext',
|
||||
`can_edit` = 1,
|
||||
`description` = @price_channel_message_desc
|
||||
WHERE `key` = 'price_channel_message_text';
|
||||
|
||||
INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`, `type`)
|
||||
SELECT 'price_channel_footer_id', '', 'آیدی کانال در پیام', 1, 1,
|
||||
'اگر پر باشد در انتهای پیام نمایش داده میشود (مثلاً یوزرنیم کانال). خالی = نمایش داده نمیشود.', 'text'
|
||||
@@ -82,7 +109,8 @@ UPDATE `settings` SET `can_edit` = 0 WHERE `key` IN (
|
||||
);
|
||||
UPDATE `settings` SET `can_edit` = 1 WHERE `key` IN (
|
||||
'price_channel_enabled', 'price_channel_messengers', 'price_channel_diff',
|
||||
'price_channel_min_seconds', 'price_channel_footer_id', 'price_channel_footer_phone',
|
||||
'price_channel_min_seconds', 'price_channel_message_text',
|
||||
'price_channel_footer_id', 'price_channel_footer_phone',
|
||||
'price_channel_footer_link', 'change_mesghal'
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user