diff --git a/src/pages/menuPages/configuration/index.vue b/src/pages/menuPages/configuration/index.vue index 8510547..12d0c5e 100644 --- a/src/pages/menuPages/configuration/index.vue +++ b/src/pages/menuPages/configuration/index.vue @@ -80,7 +80,7 @@ ({ })) const baseData = ref>([]) -const drafts = ref>({}) +/** draft بر اساس id یا key — ردیف‌های overlay سوپرادمین id=null دارند */ +const drafts = ref>({}) const addConfigVisible = ref(false) const search = ref('') const filterType = ref() @@ -266,6 +267,11 @@ const savedFlashIds = ref>(new Set()) const saveTimers = new Map>() const debouncedSave = new Map>() +function rowDraftKey(row: Const): string { + if (row.id != null) return `id:${row.id}` + return `key:${row.key || ''}` +} + const form = ref({ key: '', value: '', @@ -311,7 +317,7 @@ function matchesFilter(row: Const): boolean { (row.key || '').toLowerCase().includes(q) || (row.title_fa || '').toLowerCase().includes(q) || (row.value || '').toLowerCase().includes(q) || - (drafts.value[row.id!] || '').toLowerCase().includes(q) + (drafts.value[rowDraftKey(row)] || '').toLowerCase().includes(q) ) } @@ -453,8 +459,8 @@ function isReadonly(row: Const): boolean { } function draftValue(row: Const): string { - const id = row.id! - if (drafts.value[id] !== undefined) return drafts.value[id] + const k = rowDraftKey(row) + if (drafts.value[k] !== undefined) return drafts.value[k] return row.value ?? '' } @@ -467,9 +473,9 @@ function isSavedFlash(id?: number): boolean { } function syncDraftsFromBase() { - const next: Record = {} + const next: Record = {} for (const row of baseData.value || []) { - if (row.id != null) next[row.id] = row.value ?? '' + next[rowDraftKey(row)] = row.value ?? '' } drafts.value = next } @@ -488,11 +494,39 @@ watch( } ) +async function pullSuperAdminAndApplyFlags(): Promise<{ + ok: boolean + message?: string + count?: number +}> { + invalidateSettingsBootstrap() + const res = await refreshSuperAdminSettings() + if (res?.items && typeof res.items === 'object') { + applySuperAdminAccessFlagsFromItems(res.items) + } + // get_settings کامل — فلگ منو و کارت‌ها با مقدار زنده هم‌تراز شوند + try { + const { getConfiguration } = await import('@/api/configuration') + const all = await getConfiguration() + const rows = Array.isArray(all) ? all : [] + applySuperAdminAccessFlagsFromItems(rows) + applyPriceProviderFromRows(rows) + applyPriceChannelAccessFromRows(rows) + } catch { + /* فلگ از items می‌ماند */ + } + return { + ok: res?.ok !== false, + message: res?.message, + count: res?.count + } +} + async function refreshFromSuperAdmin() { if (refreshingSuperAdmin.value) return refreshingSuperAdmin.value = true try { - const res = await refreshSuperAdminSettings() + const res = await pullSuperAdminAndApplyFlags() await initConfig() refreshMenuAfterStoreChange() message.success(res?.message || `همگام شد (${res?.count ?? 0} کلید دسترسی از سوپرادمین)`) @@ -505,21 +539,23 @@ async function refreshFromSuperAdmin() { } } -/** بروزرسانی: اول از سوپرادمین زنده بخوان، بعد لیست تنظیمات را دوباره بگیر */ +/** بروزرسانی: زنده از سوپرادمین بگیر → فلگ منو اعمال شود → لیست تنظیمات رفرش */ async function onRefreshClick() { if (refreshingSuperAdmin.value || loading.value) return refreshingSuperAdmin.value = true try { - await refreshSuperAdminSettings() + const res = await pullSuperAdminAndApplyFlags() + await initConfig() + refreshMenuAfterStoreChange() + message.success(res?.message || 'بروزرسانی شد') } catch (e: any) { console.error(e) const msg = e?.response?.data?.message || e?.message || 'همگام‌سازی از سوپرادمین ناموفق بود' message.error(Array.isArray(msg) ? msg.join('، ') : msg) + await initConfig() } finally { refreshingSuperAdmin.value = false } - await initConfig() - refreshMenuAfterStoreChange() } async function initConfig() { @@ -644,13 +680,15 @@ function syncMenuFlagsFromSetting(key: string | undefined, value: string) { } function onValueChange(row: Const, value: string) { - if (row.id == null || isReadonly(row)) return + if (isReadonly(row)) return - drafts.value[row.id] = value + drafts.value[rowDraftKey(row)] = value // منو و UI وابسته را همان لحظه با سوئیچ همگام کن syncMenuFlagsFromSetting(row.key, value) + if (row.id == null) return + // longtext هم باید ذخیره شود، فقط با delay بیشتر scheduleSave(row) } @@ -699,9 +737,10 @@ async function persistRow(row: Const) { async function saveSettingRow(row: Const) { if (row.id == null) return const id = row.id + const draftKey = rowDraftKey(row) const type = resolveSettingFieldType(row) - const raw = drafts.value[id] ?? row.value ?? '' + const raw = drafts.value[draftKey] ?? row.value ?? '' const value = formatValueForSave(raw, type, row.key) if (value === (row.value ?? '')) return @@ -723,9 +762,9 @@ async function saveSettingRow(row: Const) { }) row.value = value row.is_active = true - const currentDraft = drafts.value[id] ?? '' + const currentDraft = drafts.value[draftKey] ?? '' if (currentDraft === draftSnapshot) { - drafts.value[id] = value + drafts.value[draftKey] = value } else { scheduleSave(row) } @@ -745,8 +784,8 @@ async function saveSettingRow(row: Const) { ) } catch (e) { console.error(e) - if ((drafts.value[id] ?? '') === draftSnapshot) { - drafts.value[id] = row.value ?? '' + if ((drafts.value[draftKey] ?? '') === draftSnapshot) { + drafts.value[draftKey] = row.value ?? '' } // برگرداندن فلگ منو به مقدار ذخیره‌شده قبلی syncMenuFlagsFromSetting(row.key, row.value ?? '') diff --git a/src/utils/config.ts b/src/utils/config.ts index 3f66d4c..e963bc3 100644 --- a/src/utils/config.ts +++ b/src/utils/config.ts @@ -283,6 +283,33 @@ export function applyCustomerSpecialPricingFromRows( if (row) setCustomerSpecialPricingEnabledFromSettings(isSwitchOn(row.value)) } +/** بعد از همگام‌سازی سوپرادمین — bootstrap بعدی دوباره از API می‌خواند */ +export function invalidateSettingsBootstrap(): void { + settingsBootstrapped = false +} + +/** + * اعمال مستقیم ۱۴ دسترسی سوپرادمین روی فلگ‌های منو/UI + * (پاسخ refresh-superadmin.items یا ردیف‌های get_settings). + */ +export function applySuperAdminAccessFlagsFromItems( + items: Record | Array<{ key?: string; value?: string | null }> +): void { + const rows = Array.isArray(items) + ? items + : Object.entries(items).map(([key, value]) => ({ key, value })) + applyCustomerDirectSmsFromRows(rows) + applyGroupSmsFromRows(rows) + applyCustomerSpecialPricingFromRows(rows) + applyConditionalOrderEnabledFromRows(rows) + applyAutomationEnabledFromRows(rows) + applyProductFundsEnabledFromRows(rows) + applyCustomerLevelProfitEnabledFromRows(rows) + applyPriceTriggerEnabledFromRows(rows) + applyAppNotificationEnabledFromRows(rows) + applySupportChatMenuEnabledFromRows(rows) +} + export function applyConditionalOrderEnabledFromRows( rows: Array<{ key?: string; value?: string | null }> ) {