From 6c393ecb943e1c29582d3ea3665eb3c85dfce942 Mon Sep 17 00:00:00 2001 From: adonis Date: Tue, 30 Jun 2026 22:19:38 +0330 Subject: [PATCH] fix bugs --- .htaccess | 14 ++ .../menuPages/configuration/settingGroups.ts | 2 +- .../menuPages/configuration/settingTypes.ts | 198 ++++++++++++++++-- 3 files changed, 199 insertions(+), 15 deletions(-) create mode 100644 .htaccess diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000..108ccfe --- /dev/null +++ b/.htaccess @@ -0,0 +1,14 @@ + + + Options -MultiViews -Indexes + + + # Handle Front Controller... + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_FILENAME} !-f + #RewriteBase / + RewriteRule ^ /admin/index.html [L] + + + + diff --git a/src/pages/menuPages/configuration/settingGroups.ts b/src/pages/menuPages/configuration/settingGroups.ts index bea0208..53fecce 100644 --- a/src/pages/menuPages/configuration/settingGroups.ts +++ b/src/pages/menuPages/configuration/settingGroups.ts @@ -82,7 +82,7 @@ export const EDITABLE_SETTING_GROUPS: SettingGroupDef[] = [ id: 'features', title: 'قابلیت‌های سیستم', icon: 'vuesax-linear:setting-2', - match: (k) => /^(product_|main_wallet_products|price_from_nasiryan|profit_gold)/.test(k) + match: (k) => /^(product_|main_wallet_products|profit_gold)/.test(k) }, { id: 'misc', diff --git a/src/pages/menuPages/configuration/settingTypes.ts b/src/pages/menuPages/configuration/settingTypes.ts index 7d5cf48..68e9608 100644 --- a/src/pages/menuPages/configuration/settingTypes.ts +++ b/src/pages/menuPages/configuration/settingTypes.ts @@ -6,18 +6,17 @@ export type SettingFieldType = 'text' | 'number' | 'price' | 'switch' | 'select' /** کلیدهای legacy — در پنل نمایش داده نمی‌شوند */ export const HIDDEN_LEGACY_SETTING_KEYS = new Set([ 'main_product_price', - 'montzar_price', 'etehadie_api_url', 'goldir_price', 'price_primary_source', 'price_method', 'montzar_last_product_log', 'montzar_order_response', - 'service_charge_percentage' + 'service_charge_percentage', ]) /** فقط وقتی is_store فعال است در پنل دیده می‌شوند */ -export const STORE_ONLY_SETTING_KEYS = new Set(['store_status', 'price_from_nasiryan']) +export const STORE_ONLY_SETTING_KEYS = new Set(['store_status']) export function isSettingLocked(canEdit: Const['can_edit']): boolean { return canEdit === 0 || canEdit === false || canEdit === '0' @@ -90,7 +89,6 @@ const KEY_TYPE_FALLBACK: Record = { payping_fin_sync_enabled: 'switch', external_order_api_enabled: 'switch', is_store: 'switch', - price_from_nasiryan: 'switch', banner_enabled: 'switch', apk_download_link: 'text', node_client_id: 'text', @@ -224,34 +222,206 @@ export function switchLabels(key: string | undefined): { on: string; off: string return { on: 'فعال', off: 'غیرفعال' } } -/** توضیحات کامل و ساده برای کلیدهای مهم — اگر description در دیتابیس خالی بود استفاده می‌شود */ +/** توضیحات ساده و فارسی برای پنل — بر توضیح دیتابیس (که ممکن است نام فنی انگلیسی داشته باشد) اولویت دارد */ const KEY_HELP_FALLBACK: Record = { + name_fa: + 'نام فارسی برند که در پیامک‌ها، عنوان صفحات و بخش‌های عمومی اپ به مشتری نشان داده می‌شود.', + open_register: + 'روشن: کاربران جدید می‌توانند ثبت‌نام کنند. خاموش: فقط ورود کاربران قبلی مجاز است.', + auto_active_customer: + 'روشن: حساب بلافاصله پس از ثبت‌نام فعال می‌شود. خاموش: نیاز به تأیید دستی شما در پنل دارد.', close_price: - 'فیلتر اصلی فروشگاه. وقتی روشن باشد، خرید و فروش و نمایش قیمت فقط در بازهٔ «ساعت شروع» تا «ساعت پایان» انجام می‌شود و خارج از این بازه به مشتری پیام «فروشگاه بسته است» نشان داده می‌شود. اگر خاموش باشد، فروشگاه همیشه باز است (مگر اینکه برای محصولی به‌صورت اختصاصی ساعت تعریف کرده باشید).', + 'فیلتر اصلی فروشگاه. وقتی روشن باشد، خرید و فروش و نمایش قیمت فقط بین «ساعت شروع» و «ساعت پایان» انجام می‌شود و خارج از این بازه به مشتری «فروشگاه بسته است» نشان داده می‌شود. خاموش: محدودیت ساعتی سراسری اعمال نمی‌شود (مگر برای محصولی ساعت اختصاصی تعریف کرده باشید).', startDay: - 'ساعت شروع فعالیت فروشگاه. فقط وقتی «بستن خودکار خارج از ساعت کاری» روشن باشد اعمال می‌شود. ساعت را از روی ساعت‌شمار انتخاب کنید (مثلاً ۰۹:۰۰).', + 'ساعت شروع فعالیت روزانه فروشگاه. فقط وقتی «بستن خودکار خارج از ساعت کاری» روشن باشد اعمال می‌شود. از ساعت‌شمار انتخاب کنید (مثلاً ۰۹:۰۰).', endDay: - 'ساعت پایان فعالیت فروشگاه. فقط وقتی «بستن خودکار خارج از ساعت کاری» روشن باشد اعمال می‌شود. بعد از این ساعت فروشگاه بسته می‌شود (مثلاً ۱۷:۰۰).', + 'ساعت پایان فعالیت روزانه فروشگاه. فقط وقتی «بستن خودکار خارج از ساعت کاری» روشن باشد اعمال می‌شود. بعد از این ساعت فروشگاه بسته می‌شود (مثلاً ۱۷:۰۰ یا ۲۲:۰۰).', show_last_price: - 'وقتی قیمت زندهٔ لحظه‌ای در دسترس نباشد: اگر روشن باشد، آخرین قیمت ذخیره‌شده در دیتابیس به مشتری نشان داده می‌شود؛ اگر خاموش باشد، به‌جای قیمت صفر پیام «مظنه در دسترس نیست» نمایش داده می‌شود.' + 'وقتی قیمت زنده در دسترس نباشد: روشن = آخرین قیمت ذخیره‌شده نشان داده می‌شود؛ خاموش = به‌جای صفر پیام «مظنه در دسترس نیست» نمایش داده می‌شود.', + fee_single: + 'اختلاف پایه (ریال) بین قیمت خرید و فروش روی مظنه. معمولاً نصف فاصله اسپرد کل است.', + buy_fee: + 'مبلغ اضافه (ریال) روی قیمت پایه برای سمت خرید. اگر خالی بگذارید، از «اختلاف پایه» استفاده می‌شود.', + sell_fee: + 'مبلغ کسر (ریال) از قیمت پایه برای سمت فروش. اگر خالی بگذارید، از «اختلاف پایه» استفاده می‌شود.', + fee_service_charge_percentage: + 'درصد کارمزد هر معامله از مبلغ سفارش (اعشاری؛ مثلاً ۰٫۰۰۵ یعنی نیم در هزار).', + fee_free: + 'تعداد اولین سفارش‌های هر کاربر که از کارمزد معاف می‌شوند. صفر یعنی غیرفعال.', + min_withdraw: + 'حداقل مبلغ درخواست برداشت (ریال). درخواست‌های کمتر پذیرفته نمی‌شوند.', + min_first_buy: + 'حداقل مبلغ اولین خرید هر کاربر (ریال).', + minimum_sell: + 'حداقل مقدار یا مبلغ مجاز برای ثبت سفارش فروش.', + balance_report_exclude_customer_id: + 'شناسه عددی مشتری که از گزارش تراز و آمار حذف می‌شود (مثلاً حساب آزمایشی). چند شناسه را با ویرگول جدا کنید.', + text_rule: + 'متن کامل قوانین و مقررات که در صفحه قوانین اپ به مشتری نشان داده می‌شود.', + text_about: + 'متن «درباره ما» شامل معرفی مجموعه، راه‌های ارتباطی و توضیح خدمات.', + referral_id: + 'روشن: وارد کردن کد معرف در ثبت‌نام اجباری است. خاموش: کد معرف اختیاری است.', + gift_for_referrer: + 'مقدار پاداش (معمولاً وزن فلز به گرم) که پس از ثبت‌نام موفق معرف‌شونده به کیف معرف واریز می‌شود.', + gift_for_referral: + 'مقدار پاداش (معمولاً وزن فلز) که به کاربر تازه‌ثبت‌نام‌شده داده می‌شود. صفر یعنی بدون پاداش.', + register_referral_sms_to_referrer: + 'روشن: پس از ثبت‌نام کاربر جدید، پیامک اطلاع‌رسانی برای معرف ارسال می‌شود.', + register_referral_bonus_message: + 'روشن: متن پاداش معرف در پیامک خوش‌آمد ثبت‌نام گنجانده می‌شود.', + referral_limit: + 'حداکثر تعداد دعوت مجاز برای هر کاربر. خالی = بدون محدودیت.', + referral_bonus_amount: + 'مبلغ یا مقدار پاداش معرف برای نمایش در پیامک‌ها و متن‌های دعوت.', + jibit_verification: + 'روشن: هنگام ثبت یا ویرایش کارت بانکی، تطبیق با سرویس احراز هویت جیبیت انجام می‌شود.', + register_jibit_verify: + 'روشن: در ثبت‌نام، تطبیق کد ملی و شماره موبایل از طریق جیبیت انجام می‌شود.', + has_page_earn_money: + 'روشن: منوی «کسب درآمد / دعوت دوستان» در اپ مشتری نمایش داده می‌شود.', + invite_link_text: + 'متن پیام اشتراک‌گذاری دعوت. می‌توانید از ٪نام برای نام کاربر و ٪لینک برای لینک ثبت‌نام با کد معرف استفاده کنید. خالی = متن پیش‌فرض اپ.', + montzar_mobile: + 'شماره موبایل حساب اتصال به سرویس همکار قیمت.', + montzar_password: + 'رمز عبور حساب اتصال به سرویس همکار قیمت. محرمانه نگه دارید.', + montzar_product_id: + 'شناسه محصول مرجع در سرویس همکار قیمت.', + montzar_base_url: + 'آدرس پایه سرور سرویس همکار (بدون اسلش انتهایی).', + montzar_open_buy: + 'روشن: ثبت سفارش خرید از طریق قیمت همکار مجاز است (وضعیت واقعی از سرویس خارجی خوانده می‌شود).', + montzar_open_sell: + 'روشن: ثبت سفارش فروش از طریق قیمت همکار مجاز است.', + montzar_closed: + 'وضعیت گزارش‌شده از سرویس همکار؛ فقط برای نمایش — این سوییچ را دستی تغییر ندهید.', + external_order_api_enabled: + 'روشن: دریافت کیف پول و ثبت سفارش از سرویس فروشگاه خارجی فعال است.', + node_client_id: + 'شناسه کلاینت برای اتصال امن به سرویس سفارش خارجی.', + node_shared_secret: + 'کلید مشترک امضای درخواست‌ها به سرویس سفارش خارجی. محرمانه نگه دارید.', + support_messenger: + 'پیام‌رسانی که دکمه پشتیبانی در اپ مشتری به آن هدایت می‌کند.', + support_messenger_id: + 'شناسه تماس پشتیبانی: یوزرنیم، شماره یا آیدی بسته به پیام‌رسان انتخاب‌شده.', + support_messenger_text: + 'متن کوتاه کنار دکمه پشتیبانی در اپ مشتری.', + deposit_sms_support_number: + 'شماره پشتیبانی واریز؛ در صفحه شارژ حساب دکمه پیامک با متن شماره حساب نشان داده می‌شود.', + charge_notif: + 'روشن: پس از شارژ کیف توسط ادمین، پیامک به مشتری ارسال می‌شود.', + group_sms: + 'روشن: امکان ارسال پیامک گروهی از پنل ادمین فعال است.', + profit_gold_api_enabled: + 'روشن: محاسبه سود طلا از API خارجی فعال است. در اکثر نصب‌ها خاموش می‌ماند.', + default_vc_number: + 'پیشوند اختیاری برای شماره‌گذاری حواله‌ها در حسابداری خارجی. خالی = بدون پیشوند.', + unit: + 'واحد نمایش وزن در دارایی‌ها، کیف پول و جزئیات معاملات (گرم یا کیلوگرم).', + chart_use_local_data: + 'روشن: نمودار از تاریخچه ذخیره‌شده در دیتابیس خودتان. خاموش: از سرویس تابلو آنلاین.', + chart_id: + 'شناسه نمودار در سرویس تابلو. خالی = شناسه پیش‌فرض سرویس.', + price_provider: + 'منبع دریافت قیمت لحظه‌ای برای اپ مشتری و همگام‌سازی محصولات.', + main_product: + 'شناسه یا نام محصول مرجع آبشده. وقتی منبع قیمت «محصول مرجع» باشد برای محاسبه استفاده می‌شود.', + zaarbox_api_url: + 'آدرس پایه API سرویس تابلو آنلاین.', + zaarbox_price_key: + 'شناسه ردیف قیمت در پاسخ سرویس تابلو.', + payping_fin_sync_enabled: + 'روشن: پس از واریز یا برداشت، تراکنش به سامانه حسابداری مالی همگام می‌شود.', + payping_fin_url: + 'آدرس ثبت تراکنش در سامانه حسابداری مالی.', + payping_fin_token: + 'توکن احراز هویت سامانه حسابداری مالی.', + payping_fin_customer_id: + 'شناسه مشتری در سامانه حسابداری که تراکنش‌ها به نام آن ثبت می‌شوند.', + payping_gateway_name: + 'نام درگاه پرداخت فعال که به واسط درگاه ارسال می‌شود.', + payping_gateway_item: + 'کد درگاه (تکی). اگر لیست چرخشی درگاه پر باشد، اولویت با آن است.', + payping_gateway_items: + 'لیست کدهای درگاه با ویرگول برای چرخش بین چند پذیرنده. خالی = استفاده از کد تکی.', + payping_start_url: + 'آدرس API شروع پرداخت (هدایت مشتری به درگاه).', + payping_verify_url: + 'آدرس API تأیید پرداخت پس از بازگشت از درگاه.', + payping_round_toman: + 'روشن: مبلغ پرداخت به نزدیک‌ترین تومان گرد می‌شود. خاموش: مبلغ دقیق ریالی.', + payping_strict_failed_withdraw: + 'روشن: در صورت برداشت ناموفق قبلی، تسویه جدید با احتیاط بیشتر انجام می‌شود.', + send_to_tahesab: + 'روشن: واریز و برداشت مشتریان به‌صورت خودکار به ته‌حساب ارسال می‌شود.', + tahesab_host: + 'آدرس سرور نرم‌افزار ته‌حساب در شبکه.', + tahesab_port: + 'شماره پورت اتصال به ته‌حساب.', + tahesab_token: + 'توکن اتصال به ته‌حساب. از پنل ته‌حساب دریافت می‌شود.', + tahesab_db: + 'نام پایگاه داده در ته‌حساب که سند به آن ارسال می‌شود.', + tahesab_bank_account: + 'نام یا کد حساب بانکی در سند واریز/برداشت ته‌حساب.', + montify_name: + 'نام فروشگاه که در درگاه پرداخت و رسید بانکی به مشتری نشان داده می‌شود.', + app_url: + 'آدرس کامل وب‌اپ مشتری (با https). در پیامک‌ها و بازگشت از درگاه استفاده می‌شود.', + admin_url: + 'آدرس کامل پنل مدیریت (با https).', + main_product_price: + 'تنظیم قدیمی — از «منبع قیمت» استفاده کنید. روشن نگه داشتن توصیه نمی‌شود.' } -/** برچسب فارسی ساده برای کلیدهای مهم — اگر سرور برچسبی نفرستد */ +/** برچسب فارسی ساده — اگر سرور برچسبی نفرستد یا برچسب فنی باشد */ export const KEY_LABEL_FALLBACK: Record = { close_price: 'بستن خودکار خارج از ساعت کاری', startDay: 'ساعت شروع', endDay: 'ساعت پایان', - show_last_price: 'نمایش آخرین قیمت ذخیره‌شده' + show_last_price: 'نمایش آخرین قیمت ذخیره‌شده', + fee_single: 'اختلاف پایه خرید/فروش', + buy_fee: 'اضافه قیمت خرید', + sell_fee: 'کسر قیمت فروش', + fee_service_charge_percentage: 'درصد کارمزد معامله', + fee_free: 'معافیت کارمزد سفارش اول', + min_withdraw: 'حداقل مبلغ برداشت', + min_first_buy: 'حداقل اولین خرید', + minimum_sell: 'حداقل مقدار فروش', + referral_id: 'کد معرف اجباری', + open_register: 'ثبت‌نام باز', + auto_active_customer: 'فعال‌سازی خودکار پس از ثبت‌نام', + balance_report_exclude_customer_id: 'حذف مشتری از گزارش تراز', + chart_use_local_data: 'نمودار از داده داخلی', + chart_id: 'شناسه نمودار تابلو', + price_provider: 'منبع قیمت', + main_product: 'محصول مرجع قیمت', + montzar_open_buy: 'خرید از همکار', + montzar_open_sell: 'فروش از همکار', + external_order_api_enabled: 'API سفارش خارجی', + payping_fin_sync_enabled: 'همگام‌سازی با حسابداری مالی', + send_to_tahesab: 'ارسال خودکار به ته‌حساب', + support_messenger: 'پیام‌رسان پشتیبانی', + deposit_sms_support_number: 'شماره پشتیبانی واریز' } export function helpText(row: Const): string { + const key = (row.key ?? '').trim() + if (key && KEY_HELP_FALLBACK[key]) { + return KEY_HELP_FALLBACK[key] + } + const desc = (row.description || '').trim() if (!desc) { - return (row.key && KEY_HELP_FALLBACK[row.key]) || '' + return '' + } + if (resolveSettingFieldType(row) === 'select' && desc.includes('|')) { + return desc.split('|')[0]?.trim() ?? '' } if (resolveSettingFieldType(row) === 'select' && desc.includes(',')) { - const parts = desc.split('|') - return parts.length > 1 ? parts[0].trim() : '' + return '' } return desc }