52 lines
2.3 KiB
JavaScript
52 lines
2.3 KiB
JavaScript
// سیاست ایندکس صفحات فرود تخصص — منبع مشترک صفحه و sitemap تا واگرا نشوند.
|
|
//
|
|
// تخصصی که زیرشاخهٔ فعال دارد (مثل «داخلی» با فرزند «گوارش و کبد») یک دستهٔ سطحبالاست:
|
|
// محتوای مستقلی ندارد و با فرزندانش روی همان کوئری رقابت میکند → noindex.
|
|
//
|
|
// اما «والد بودن» بهتنهایی کافی نیست: تخصصهایی مثل «پزشک عمومی» هم parent_id تهی
|
|
// دارند و هم هیچ زیرشاخهای ندارند. آنها در عمل برگاند و صفحهٔ واقعی خدمات و
|
|
// پزشکان را نشان میدهند، پس ایندکس میمانند.
|
|
|
|
import specialtiesData from "@/data/specialties.json";
|
|
|
|
// فقط فرزندان فعال شمرده میشوند؛ زیرشاخهٔ غیرفعال صفحهای ندارد که رقابت کند.
|
|
const IDS_WITH_ACTIVE_CHILDREN = new Set(
|
|
specialtiesData
|
|
.filter((item) => item?.status === 1 && item?.parent_id != null)
|
|
.map((item) => Number(item.parent_id))
|
|
);
|
|
|
|
/** دستهٔ سطحبالا: بدون والد، ولی دارای زیرشاخهٔ فعال. */
|
|
export function isCategorySpecialty(specialty) {
|
|
if (!specialty || specialty.parent_id != null) return false;
|
|
return IDS_WITH_ACTIVE_CHILDREN.has(Number(specialty.id));
|
|
}
|
|
|
|
export function isIndexableSpecialty(specialty) {
|
|
return Boolean(specialty) && !isCategorySpecialty(specialty);
|
|
}
|
|
|
|
/** زیرشاخههای فعالِ یک تخصص، به ترتیب weight سپس نام. */
|
|
export function childSpecialties(specialty) {
|
|
if (!specialty) return [];
|
|
|
|
return specialtiesData
|
|
.filter(
|
|
(item) =>
|
|
item?.status === 1 &&
|
|
String(item.parent_id ?? "") === String(specialty.id)
|
|
)
|
|
.sort((a, b) => (a.weight ?? 0) - (b.weight ?? 0) || a.name.localeCompare(b.name, "fa"));
|
|
}
|
|
|
|
/** والدِ فعالِ یک زیرتخصص، یا null اگر ریشه باشد. */
|
|
export function parentSpecialty(specialty) {
|
|
if (!specialty?.parent_id) return null;
|
|
|
|
return (
|
|
specialtiesData.find(
|
|
(item) => item?.status === 1 && String(item.id) === String(specialty.parent_id)
|
|
) ?? null
|
|
);
|
|
}
|