setting in better position
This commit is contained in:
@@ -24,7 +24,7 @@
|
|||||||
:setting-type="settingType"
|
:setting-type="settingType"
|
||||||
:description="description"
|
:description="description"
|
||||||
:disabled="readonly"
|
:disabled="readonly"
|
||||||
:rows="fieldType === 'longtext' ? 4 : 6"
|
:rows="fieldType === 'longtext' ? 6 : 6"
|
||||||
@update:value="emit('update:value', $event)"
|
@update:value="emit('update:value', $event)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -262,7 +262,7 @@ const otherRows = computed(() =>
|
|||||||
)
|
)
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// گروهبندی تنظیمات (برای کالپس جذاب + سرچ هوشمند)
|
// گروهبندی تنظیمات — اولین match برنده است؛ misc فقط برای باقیمانده
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
const SETTING_GROUPS: Array<{
|
const SETTING_GROUPS: Array<{
|
||||||
id: string
|
id: string
|
||||||
@@ -272,9 +272,12 @@ const SETTING_GROUPS: Array<{
|
|||||||
}> = [
|
}> = [
|
||||||
{
|
{
|
||||||
id: 'general',
|
id: 'general',
|
||||||
title: 'عمومی و اطلاعات اپ',
|
title: 'عمومی و برند اپ',
|
||||||
icon: 'vuesax-linear:home-2',
|
icon: 'vuesax-linear:home-2',
|
||||||
match: (k) => /^(name_fa|app_url|admin_url|metal_type|unit$|open_register|auto_active_customer|is_store)/.test(k)
|
match: (k) =>
|
||||||
|
/^(name_fa|name_en|app_url|admin_url|bace_url|server_url|logo_|title_pwa|title_fav|metal_type|unit$|open_register|auto_active_customer|store_status|key$)/.test(
|
||||||
|
k
|
||||||
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'chart',
|
id: 'chart',
|
||||||
@@ -284,37 +287,75 @@ const SETTING_GROUPS: Array<{
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'pricing',
|
id: 'pricing',
|
||||||
title: 'قیمتگذاری و تابلو',
|
title: 'قیمتگذاری، کارمزد و تابلو',
|
||||||
icon: 'vuesax-linear:dollar-circle',
|
icon: 'vuesax-linear:dollar-circle',
|
||||||
match: (k) =>
|
match: (k) =>
|
||||||
/^(fee_|buy_fee|sell_fee|min_|price_provider|zaarbox_|main_product$|show_last_price|close_price|startDay|endDay)/.test(k) ||
|
/^(fee_|buy_fee|sell_fee|min_|minimum_|price_provider|zaarbox_|main_product$|show_last_price|close_price|startDay|endDay|up_price|down_price|price_extreme_date|balance_report_exclude)/.test(
|
||||||
k.includes('charge_percentage')
|
k
|
||||||
|
) || k.includes('charge_percentage')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'content',
|
||||||
|
title: 'متنهای اپ (قوانین و درباره)',
|
||||||
|
icon: 'vuesax-linear:document-text',
|
||||||
|
match: (k) => /^text_/.test(k)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'referral',
|
id: 'referral',
|
||||||
title: 'معرف، پاداش و ثبتنام',
|
title: 'معرف، پاداش و ثبتنام',
|
||||||
icon: 'vuesax-linear:people',
|
icon: 'vuesax-linear:people',
|
||||||
match: (k) =>
|
match: (k) =>
|
||||||
/^(referral_|gift_for|register_referral|register_jibit|has_page_earn_money|jibit_verification)/.test(k)
|
/^(referral_|gift_for|register_referral|register_jibit|has_page_earn_money|jibit_verification|referral_bonus)/.test(
|
||||||
|
k
|
||||||
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'montzar',
|
id: 'montzar',
|
||||||
title: 'سرویس همکار (montzar)',
|
title: 'همکار قیمت (Montzar)',
|
||||||
icon: 'vuesax-linear:link',
|
icon: 'vuesax-linear:link-2',
|
||||||
match: (k) => k.startsWith('montzar_')
|
match: (k) => k.startsWith('montzar_') || k === 'display_montzar'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'store',
|
||||||
|
title: 'اتصال به فروشگاه (Montify)',
|
||||||
|
icon: 'vuesax-linear:shop',
|
||||||
|
match: (k) => /^(external_order|node_|montify_name)/.test(k)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'payping',
|
||||||
|
title: 'درگاه Payping / Zify',
|
||||||
|
icon: 'vuesax-linear:card',
|
||||||
|
match: (k) => k.startsWith('payping_')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'tahesab',
|
||||||
|
title: 'تهحساب',
|
||||||
|
icon: 'vuesax-linear:receipt-2',
|
||||||
|
match: (k) => k.startsWith('tahesab_') || k === 'send_to_tahesab'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'support',
|
||||||
|
title: 'پشتیبانی اپ کاربر',
|
||||||
|
icon: 'vuesax-linear:headphone',
|
||||||
|
match: (k) => k.startsWith('support_messenger')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'bots',
|
||||||
|
title: 'بات تلگرام و بله',
|
||||||
|
icon: 'vuesax-linear:messages-2',
|
||||||
|
match: (k) => /^(telegram_bot|bale_bot)/.test(k)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'notifications',
|
||||||
|
title: 'پیامک و اعلان',
|
||||||
|
icon: 'vuesax-linear:notification',
|
||||||
|
match: (k) => /^(charge_notif|group_sms)/.test(k)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'features',
|
id: 'features',
|
||||||
title: 'ویژگیها و اعلانها',
|
title: 'محصولات و قابلیتهای سیستم',
|
||||||
icon: 'vuesax-linear:menu',
|
icon: 'vuesax-linear:setting-2',
|
||||||
match: (k) => /^(charge_notif|group_sms|main_wallet_products|price_from_nasiryan)/.test(k)
|
match: (k) => /^(product_|main_wallet_products|price_from_nasiryan|profit_gold)/.test(k)
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'integrations',
|
|
||||||
title: 'اتصالات خارجی و درگاهها',
|
|
||||||
icon: 'vuesax-linear:card',
|
|
||||||
match: (k) =>
|
|
||||||
/^(tahesab_|payping_|telegram_|bale_|support_messenger|external_order|profit_gold|node_)/.test(k)
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'misc',
|
id: 'misc',
|
||||||
@@ -326,6 +367,7 @@ const SETTING_GROUPS: Array<{
|
|||||||
|
|
||||||
function getGroupId(key: string): string {
|
function getGroupId(key: string): string {
|
||||||
for (const g of SETTING_GROUPS) {
|
for (const g of SETTING_GROUPS) {
|
||||||
|
if (g.id === 'misc') continue
|
||||||
if (g.match(key)) return g.id
|
if (g.match(key)) return g.id
|
||||||
}
|
}
|
||||||
return 'misc'
|
return 'misc'
|
||||||
@@ -346,7 +388,7 @@ const groupedFiltered = computed(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// کالپسهای باز — وقتی سرچ فعال است فقط گروههای دارای نتیجه باز میشوند
|
// کالپسهای باز — وقتی سرچ فعال است فقط گروههای دارای نتیجه باز میشوند
|
||||||
const defaultOpenGroups: string[] = []
|
const defaultOpenGroups = ['general', 'pricing', 'store', 'payping', 'tahesab']
|
||||||
const activeKeys = ref<string[]>(defaultOpenGroups)
|
const activeKeys = ref<string[]>(defaultOpenGroups)
|
||||||
|
|
||||||
watch(search, (q) => {
|
watch(search, (q) => {
|
||||||
|
|||||||
@@ -80,8 +80,13 @@ const KEY_TYPE_FALLBACK: Record<string, SettingFieldType> = {
|
|||||||
price_from_nasiryan: 'switch',
|
price_from_nasiryan: 'switch',
|
||||||
node_client_id: 'text',
|
node_client_id: 'text',
|
||||||
node_shared_secret: 'text',
|
node_shared_secret: 'text',
|
||||||
|
tahesab_host: 'text',
|
||||||
|
tahesab_port: 'number',
|
||||||
|
tahesab_token: 'text',
|
||||||
|
tahesab_db: 'text',
|
||||||
|
tahesab_bank_account: 'text',
|
||||||
support_messenger_id: 'text',
|
support_messenger_id: 'text',
|
||||||
support_messenger_text: 'text',
|
support_messenger_text: 'longtext',
|
||||||
support_messenger: 'select',
|
support_messenger: 'select',
|
||||||
zaarbox_price_key: 'select'
|
zaarbox_price_key: 'select'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
<BaseButton :loading="syncing" @click="handleSync">
|
<BaseButton :loading="syncing" @click="handleSync">
|
||||||
همگامسازی از محصولات
|
همگامسازی از محصولات
|
||||||
</BaseButton>
|
</BaseButton>
|
||||||
|
<span class="text-sm text-gray-500">
|
||||||
|
تب فیلتر اپ خودکار از دستههای فعالی است که محصول دارند.
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a-spin :spinning="loading">
|
<a-spin :spinning="loading">
|
||||||
@@ -24,12 +27,6 @@
|
|||||||
@change="(checked: boolean) => toggleField(record, 'active', checked)"
|
@change="(checked: boolean) => toggleField(record, 'active', checked)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="column.key === 'show_in_filter'">
|
|
||||||
<a-switch
|
|
||||||
:checked="asBool(record.show_in_filter)"
|
|
||||||
@change="(checked: boolean) => toggleField(record, 'show_in_filter', checked)"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
<template v-else-if="column.key === 'show_in_select'">
|
<template v-else-if="column.key === 'show_in_select'">
|
||||||
<a-switch
|
<a-switch
|
||||||
:checked="asBool(record.show_in_select)"
|
:checked="asBool(record.show_in_select)"
|
||||||
@@ -62,7 +59,7 @@ const loading = ref(false)
|
|||||||
const syncing = ref(false)
|
const syncing = ref(false)
|
||||||
const items = ref<Category[]>([])
|
const items = ref<Category[]>([])
|
||||||
|
|
||||||
type CategoryField = 'active' | 'show_in_filter' | 'show_in_select' | 'sort_order'
|
type CategoryField = 'active' | 'show_in_select' | 'sort_order'
|
||||||
|
|
||||||
const pendingPatches = new Map<number, Partial<Record<CategoryField, number>>>()
|
const pendingPatches = new Map<number, Partial<Record<CategoryField, number>>>()
|
||||||
const debouncedFlush = new Map<number, ReturnType<typeof debounce>>()
|
const debouncedFlush = new Map<number, ReturnType<typeof debounce>>()
|
||||||
@@ -76,12 +73,6 @@ const columns: TableColumnType<Category>[] = [
|
|||||||
width: 160,
|
width: 160,
|
||||||
align: 'center'
|
align: 'center'
|
||||||
},
|
},
|
||||||
{
|
|
||||||
title: 'تب فیلتر اپ',
|
|
||||||
key: 'show_in_filter',
|
|
||||||
width: 120,
|
|
||||||
align: 'center'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: 'سلکت افزودن محصول',
|
title: 'سلکت افزودن محصول',
|
||||||
key: 'show_in_select',
|
key: 'show_in_select',
|
||||||
@@ -137,7 +128,6 @@ async function flushSave(id: number) {
|
|||||||
|
|
||||||
const snapshot = {
|
const snapshot = {
|
||||||
active: record.active,
|
active: record.active,
|
||||||
show_in_filter: record.show_in_filter,
|
|
||||||
show_in_select: record.show_in_select,
|
show_in_select: record.show_in_select,
|
||||||
sort_order: record.sort_order
|
sort_order: record.sort_order
|
||||||
}
|
}
|
||||||
@@ -154,7 +144,7 @@ async function flushSave(id: number) {
|
|||||||
|
|
||||||
function toggleField(
|
function toggleField(
|
||||||
record: Category,
|
record: Category,
|
||||||
field: 'active' | 'show_in_filter' | 'show_in_select',
|
field: 'active' | 'show_in_select',
|
||||||
checked: boolean
|
checked: boolean
|
||||||
) {
|
) {
|
||||||
if (asBool(record[field]) === checked) return
|
if (asBool(record[field]) === checked) return
|
||||||
|
|||||||
Reference in New Issue
Block a user