شکاف موجود: در حال حاضر هیچ مدل، کنترلر، سرویس یا صفحه اختصاصی برای **«شاهمانیتورینگ ورودیهای املاک و محیطهای سهبعدی (VOD Property Entry * در لایه بکاند لاراول (app/Models/ و app/Http/Controllers/Api/)، مدلهای Feature.php، FeatureProperties.php و IsicCode.php و کنترلرهای LandsController.php و IsicCodeController.php وجود دارند.
در لایه فرانتاند (resources/js/pages/lands/ و resources/js/pages/isic-codes/)، صفحات پایه مدیریت زمینها (Listing.vue, Prices.vue, Pricing.vue, Sold.vue, Traded.vue, FeatureLimits.vue) با استفاده از کامپوزبل() و کامپوننتهای `
<Monitoring)».
۳. شاخصهای پنجگانه الزامی در شاهمانیتورینگ ورودیهای املاک
این زیرساخت باید دقیقاً ۵ شاخص و قابلیت کلیدی زیر را در سطح کلان (کارتهای KPI بالای صفحه) و در سطح تکتک املاک (جدول مانیتورینگ و مودال ریزِ نشستها) پوشش دهد:
ه در محیط (Total Registered Entries):**
نمایش تعداد کل دفعات ورود شهروندان به هر محیط (و مجموع کل ورودها در بالای صفحه) با قابلیت فیلتر در بازه ز * زمان اعمال: این فرآیند تماماً پس از ورود (entered_at) آغاز شده و پس از خروج (exited_at) محاسبه و به زمان فعالیت محیط اضافه میگردد:
$$ ext{Activity Hours} = rac{\sum_{i=1}^{N_{ ext{closed}}} ( ext{exited_at}_i - ext{entered_at}_i)}{3600}$$
فیلتر دقیق برای طبقهبندی محیطها بر اساس نوع کاربری (karbari):
امکان فیلتر کردن محیطها بر اساس کدهای کاربری استاندارد متارنگ در feature_properties.karbari (تجاری t، مسکونی m، آموزشی a، اداری e، صنعتی s، فرهنگی f، بهداشتی/درمانی p، کشاورزی z، گردشگری g، نظامی n، بایر b).
فیلتر بر اساس دستهبندیهای تعریفشده ISIC (isic_codes):
امکان جستجو و فیلتر کردن محیطها بر اساس کد و عنوان فعالیت اقتصادی ISIC تعریفشده در جدول isic_codes (متصل به مدل app/Models/IsicCode.php).
**میزان ورود ثبتش میزان افراد حاضر در محیط (Current Active Citizens Inside):
نمایش بلادرنگ تعداد شهروندانی که هماکنون در داخل محیط سهبعدی حضور دارند (نشستهای فعالی که وارد شدهاند اما هنوز خارج نشدهاند: exited_at IS NULL).
۴. طراحی فنی و اقدامات اجرایی در بکاند Laravel 12 (app/)
۴.۱. ایجاد مدلهای Eloquent جدید (app/Models/)
app/Models/BuildingEntrySession.php:
متصل به جدول building_entry_sessions.
فیلدهای Fillable و Casts: feature_id (int), user_id (int), fee_psc_paid (decimal:8), fee_irr_paid (decimal:2), coupon_id (int), ticket_id (string), exited_at (datetime), duration_seconds (int), exit_reason (string).
itoring`:
الف) متد index(Request $request) — دریافت لیست صفحهب * روابط: feature() به Feature::class، user() به User::class.
app/Models/BuildingEntryConfig.php:
متصل به جدول building_entry_configs.
فیلدها: feature_id, isic_code_id, fee_psc, fee_irr, is_active, level_scope_type, level_slug, total_entries_count, total_activity_seconds.
روابط: feature() به Feature::class، isicCode() به IsicCode::class.
بهروزرسانی app/Models/Feature.php و app/Models/FeatureProperties.php:
پارامترهای ورودی فیلتر (Query Params):
search: جستجو بر اساس شناسه ملک (feature_properties.id مانند TO111)، نام یا کد شهروندی مالک (owner.code).
karbari: فیلتر بر اساس یک یا چند نوع کاربری (مثلاً t, m, a).
isic_code_id: فیلتر بر اساس شناسه دستهبندی ISIC (یا isic_code برای جستجوی کد ISIC).
only_online: (boolean) نمایش صرفاً محیطهایی که در حال حاضر حداقل ۱ شهروند در آنها حضور دارد (active_online_count > 0).
date_from و date_to: فیلتر بازه زمانی ورود/خروج برای محاسبه پویا در بازه دلخواه.
sort_by: مرتبسازی بر اساس activity_seconds (بیشترین ساعت فعالیت)، entries_count (بیشترین میزان ورود)، یا online_count (بیشترین افراد حاضر در محیط).
sort_dir: asc | desc (پیشفرض: desc).
منطق کوئری تجمیعی SQL / Eloquent:
$sessionsSubquery = DB::table('building_entry_sessions')
->selectRaw('
feature_id,
COUNT(*) as total_entries_count,
SUM(CASE WHEN exited_at IS NULL THEN 1 ELSE 0 END) as active_online_count,
"total_activity_hours": 10.0,
"total_activity_formatted": "۱۰ ساعت و ۰ دقیقه",
"total_entries_count": 48,
"active_online_count": 5
},
"entry_conf COALESCE(SUM(CASE WHEN exited_at IS NOT NULL THEN COALESCE(duration_seconds, TIMESTAMPDIFF(SECOND, entered_at, exited_at)) ELSE 0 END), 0) as total_activity_seconds
')
->when($request->filled('date_from'), fn($q) => $q->where('entered_at', '>=', $request->date_from))
->when($request->filled('date_to'), fn($q) => $q->where('entered_at', '<=', $request->date_to))
->groupBy('feature_id');
سپس Join کردن این Subquery با feature_properties، features، users (مالک)، building_entry_configs و isic_codes تا در یک کوئری واحد و بدون مشکل
N
+
1
، تمام اطلاعات هر محیط استخراج شود.
ساختار JSON خروجی هر ردیف در API:
{
"feature_id": 44,
"feature_properties_id": "TO111",
"label": "مجتمع تجاری الماس",
"karbari": "t",
"application_title": "تجاری",
"isic_code": {
"id": 12,
"code": 4711,
"name": "خردهفروشی در فروشگاههای غیرتخصصی"
},
"owner": {
"id": 105,
"name": "حسین قدیری",
"code": "hm-2000001"
},
"metrics": {
"total_activity_seconds": 36000,
ig": {
"is_active": true,
"fee_psc": "1.50000000",
"fee_irr": "150000"
}
}