fix bug and added options

This commit is contained in:
2026-07-12 18:30:09 +03:30
parent fad305cd29
commit e0e3ec94f3
4 changed files with 228 additions and 3 deletions
@@ -10,6 +10,13 @@
<template #unCheckedChildren>{{ labels.off }}</template>
</a-switch>
<SupportMessengersField
v-else-if="isSupportMessengers"
:model-value="modelValue"
:disabled="disabled"
@update:value="emit('update:value', $event)"
/>
<MainWalletProductsField
v-else-if="isMainWalletProducts"
:model-value="modelValue"
@@ -109,6 +116,7 @@
<script setup lang="ts">
import MainWalletProductsField from './MainWalletProductsField.vue'
import SupportMessengersField from './SupportMessengersField.vue'
import ZaarboxPriceKeyField from './ZaarboxPriceKeyField.vue'
import {
parseSelectOptions,
@@ -145,6 +153,7 @@ const fieldType = computed<SettingFieldType>(() =>
const isZaarboxPriceKey = computed(() => props.settingKey === 'zaarbox_price_key')
const isMainWalletProducts = computed(() => props.settingKey === 'main_wallet_products')
const isSupportMessengers = computed(() => props.settingKey === 'support_messengers')
const selectItems = computed(() =>
parseSelectOptions({
@@ -0,0 +1,140 @@
<template>
<div class="support-messengers-field">
<div
v-for="(row, index) in rows"
:key="index"
class="support-messengers-field__row"
>
<a-select
:value="row.messenger || undefined"
:disabled="disabled"
allow-clear
placeholder="پیام‌رسان"
class="support-messengers-field__type"
@update:value="(val) => updateRow(index, { messenger: String(val ?? '') })"
>
<a-select-option v-for="opt in messengerOptions" :key="opt.key" :value="opt.key">
{{ opt.value }}
</a-select-option>
</a-select>
<a-input
:value="row.id"
:disabled="disabled"
allow-clear
class="support-messengers-field__id"
:placeholder="supportMessengerIdPlaceholder(row.messenger)"
@update:value="(val) => updateRow(index, { id: String(val ?? '') })"
/>
<a-button
type="text"
danger
:disabled="disabled || rows.length <= 1"
aria-label="حذف"
@click="removeRow(index)"
>
حذف
</a-button>
</div>
<a-button
type="dashed"
block
:disabled="disabled"
class="support-messengers-field__add"
@click="addRow"
>
افزودن پیام‌رسان
</a-button>
<p v-if="rows.length === 0" class="support-messengers-field__hint">
حداقل یک پیام‌رسان با شناسه معتبر اضافه کنید.
</p>
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import {
formatSupportMessengers,
parseSelectOptions,
parseSupportMessengers,
supportMessengerIdPlaceholder,
type SupportMessengerEntryDraft,
} from './settingTypes'
const props = withDefaults(
defineProps<{
modelValue: string
disabled?: boolean
}>(),
{ disabled: false },
)
const emit = defineEmits<{ 'update:value': [value: string] }>()
const messengerOptions = computed(() =>
parseSelectOptions({
key: 'support_messenger',
description: 'bale,telegram,whatsapp,rubika,eitaa,soroush',
type: 'select',
}),
)
const rows = computed<SupportMessengerEntryDraft[]>({
get() {
const parsed = parseSupportMessengers(props.modelValue)
if (parsed.length > 0) return parsed
return [{ messenger: 'bale', id: '' }]
},
set(nextRows) {
emit('update:value', formatSupportMessengers(nextRows))
},
})
function commit(nextRows: SupportMessengerEntryDraft[]) {
emit('update:value', formatSupportMessengers(nextRows))
}
function updateRow(index: number, patch: Partial<SupportMessengerEntryDraft>) {
const next = rows.value.map((row, i) => (i === index ? { ...row, ...patch } : row))
commit(next)
}
function addRow() {
commit([...rows.value, { messenger: 'bale', id: '' }])
}
function removeRow(index: number) {
const next = rows.value.filter((_, i) => i !== index)
commit(next.length > 0 ? next : [{ messenger: 'bale', id: '' }])
}
</script>
<style scoped>
.support-messengers-field {
display: flex;
flex-direction: column;
gap: 10px;
}
.support-messengers-field__row {
display: grid;
grid-template-columns: minmax(120px, 160px) 1fr auto;
gap: 8px;
align-items: center;
}
.support-messengers-field__hint {
margin: 0;
font-size: 12px;
color: #6b7280;
}
@media (max-width: 640px) {
.support-messengers-field__row {
grid-template-columns: 1fr;
}
}
</style>
@@ -71,7 +71,8 @@ export const EDITABLE_SETTING_GROUPS: SettingGroupDef[] = [
title: 'پشتیبانی',
icon: 'vuesax-linear:headphone',
match: (k) =>
k.startsWith('support_messenger')
k === 'support_messengers'
|| k.startsWith('support_messenger_')
|| k === 'deposit_sms_support_number'
|| k.startsWith('deposit_'),
},
@@ -171,7 +172,7 @@ export const SYSTEM_SETTING_GROUPS: SettingGroupDef[] = [
id: 'infra',
title: 'زیرساخت',
icon: 'vuesax-linear:cpu',
match: (k) => /^(wss_enabled|sse_path|profit_gold_api_enabled)/.test(k)
match: (k) => /^(wss_enabled|sse_path|profit_gold_api_enabled|tracking_systems)$/.test(k)
},
{
id: 'misc',
@@ -48,6 +48,67 @@ export function normalizeMainWalletProductsValue(value: string | undefined | nul
return formatted || MAIN_WALLET_PRODUCTS_DEFAULT
}
export type SupportMessengerEntryDraft = {
messenger: string
id: string
}
const SUPPORT_MESSENGER_TYPES = ['bale', 'telegram', 'whatsapp', 'rubika', 'eitaa', 'soroush'] as const
export function isSupportMessengerType(value: string | undefined | null): boolean {
const type = (value ?? '').trim().toLowerCase()
return SUPPORT_MESSENGER_TYPES.includes(type as (typeof SUPPORT_MESSENGER_TYPES)[number])
}
/** پارس setting `support_messengers` — JSON یا legacy تک‌مورد */
export function parseSupportMessengers(value: string | undefined | null): SupportMessengerEntryDraft[] {
const raw = (value ?? '').trim()
if (!raw) return []
try {
const decoded = JSON.parse(raw)
if (!Array.isArray(decoded)) return []
return decoded
.map((row) => ({
messenger: String(row?.messenger ?? '').trim().toLowerCase(),
id: String(row?.id ?? '').trim(),
}))
.filter((row) => isSupportMessengerType(row.messenger) && row.id !== '')
} catch {
return []
}
}
export function formatSupportMessengers(entries: SupportMessengerEntryDraft[]): string {
const normalized = entries
.map((row) => ({
messenger: (row.messenger ?? '').trim().toLowerCase(),
id: (row.id ?? '').trim(),
}))
.filter((row) => isSupportMessengerType(row.messenger) && row.id !== '')
if (normalized.length === 0) return ''
return JSON.stringify(normalized, null, 0)
}
export function supportMessengerIdPlaceholder(messenger?: string): string {
switch ((messenger ?? '').trim().toLowerCase()) {
case 'whatsapp':
return 'شماره با کد کشور، مثلاً 989121234567'
case 'bale':
return 'یوزرنیم بله یا لینک ble.ir'
case 'telegram':
return 'یوزرنیم تلگرام بدون @'
case 'rubika':
case 'eitaa':
case 'soroush':
return 'یوزرنیم یا آیدی'
default:
return 'شناسه / یوزرنیم / شماره'
}
}
/** کلیدهای legacy — در پنل نمایش داده نمی‌شوند */
export const HIDDEN_LEGACY_SETTING_KEYS = new Set([
'main_product_price',
@@ -58,6 +119,8 @@ export const HIDDEN_LEGACY_SETTING_KEYS = new Set([
'montzar_last_product_log',
'montzar_order_response',
'service_charge_percentage',
'support_messenger',
'support_messenger_id',
])
/** فقط وقتی is_store فعال است در پنل دیده می‌شوند */
@@ -150,6 +213,8 @@ const KEY_TYPE_FALLBACK: Record<string, SettingFieldType> = {
pargar_username: 'text',
pargar_password: 'text',
pargar_api_token: 'text',
support_messengers: 'longtext',
tracking_systems: 'longtext',
support_messenger_id: 'text',
support_messenger_text: 'longtext',
deposit_support_message_text: 'longtext',
@@ -293,6 +358,9 @@ export function formatValueForSave(
if (key === 'main_wallet_products') {
return normalizeMainWalletProductsValue(value)
}
if (key === 'support_messengers') {
return formatSupportMessengers(parseSupportMessengers(value))
}
return value ?? ''
}
@@ -396,6 +464,10 @@ const KEY_HELP_FALLBACK: Record<string, string> = {
'شناسه کلاینت برای اتصال امن به سرویس سفارش خارجی.',
node_shared_secret:
'کلید مشترک امضای درخواست‌ها به سرویس سفارش خارجی. محرمانه نگه دارید.',
support_messengers:
'لیست پیام‌رسان‌های پشتیبانی. اگر چند مورد باشد، با کلیک دکمه شناور منوی انتخاب باز می‌شود؛ اگر یک مورد باشد مستقیم باز می‌شود. تماس تلفنی جداگانه از «شماره تماس پشتیبانی» است.',
tracking_systems:
'لیست JSON سامانه‌های ردیابی/آنالیتیکس در اپ مشتری. هر مورد: type (gtag، gtm، clarity، custom)، id (کد اندازه‌گیری یا شناسه پروژه)، enabled (روشن/خاموش). فقط از صفحه دیپلوی قابل ویرایش است.',
support_messenger:
'پیام‌رسانی که آیکون کناری و دکمه شناور پشتیبانی در اپ مشتری (درباره ما، قوانین، آموزش و راهنمای واریز) به آن هدایت می‌کند.',
support_messenger_id:
@@ -549,6 +621,8 @@ export const KEY_LABEL_FALLBACK: Record<string, string> = {
accounting_provider: 'سیستم حسابداری',
send_to_tahesab: 'ارسال خودکار به ته‌حساب (قدیمی)',
send_to_pargar: 'ارسال خودکار به پرگار (قدیمی)',
support_messengers: 'پیام‌رسان‌های پشتیبانی',
tracking_systems: 'سامانه‌های ردیابی',
support_messenger: 'پیام‌رسان پشتیبانی',
support_messenger_id: 'شناسه پشتیبانی',
support_messenger_text: 'متن راهنمای واریز',
@@ -597,6 +671,7 @@ export const SETTING_LOCKED_KEYS = new Set([
'send_to_tahesab', 'send_to_pargar', 'accounting_provider', 'service_charge_percentage',
'sse_path',
'tahesab_bank_account', 'tahesab_db', 'tahesab_host', 'tahesab_port', 'tahesab_token',
'tracking_systems',
'pargar_api_token', 'pargar_password', 'pargar_username',
'telegram_bot_token', 'rubika_bot_token',
'price_channel_bale_to', 'price_channel_telegram_to', 'price_channel_rubika_to',
@@ -626,7 +701,7 @@ export const SETTING_EDITABLE_KEYS = new Set([
'referral_bonus_amount', 'referral_id', 'referral_limit', 'referral_gift_on_first_order',
'register_jibit_verify', 'register_referral_bonus_message', 'register_referral_sms_to_referrer',
'sell_fee', 'show_last_price', 'show_gold_ounce_price', 'startDay',
'support_messenger', 'support_messenger_id', 'support_messenger_text',
'support_messengers', 'support_messenger_text',
'deposit_support_message_text', 'deposit_account_holder', 'deposit_card_number', 'deposit_sheba',
'text_about', 'text_rule',
'zaarbox_price_key',