From b81a85f67276e45ba9cd1051a19244a7d616fcbc Mon Sep 17 00:00:00 2001 From: Kavehhn174 Date: Wed, 19 Aug 2026 06:50:01 +0330 Subject: [PATCH] feat(settings): add database seeder section with one-time execution and lock mechanism --- src/service/SettingService.js | 40 ++++++ src/views/pages/Settings/SearchSettings.vue | 127 +++++++++++++++++++- 2 files changed, 166 insertions(+), 1 deletion(-) diff --git a/src/service/SettingService.js b/src/service/SettingService.js index 6a93d8b..9d9d1f2 100644 --- a/src/service/SettingService.js +++ b/src/service/SettingService.js @@ -97,5 +97,45 @@ export const SettingService = { console.error('Error bulk updating search settings:', err); throw err; } + }, + + /** + * Get database seeding status + * @returns {Promise<{isSeeded: boolean, seededAt: string|null, seededBy: string|null}>} + */ + getSeedStatus: async () => { + const config = { + method: 'get', + url: '/api/settings/seed-status', + withCredentials: true, + headers: SettingService._getAuthHeader() + }; + try { + const response = await axios(config); + return response.data.data; + } catch (err) { + console.error('Error fetching seed status:', err); + throw err; + } + }, + + /** + * Execute one-time database seeding + * @returns {Promise} + */ + seedDatabase: async () => { + const config = { + method: 'post', + url: '/api/settings/seed-database', + withCredentials: true, + headers: SettingService._getAuthHeader() + }; + try { + const response = await axios(config); + return response.data.data; + } catch (err) { + console.error('Error seeding database:', err); + throw err; + } } }; diff --git a/src/views/pages/Settings/SearchSettings.vue b/src/views/pages/Settings/SearchSettings.vue index 6fa94c7..af20f72 100644 --- a/src/views/pages/Settings/SearchSettings.vue +++ b/src/views/pages/Settings/SearchSettings.vue @@ -13,15 +13,72 @@ const loading = ref(false); const saving = ref(false); const settings = ref([]); +// Seeder State +const seedStatus = ref({ isSeeded: false, seededAt: null }); +const isSeeding = ref(false); +const seedLoading = ref(false); + const methodOptions = [ { label: 'Typesense', value: 'typesense', icon: 'pi pi-bolt', class: 'text-amber-500' }, { label: 'MongoDB', value: 'mongo', icon: 'pi pi-database', class: 'text-emerald-500' } ]; onMounted(async () => { - await loadSettings(); + await Promise.all([loadSettings(), loadSeedStatus()]); }); +const loadSeedStatus = async () => { + seedLoading.value = true; + try { + const data = await SettingService.getSeedStatus(); + seedStatus.value = data || { isSeeded: false, seededAt: null }; + } catch (e) { + console.warn('Failed to load seed status:', e); + } finally { + seedLoading.value = false; + } +}; + +const handleSeedDatabase = () => { + if (seedStatus.value.isSeeded) return; + + confirm.require({ + message: 'توجه: این عملیات داده‌های اولیه سیستم (کاربران پیش‌فرض، نقش‌ها، دسته‌بندی‌ها، ویژگی‌های تکمیلی و وضعیت‌های املاک) را در پایگاه داده ایجاد می‌کند. این عملیات فقط یک‌بار قابل اجراست و پس از انجام دکمه برای همیشه قفل خواهد شد. آیا ادامه می‌دهید؟', + header: 'تایید مقداردهی اولیه پایگاه داده (Seed Database)', + icon: 'pi pi-exclamation-triangle', + rejectProps: { label: 'انصراف', severity: 'secondary', outlined: true }, + acceptProps: { label: 'تایید و شروع مقداردهی', severity: 'primary' }, + accept: async () => { + isSeeding.value = true; + try { + const res = await SettingService.seedDatabase(); + seedStatus.value = { + isSeeded: true, + seededAt: res.seededAt || new Date() + }; + toast.add({ + severity: 'success', + summary: 'موفقیت‌آمیز', + detail: res.message || 'پایگاه داده با موفقیت مقداردهی شد و قفل گردید.', + life: 5000 + }); + await loadSettings(); + } catch (err) { + const errMsg = err?.response?.data?.message || err.message || 'خطا در مقداردهی پایگاه داده'; + toast.add({ + severity: 'error', + summary: 'خطا در مقداردهی', + detail: errMsg, + life: 4000 + }); + await loadSeedStatus(); + } finally { + isSeeding.value = false; + } + } + }); +}; + const loadSettings = async () => { loading.value = true; try { @@ -151,6 +208,74 @@ const navigateToModule = (routePath) => { + +
+
+
+
+ +
+
+
+

+ مقداردهی اولیه پایگاه داده (Seed Database) +

+ + +
+

+ ایجاد خودکار کاربران اولیه، نقش‌ها و سطوح دسترسی، دسته‌بندی‌های املاک، ویژگی‌های تکمیلی و وضعیت‌های املاک در دیتابیس. این عملیات صرفاً یک‌بار قابل اجراست و پس از انجام دکمه برای همیشه قفل می‌شود. +

+
+ + تاریخ اجرا: {{ new Date(seedStatus.seededAt).toLocaleString('fa-IR') }} +
+
+
+ +
+
+
+
+