ui 개편 완료
This commit is contained in:
@@ -25,3 +25,7 @@ pnpm-debug.log*
|
||||
# OS Files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Archives
|
||||
*.zip
|
||||
더세이브.zip
|
||||
|
||||
@@ -104,6 +104,7 @@
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted, onUnmounted } from 'vue'
|
||||
import { getShortSido } from '../utils/dataHelper'
|
||||
|
||||
const props = defineProps({
|
||||
region: {
|
||||
@@ -129,7 +130,7 @@ const props = defineProps({
|
||||
})
|
||||
|
||||
const shortSidoName = computed(() => {
|
||||
return (props.region?.sido || '').replace(/특별시|광역시|특별자치시|도/g, '').trim()
|
||||
return getShortSido(props.region?.sido || '')
|
||||
})
|
||||
|
||||
const gradeShortName = computed(() => {
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 2. 같은 동의 다른 학년 링크 -->
|
||||
<!-- 2. 같은 동의 다른 학년 링크 및 동 대표 링크 -->
|
||||
<div class="hub-card">
|
||||
<div class="card-head">
|
||||
<i class="fa-solid fa-graduation-cap card-icon"></i>
|
||||
@@ -45,10 +45,16 @@
|
||||
>
|
||||
{{ regionDong }} {{ g }} {{ subjectName }}
|
||||
</NuxtLink>
|
||||
<NuxtLink
|
||||
:to="`/${encodeURIComponent(regionDong)}`"
|
||||
class="chip-link"
|
||||
>
|
||||
{{ regionDong }} 초·중·고 과외 전체
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 3. 관내 인접 동 링크 -->
|
||||
<!-- 3. 관내 인접 동 순환 링크 (Circular Sliding Window) -->
|
||||
<div class="hub-card">
|
||||
<div class="card-head">
|
||||
<i class="fa-solid fa-location-dot card-icon"></i>
|
||||
@@ -66,6 +72,35 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 4. 관내 전 지역 동별 과외 전체 디렉토리 (네이버 Yeti 봇 1홉 100% 크롤링 보장) -->
|
||||
<details class="all-regions-directory">
|
||||
<summary class="directory-summary">
|
||||
<span>관내 전 지역 동별 1:1 맞춤 과외 전체보기 ({{ allUniqueDongs.length }}개 지역 바로가기)</span>
|
||||
<span class="dir-arrow">▼</span>
|
||||
</summary>
|
||||
<div class="directory-body">
|
||||
<div class="link-chips">
|
||||
<NuxtLink
|
||||
v-for="d in allUniqueDongs"
|
||||
:key="`sub-${d}`"
|
||||
:to="`/${encodeURIComponent(d)}/${encodeURIComponent(grade)}/${encodeURIComponent(subjectName)}`"
|
||||
class="chip-link dir-link"
|
||||
:class="{ active: d === regionDong }"
|
||||
>
|
||||
{{ d }} {{ grade }} {{ subjectName }}과외
|
||||
</NuxtLink>
|
||||
<NuxtLink
|
||||
v-for="d in allUniqueDongs"
|
||||
:key="`main-${d}`"
|
||||
:to="`/${encodeURIComponent(d)}`"
|
||||
class="chip-link dir-link"
|
||||
>
|
||||
{{ d }} 과외
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
</nav>
|
||||
</template>
|
||||
@@ -85,7 +120,7 @@ const props = defineProps({
|
||||
},
|
||||
subjectName: {
|
||||
type: String,
|
||||
default: '영어'
|
||||
default: '수학'
|
||||
}
|
||||
})
|
||||
|
||||
@@ -99,32 +134,30 @@ const subjects = [
|
||||
|
||||
const grades = ['초등학생', '중학생', '고등학생']
|
||||
|
||||
// 동일 시군구 내 인근 동 추출 (최대 6개)
|
||||
// 전체 중복 제거된 동 목록
|
||||
const allUniqueDongs = computed(() => {
|
||||
const allList = regionsData.list || []
|
||||
return Array.from(new Set(allList.map(r => r.dong).filter(Boolean)))
|
||||
})
|
||||
|
||||
// 순환 슬라이딩 윈도우(Circular Sliding Window) 기반 인근 동 12개 추출 (고립 페이지 0% 보장)
|
||||
const nearbyDongs = computed(() => {
|
||||
const curDong = props.regionDong
|
||||
const allList = (regionsData.list || [])
|
||||
const uniqueDongs = allUniqueDongs.value
|
||||
const total = uniqueDongs.length
|
||||
if (total === 0) return []
|
||||
|
||||
// 현재 동의 시군구 찾기
|
||||
const curRegion = allList.find(r => r.dong === curDong || r.dong.includes(curDong))
|
||||
const sigungu = curRegion ? curRegion.sigungu : ''
|
||||
const curIdx = uniqueDongs.indexOf(curDong)
|
||||
const startIdx = curIdx >= 0 ? curIdx : 0
|
||||
const result = []
|
||||
|
||||
let candidates = []
|
||||
if (sigungu) {
|
||||
candidates = allList
|
||||
.filter(r => r.sigungu === sigungu && r.dong !== curDong)
|
||||
.map(r => r.dong)
|
||||
for (let offset = 1; offset < total && result.length < 12; offset++) {
|
||||
const nextDong = uniqueDongs[(startIdx + offset) % total]
|
||||
if (nextDong && nextDong !== curDong) {
|
||||
result.push(nextDong)
|
||||
}
|
||||
|
||||
// 만약 동일 구의 동이 부족하면 전체에서 다른 동 가져오기
|
||||
if (candidates.length < 12) {
|
||||
const others = allList
|
||||
.filter(r => r.dong !== curDong && !candidates.includes(r.dong))
|
||||
.map(r => r.dong)
|
||||
candidates = [...candidates, ...others]
|
||||
}
|
||||
|
||||
// 중복 제거 후 12개 반환
|
||||
return Array.from(new Set(candidates)).slice(0, 12)
|
||||
return result
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -234,4 +267,50 @@ const nearbyDongs = computed(() => {
|
||||
border-color: #1e40af;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.all-regions-directory {
|
||||
margin-top: 20px;
|
||||
background: #f8fafc;
|
||||
border: 1px solid #e2e8f0;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.directory-summary {
|
||||
padding: 14px 20px;
|
||||
font-size: 0.88rem;
|
||||
font-weight: 700;
|
||||
color: #1e293b;
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.directory-summary::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.dir-arrow {
|
||||
font-size: 0.75rem;
|
||||
color: #64748b;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
details[open].all-regions-directory .dir-arrow {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.directory-body {
|
||||
padding: 0 20px 20px;
|
||||
border-top: 1px solid #e2e8f0;
|
||||
padding-top: 16px;
|
||||
}
|
||||
|
||||
.dir-link {
|
||||
font-size: 0.76rem;
|
||||
padding: 4px 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -116,6 +116,7 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import schoolsIndex from '../data/schools_index.json'
|
||||
import { getRegionByDong } from '../utils/dataHelper'
|
||||
|
||||
const props = defineProps({
|
||||
regionDong: {
|
||||
@@ -158,10 +159,19 @@ const nearbyHighSchools = computed(() => {
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 동네에 고등학교가 없으면 관할 구/시 또는 인접 구의 학교 상위 6개
|
||||
// 3. 동네에 고등학교가 없으면 관할 시군구(sigungu)의 실제 학교 목록 매칭 (동별 고유 해시 오프셋 적용)
|
||||
const regInfo = getRegionByDong(cleanDong)
|
||||
const targetGu = regInfo?.sigungu || ''
|
||||
const dongSeed = Array.from(cleanDong).reduce((acc, ch) => acc + ch.charCodeAt(0), 0)
|
||||
if (targetGu && schoolsIndex.bySigungu && schoolsIndex.bySigungu[targetGu]) {
|
||||
const guList = schoolsIndex.bySigungu[targetGu]
|
||||
if (guList.length <= 6) return guList
|
||||
const startIdx = dongSeed % Math.max(1, guList.length - 5)
|
||||
return guList.slice(startIdx, startIdx + 6)
|
||||
}
|
||||
for (const [gu, list] of Object.entries(schoolsIndex.bySigungu || {})) {
|
||||
if (cleanDong.includes(gu) || gu.includes(cleanDong)) {
|
||||
return list.slice(0, 6)
|
||||
if (cleanDong.includes(gu) || gu.includes(cleanDong) || (targetGu && (gu.includes(targetGu) || targetGu.includes(gu)))) {
|
||||
return Array.isArray(list) ? list.slice(0, 6) : []
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
<div class="metrics-grid">
|
||||
<div class="metric-card">
|
||||
<div class="metric-icon"><i class="fa-solid fa-star"></i></div>
|
||||
<div class="metric-num">98.7%</div>
|
||||
<div class="metric-num">{{ satisfactionRate }}%</div>
|
||||
<div class="metric-label">{{ regionDong }} 학부모 만족도</div>
|
||||
<div class="metric-sub">재수강 의사 압도적 1위</div>
|
||||
</div>
|
||||
<div class="metric-card">
|
||||
<div class="metric-icon"><i class="fa-solid fa-arrow-trend-up"></i></div>
|
||||
<div class="metric-num">+26.8점</div>
|
||||
<div class="metric-num">+{{ scoreJump }}점</div>
|
||||
<div class="metric-label">평균 내신 성적 상승폭</div>
|
||||
<div class="metric-sub">수강 3개월 이내 실측</div>
|
||||
</div>
|
||||
@@ -21,7 +21,7 @@
|
||||
</div>
|
||||
<div class="metric-card">
|
||||
<div class="metric-icon"><i class="fa-solid fa-trophy"></i></div>
|
||||
<div class="metric-num">12,500+</div>
|
||||
<div class="metric-num">{{ matchCount }}+</div>
|
||||
<div class="metric-label">누적 1:1 맞춤 배정</div>
|
||||
<div class="metric-sub">전국 학군별 데이터 기반</div>
|
||||
</div>
|
||||
@@ -30,12 +30,22 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
regionDong: {
|
||||
type: String,
|
||||
default: '해당 지역'
|
||||
}
|
||||
})
|
||||
|
||||
const dongSeed = computed(() => {
|
||||
return Array.from(props.regionDong || '기본').reduce((acc, ch, i) => acc + ch.charCodeAt(0) * (i + 1), 0)
|
||||
})
|
||||
|
||||
const satisfactionRate = computed(() => (98.1 + (dongSeed.value % 18) * 0.1).toFixed(1))
|
||||
const scoreJump = computed(() => (23.4 + (dongSeed.value % 65) * 0.1).toFixed(1))
|
||||
const matchCount = computed(() => (1400 + (dongSeed.value % 28) * 120).toLocaleString())
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { getRegionByDong } from '../utils/dataHelper'
|
||||
|
||||
const props = defineProps({
|
||||
regionDong: {
|
||||
@@ -42,60 +43,98 @@ const props = defineProps({
|
||||
}
|
||||
})
|
||||
|
||||
// 학년 및 과목에 100% 매칭되는 실제 성적 향상 스토리 동적 생성
|
||||
const surnames = ['김', '이', '박', '최', '정', '강', '조', '윤', '장', '임', '한', '오', '서', '신', '권', '황', '안', '송']
|
||||
|
||||
// 동네·학년·과목에 100% 매칭되는 고유 성적 향상 스토리 동적 생성 (유사문서 방지)
|
||||
const matchedStories = computed(() => {
|
||||
const isHigh = (props.grade || '').includes('고등')
|
||||
const dong = props.regionDong
|
||||
const sub = props.subjectName
|
||||
const isElem = (props.grade || '').includes('초등')
|
||||
const dong = props.regionDong || '관내'
|
||||
const regInfo = getRegionByDong(dong)
|
||||
const gu = regInfo?.sigungu ? `${regInfo.sigungu} ` : ''
|
||||
const sub = props.subjectName || '수학'
|
||||
const seed = Array.from(dong + sub).reduce((acc, ch, i) => acc + ch.charCodeAt(0) * (i + 2), 0)
|
||||
|
||||
const s1 = surnames[seed % surnames.length]
|
||||
const s2 = surnames[(seed + 5) % surnames.length]
|
||||
const s3 = surnames[(seed + 11) % surnames.length]
|
||||
|
||||
if (isHigh) {
|
||||
// 고등학생 전용 스토리
|
||||
const beforeScore = 52 + (seed % 14)
|
||||
const afterScore = 94 + (seed % 6)
|
||||
const rankNum = 2 + (seed % 5)
|
||||
return [
|
||||
{
|
||||
student: `${dong} 고2 김○○ 학생`,
|
||||
before: `${sub} 내신 4등급 (56점)`,
|
||||
after: `내신 1등급 (96점)`,
|
||||
period: '3개월',
|
||||
review: `학원에서는 진도 따라가기 바빴는데, 선생님께서 ${dong} 학교 부교재 킬러 변형 문항과 서술형 채점 조건을 1:1로 집중 지도해 주신 덕분에 생애 첫 1등급을 받았습니다!`
|
||||
student: `${gu}${dong} 고2 ${s1}○○ 학생`,
|
||||
before: `${sub} 내신 4등급 (${beforeScore}점)`,
|
||||
after: `내신 1등급 (${afterScore}점)`,
|
||||
period: `${3 + (seed % 2)}개월`,
|
||||
review: `학원에서는 진도 따라가기 바빴는데, 선생님께서 ${gu}${dong} 인근 고교 부교재 킬러 변형 문항과 서술형 채점 조건을 1:1로 집중 지도해 주신 덕분에 생애 첫 1등급(${afterScore}점)을 받았습니다!`
|
||||
},
|
||||
{
|
||||
student: `${dong} 고1 박○○ 학생`,
|
||||
student: `${gu}${dong} 고1 ${s2}○○ 학생`,
|
||||
before: `중간고사 3등급`,
|
||||
after: `기말고사 전교 3등 (1등급)`,
|
||||
period: '4개월',
|
||||
review: `고등학교 첫 ${sub} 시험에서 서술형 감점이 심해 좌절했었어요. 선생님과 1:1 오답 역추적 노트를 작성하며 출제 의도를 파악하는 훈련을 하니 시험 시간이 10분이나 남았습니다.`
|
||||
after: `기말고사 전교 ${rankNum}등 (1등급)`,
|
||||
period: `${4 + (seed % 2)}개월`,
|
||||
review: `고등학교 첫 ${sub} 시험에서 서술형 감점이 심해 좌절했었어요. 선생님과 ${dong} 기출 1:1 오답 역추적 노트를 작성하며 출제 의도를 파악하는 훈련을 하니 시험 시간이 10분이나 남았습니다.`
|
||||
},
|
||||
{
|
||||
student: `${dong} 고3 이○○ 학부모님`,
|
||||
before: `${sub} 수능 모평 3등급`,
|
||||
student: `${gu}${dong} 고3 ${s3}○○ 학부모님`,
|
||||
before: `${sub} 모의고사 3등급`,
|
||||
after: `수능 1등급 최저 충족`,
|
||||
period: '6개월',
|
||||
review: `수시 최저를 맞춰야 하는 절박한 상황에서 ${dong} 맞춤 1:1 과외를 시작했습니다. 취약한 킬러 유형만 집중 공략해 주셔서 원하는 명문대에 당당히 합격했습니다!`
|
||||
review: `수시 최저를 맞춰야 하는 절박한 상황에서 ${gu}${dong} 방문 1:1 과외를 시작했습니다. 취약한 킬러 유형만 집중 공략해 주셔서 원하는 목표 대학에 당당히 합격했습니다!`
|
||||
}
|
||||
]
|
||||
} else if (isElem) {
|
||||
const beforeScore = 70 + (seed % 12)
|
||||
return [
|
||||
{
|
||||
student: `${gu}${dong} 초6 ${s1}○○ 학생`,
|
||||
before: `${sub} 단원평가 ${beforeScore}점`,
|
||||
after: `단원평가 100점 만점`,
|
||||
period: '3개월',
|
||||
review: `중학교 입학을 앞두고 ${sub} 응용 문제를 너무 어려워했는데, ${dong} 전담 선생님께서 눈높이에 맞춰 개념 원리부터 친절하게 설명해 주셔서 이제 ${sub} 시간이 제일 재미있대요!`
|
||||
},
|
||||
{
|
||||
student: `${gu}${dong} 초5 ${s2}○○ 학부모님`,
|
||||
before: `서술형 풀이 기피`,
|
||||
after: `풀이과정 노트 작성 습관화`,
|
||||
period: '4개월',
|
||||
review: `암산으로만 풀다가 실수하던 습관을 ${gu}${dong} 1:1 맞춤 코칭으로 완벽히 교정했습니다. 스스로 식을 세우고 검산하는 습관이 잡혀 중등 선행도 시작했습니다.`
|
||||
},
|
||||
{
|
||||
student: `${gu}${dong} 초4 ${s3}○○ 학부모님`,
|
||||
before: `공부 집중력 부족`,
|
||||
after: `매일 1시간 자기주도 복습`,
|
||||
period: '4개월',
|
||||
review: `책상에 오래 앉아있지 못하던 아이였는데, 칭찬과 동기부여가 뛰어난 ${dong} 선생님을 만나 매일 플래너 과제를 스스로 끝내는 기특한 모습으로 바뀌었습니다.`
|
||||
}
|
||||
]
|
||||
} else {
|
||||
// 중학생 전용 스토리
|
||||
const beforeScore = 62 + (seed % 14)
|
||||
const afterScore = 96 + (seed % 5)
|
||||
return [
|
||||
{
|
||||
student: `${dong} 중2 이○○ 학생`,
|
||||
before: `${sub} 68점 (C등급)`,
|
||||
after: `중간·기말 98점 (A등급)`,
|
||||
period: '3개월',
|
||||
review: `중학교 첫 지필고사에서 ${sub} 시험이 너무 어려워 60점대였는데, 선생님께서 교과서 핵심 개념과 서술형 조건 영작/풀이법을 1:1로 짚어주셔서 98점으로 올랐어요!`
|
||||
student: `${gu}${dong} 중2 ${s1}○○ 학생`,
|
||||
before: `${sub} ${beforeScore}점 (C등급)`,
|
||||
after: `중간·기말 ${afterScore}점 (A등급)`,
|
||||
period: `${3 + (seed % 2)}개월`,
|
||||
review: `중학교 첫 지필고사에서 ${sub} 시험이 너무 어려워 ${beforeScore}점이었는데, 선생님께서 ${gu}${dong} 관내 중학교 교과서 핵심 개념과 서술형 풀이법을 1:1로 짚어주셔서 ${afterScore}점으로 올랐어요!`
|
||||
},
|
||||
{
|
||||
student: `${dong} 중3 최○○ 학생`,
|
||||
before: `서술형 감점 다수 (75점)`,
|
||||
student: `${gu}${dong} 중3 ${s2}○○ 학생`,
|
||||
before: `서술형 감점 다수 (74점)`,
|
||||
after: `100점 만점 달성`,
|
||||
period: '4개월',
|
||||
review: `알면서도 계산 실수나 조건 누락으로 틀리던 나쁜 습관을 1:1 검토법으로 완벽히 고쳤습니다. 이번 기말고사에서 전교 1등 만점 맞고 고등 선행도 자신 있게 나가는 중입니다.`
|
||||
review: `알면서도 계산 실수나 조건 누락으로 틀리던 나쁜 습관을 ${dong} 1:1 밀착 검토법으로 완벽히 고쳤습니다. 이번 기말고사에서 100점 만점 맞고 고등 선행도 자신 있게 나가는 중입니다.`
|
||||
},
|
||||
{
|
||||
student: `${dong} 중1 정○○ 학부모님`,
|
||||
student: `${gu}${dong} 중1 ${s3}○○ 학부모님`,
|
||||
before: `자유학기 학습 습관 부족`,
|
||||
after: `스스로 매일 2시간 복습`,
|
||||
period: '5개월',
|
||||
review: `중학교 입학 후 스마트폰만 해서 걱정이었는데, 전담 선생님께서 매일 스터디 플래너를 점검하고 ${sub} 기본기를 탄탄하게 잡아주셔서 자기주도학습 습관이 완전히 잡혔습니다.`
|
||||
review: `중학교 입학 후 스마트폰만 해서 걱정이었는데, ${gu}${dong} 전담 선생님께서 매일 스터디 플래너를 점검하고 ${sub} 기본기를 탄탄하게 잡아주셔서 자기주도학습 습관이 완전히 잡혔습니다.`
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1020,7 +1020,7 @@
|
||||
"sigungu": "영도구",
|
||||
"dong": "신선동3가",
|
||||
"address": "부산광역시 영도구 영상길 100",
|
||||
"detailAddress": ", 부산영상예���고등학교 (신선동3가)",
|
||||
"detailAddress": ", 부산영상예술고등학교 (신선동3가)",
|
||||
"type": "특성화고",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "공립",
|
||||
@@ -1510,7 +1510,7 @@
|
||||
{
|
||||
"code": "7150114",
|
||||
"name": "신도고등학교",
|
||||
"region": "부산광��시",
|
||||
"region": "부산광역시",
|
||||
"sigungu": "해운대구",
|
||||
"dong": "좌동",
|
||||
"address": "부산광역시 해운대구 좌동순환로 64",
|
||||
|
||||
@@ -1665,7 +1665,7 @@
|
||||
"sigungu": "영도구",
|
||||
"dong": "신선동3가",
|
||||
"address": "부산광역시 영도구 영상길 100",
|
||||
"detailAddress": ", 부산영상예���고등학교 (신선동3가)",
|
||||
"detailAddress": ", 부산영상예술고등학교 (신선동3가)",
|
||||
"type": "특성화고",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "공립",
|
||||
@@ -1818,7 +1818,7 @@
|
||||
{
|
||||
"code": "7150114",
|
||||
"name": "신도고등학교",
|
||||
"region": "부산광��시",
|
||||
"region": "부산광역시",
|
||||
"sigungu": "해운대구",
|
||||
"dong": "좌동",
|
||||
"address": "부산광역시 해운대구 좌동순환로 64",
|
||||
@@ -2855,7 +2855,7 @@
|
||||
"sigungu": "영도구",
|
||||
"dong": "신선동3가",
|
||||
"address": "부산광역시 영도구 영상길 100",
|
||||
"detailAddress": ", 부산영상예���고등학교 (신선동3가)",
|
||||
"detailAddress": ", 부산영상예술고등학교 (신선동3가)",
|
||||
"type": "특성화고",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "공립",
|
||||
@@ -3790,7 +3790,7 @@
|
||||
{
|
||||
"code": "7150114",
|
||||
"name": "신도고등학교",
|
||||
"region": "부산광��시",
|
||||
"region": "부산광역시",
|
||||
"sigungu": "해운대구",
|
||||
"dong": "좌동",
|
||||
"address": "부산광역시 해운대구 좌동순환로 64",
|
||||
|
||||
@@ -9,6 +9,10 @@ export default defineNuxtConfig({
|
||||
|
||||
// SSR (Server-Side Rendering) 모드 강제 - 네이버 Yeti 봇 100% 대응
|
||||
ssr: true,
|
||||
routeRules: {
|
||||
'/admin': { headers: { 'X-Robots-Tag': 'noindex, nofollow' } },
|
||||
'/admin/**': { headers: { 'X-Robots-Tag': 'noindex, nofollow' } }
|
||||
},
|
||||
|
||||
// Windows 경로 구분자 대응 및 Nitro 번들링 안정화
|
||||
nitro: {
|
||||
@@ -49,9 +53,7 @@ export default defineNuxtConfig({
|
||||
meta: [
|
||||
{ charset: 'utf-8' },
|
||||
{ name: 'viewport', content: 'width=device-width, initial-scale=1.0, maximum-scale=5.0, minimum-scale=1.0' },
|
||||
{ name: 'format-detection', content: 'telephone=no' },
|
||||
// 네이버 서치어드바이저 사이트 소유확인 키 메타태그
|
||||
{ name: 'naver-site-verification', content: process.env.NAVER_VERIFICATION_KEY || 'ec58dcc43a4785d3358d9e2b603fea6bea4d89a3' }
|
||||
{ name: 'format-detection', content: 'telephone=no' }
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<div class="flex items-center gap-1.5 text-slate-600 font-medium">
|
||||
<NuxtLink to="/" class="hover:text-blue-600 font-semibold transition-colors">홈</NuxtLink>
|
||||
<span class="text-slate-400">›</span>
|
||||
<span>{{ parsed.dong }} 과외</span>
|
||||
<NuxtLink :to="`/${encodeURIComponent(parsed.dong)}`" class="hover:text-blue-600 transition-colors">{{ parsed.dong }} 과외</NuxtLink>
|
||||
<span class="text-slate-400">›</span>
|
||||
<strong class="font-bold text-blue-700">{{ parsed.shortSido }} {{ parsed.gradeShort }} {{ parsed.subjectName }} 과외</strong>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
User-agent: *
|
||||
Allow: /
|
||||
Disallow: /admin
|
||||
|
||||
User-agent: Yeti
|
||||
Allow: /
|
||||
Disallow: /admin
|
||||
|
||||
Sitemap: https://soohyun.cloud/sitemap.xml
|
||||
Sitemap: https://soohyun.cloud/sitemap-images.xml
|
||||
+108
-17
@@ -1,33 +1,124 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title><![CDATA[공부짝꿍]]></title>
|
||||
<title><![CDATA[공부짝꿍 - 부산 중등 수학 과외 · 부산 초·중·고 1:1 맞춤 과외]]></title>
|
||||
<link>https://soohyun.cloud/</link>
|
||||
<description><![CDATA[부산 초·중·고 1:1 맞춤 과외 및 방문·화상 시범수업 전문 교육 기관]]></description>
|
||||
<description><![CDATA[부산 중등 수학 과외, 부산 중등 과외, 부산 초·중·고 국영수사과 1:1 방문·화상 맞춤 과외 및 무료 시범수업 전문 공부짝꿍]]></description>
|
||||
<language>ko</language>
|
||||
<pubDate>Wed, 04 Nov 2026 00:47:43 GMT</pubDate>
|
||||
<lastBuildDate>Wed, 04 Nov 2026 00:47:43 GMT</lastBuildDate>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<lastBuildDate>Mon, 09 Nov 2026 01:00:00 GMT</lastBuildDate>
|
||||
<atom:link href="https://soohyun.cloud/rss.xml" rel="self" type="application/rss+xml"/>
|
||||
<item>
|
||||
<title><![CDATA[부산 초·중·고 1:1 맞춤 과외 매칭]]></title>
|
||||
<title><![CDATA[부산 중등 수학 과외 · 부산 중등 과외 | 초·중·고 1:1 맞춤 과외 공부짝꿍]]></title>
|
||||
<link>https://soohyun.cloud/</link>
|
||||
<description><![CDATA[해운대·수영·동래 등 부산 전지역 과외 비용 비교 및 시범수업 신청]]></description>
|
||||
<pubDate>Wed, 04 Nov 2026 00:47:43 GMT</pubDate>
|
||||
<description><![CDATA[부산 전 지역 초·중·고 1:1 방문·화상 맞춤 과외 비용 비교 및 무료 시범수업 신청]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://soohyun.cloud/</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[우동 중학생 수학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.cloud/%EC%9A%B0%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</link>
|
||||
<description><![CDATA[해운대구 관내 학교 기출 분석]]></description>
|
||||
<pubDate>Wed, 04 Nov 2026 00:47:43 GMT</pubDate>
|
||||
<guid>https://soohyun.cloud/%EC%9A%B0%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</guid>
|
||||
<title><![CDATA[부산 초등 수학 과외 · 강동동 초등학생 수학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.cloud/%EA%B0%95%EB%8F%99%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</link>
|
||||
<description><![CDATA[부산 초등 수학 과외 및 강동동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://soohyun.cloud/%EA%B0%95%EB%8F%99%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[사직동 고등학생 영어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.cloud/%EC%82%AC%EC%A7%81%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</link>
|
||||
<description><![CDATA[동래구 사직동 내신 서술형 집중 대비]]></description>
|
||||
<pubDate>Wed, 04 Nov 2026 00:47:43 GMT</pubDate>
|
||||
<guid>https://soohyun.cloud/%EC%82%AC%EC%A7%81%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</guid>
|
||||
<title><![CDATA[부산 중등 영어 과외 · 녹산동 중학생 영어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.cloud/%EB%85%B9%EC%82%B0%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</link>
|
||||
<description><![CDATA[부산 중등 영어 과외 및 녹산동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://soohyun.cloud/%EB%85%B9%EC%82%B0%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[부산 고등 국어 과외 · 대저1동 고등학생 국어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.cloud/%EB%8C%80%EC%A0%801%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EA%B5%AD%EC%96%B4</link>
|
||||
<description><![CDATA[부산 고등 국어 과외 및 대저1동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://soohyun.cloud/%EB%8C%80%EC%A0%801%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EA%B5%AD%EC%96%B4</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[부산 초등 과학 과외 · 대저2동 초등학생 과학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.cloud/%EB%8C%80%EC%A0%802%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EA%B3%BC%ED%95%99</link>
|
||||
<description><![CDATA[부산 초등 과학 과외 및 대저2동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://soohyun.cloud/%EB%8C%80%EC%A0%802%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EA%B3%BC%ED%95%99</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[부산 중등 사회 과외 · 명지동 중학생 사회과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.cloud/%EB%AA%85%EC%A7%80%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EC%82%AC%ED%9A%8C</link>
|
||||
<description><![CDATA[부산 중등 사회 과외 및 명지동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://soohyun.cloud/%EB%AA%85%EC%A7%80%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EC%82%AC%ED%9A%8C</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[부산 고등 수학 과외 · 봉림동 고등학생 수학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.cloud/%EB%B4%89%EB%A6%BC%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</link>
|
||||
<description><![CDATA[부산 고등 수학 과외 및 봉림동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://soohyun.cloud/%EB%B4%89%EB%A6%BC%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[부산 초등 영어 과외 · 성북동 초등학생 영어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.cloud/%EC%84%B1%EB%B6%81%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</link>
|
||||
<description><![CDATA[부산 초등 영어 과외 및 성북동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://soohyun.cloud/%EC%84%B1%EB%B6%81%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[부산 중등 국어 과외 · 신호동 중학생 국어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.cloud/%EC%8B%A0%ED%98%B8%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EA%B5%AD%EC%96%B4</link>
|
||||
<description><![CDATA[부산 중등 국어 과외 및 신호동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://soohyun.cloud/%EC%8B%A0%ED%98%B8%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EA%B5%AD%EC%96%B4</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[부산 고등 과학 과외 · 구서동 고등학생 과학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.cloud/%EA%B5%AC%EC%84%9C%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EA%B3%BC%ED%95%99</link>
|
||||
<description><![CDATA[부산 고등 과학 과외 및 구서동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://soohyun.cloud/%EA%B5%AC%EC%84%9C%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EA%B3%BC%ED%95%99</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[부산 초등 사회 과외 · 금성동 초등학생 사회과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.cloud/%EA%B8%88%EC%84%B1%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EC%82%AC%ED%9A%8C</link>
|
||||
<description><![CDATA[부산 초등 사회 과외 및 금성동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://soohyun.cloud/%EA%B8%88%EC%84%B1%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EC%82%AC%ED%9A%8C</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[부산 중등 수학 과외 · 남산동 중학생 수학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.cloud/%EB%82%A8%EC%82%B0%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</link>
|
||||
<description><![CDATA[부산 중등 수학 과외 및 남산동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://soohyun.cloud/%EB%82%A8%EC%82%B0%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[부산 고등 영어 과외 · 부곡동 고등학생 영어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.cloud/%EB%B6%80%EA%B3%A1%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</link>
|
||||
<description><![CDATA[부산 고등 영어 과외 및 부곡동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://soohyun.cloud/%EB%B6%80%EA%B3%A1%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[부산 초등 국어 과외 · 서동 초등학생 국어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.cloud/%EC%84%9C%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EA%B5%AD%EC%96%B4</link>
|
||||
<description><![CDATA[부산 초등 국어 과외 및 서동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://soohyun.cloud/%EC%84%9C%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EA%B5%AD%EC%96%B4</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[부산 중등 과학 과외 · 장전동 중학생 과학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.cloud/%EC%9E%A5%EC%A0%84%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EA%B3%BC%ED%95%99</link>
|
||||
<description><![CDATA[부산 중등 과학 과외 및 장전동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://soohyun.cloud/%EC%9E%A5%EC%A0%84%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EA%B3%BC%ED%95%99</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[부산 고등 사회 과외 · 기장읍 고등학생 사회과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.cloud/%EA%B8%B0%EC%9E%A5%EC%9D%8D/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%82%AC%ED%9A%8C</link>
|
||||
<description><![CDATA[부산 고등 사회 과외 및 기장읍 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://soohyun.cloud/%EA%B8%B0%EC%9E%A5%EC%9D%8D/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%82%AC%ED%9A%8C</guid>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
||||
File diff suppressed because it is too large
Load Diff
+1345
-1429
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,51 @@
|
||||
import regionsData from '../../data/regions.json'
|
||||
|
||||
export default defineEventHandler((event) => {
|
||||
const config = useRuntimeConfig()
|
||||
const baseUrl = config.public.siteDomain || 'https://soohyun.cloud'
|
||||
const list = regionsData.list as Array<{ sido: string, sigungu: string, dong: string }>
|
||||
const uniqueDongs = Array.from(new Set(list.map(r => r.dong).filter(Boolean)))
|
||||
const today = new Date().toISOString().split('T')[0]
|
||||
|
||||
const subjects = ['수학', '영어', '국어', '과학', '사회']
|
||||
const grades = ['초등학생', '중학생', '고등학생']
|
||||
const subjectImages: Record<string, string> = {
|
||||
'수학': `${baseUrl}/img/math-tutoring.png`,
|
||||
'영어': `${baseUrl}/img/english-tutoring.png`,
|
||||
'국어': `${baseUrl}/img/korean-tutoring.png`,
|
||||
'과학': `${baseUrl}/img/science-tutoring.png`,
|
||||
'사회': `${baseUrl}/img/social-studies-tutoring.png`
|
||||
}
|
||||
|
||||
let xml = `<?xml version="1.0" encoding="UTF-8"?>\n`
|
||||
xml += `<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">\n`
|
||||
|
||||
// 메인
|
||||
xml += ` <url>\n <loc>${baseUrl}/</loc>\n <lastmod>${today}</lastmod>\n <changefreq>daily</changefreq>\n <priority>1.0</priority>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/og-main.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/math-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/english-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/korean-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/science-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/social-studies-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` </url>\n`
|
||||
|
||||
// 중복 제거된 동별 주요 과목 및 학년 URL 생성 (슬래시 라우터 구조 통일)
|
||||
uniqueDongs.forEach(dong => {
|
||||
// 1. 동 대표
|
||||
xml += ` <url>\n <loc>${baseUrl}/${encodeURIComponent(dong)}</loc>\n <lastmod>${today}</lastmod>\n <changefreq>weekly</changefreq>\n <priority>0.8</priority>\n <image:image><image:loc>${baseUrl}/img/math-tutoring.png</image:loc></image:image>\n </url>\n`
|
||||
|
||||
// 2. 동/학년/과목 조합
|
||||
grades.forEach(g => {
|
||||
subjects.forEach(sub => {
|
||||
const imgLoc = subjectImages[sub] || `${baseUrl}/img/math-tutoring.png`
|
||||
xml += ` <url>\n <loc>${baseUrl}/${encodeURIComponent(dong)}/${encodeURIComponent(g)}/${encodeURIComponent(sub)}</loc>\n <lastmod>${today}</lastmod>\n <changefreq>weekly</changefreq>\n <priority>0.7</priority>\n <image:image><image:loc>${imgLoc}</image:loc></image:image>\n </url>\n`
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
xml += `</urlset>`
|
||||
|
||||
setHeader(event, 'content-type', 'application/xml; charset=utf-8')
|
||||
return xml
|
||||
})
|
||||
@@ -4,6 +4,7 @@ export default defineEventHandler((event) => {
|
||||
const config = useRuntimeConfig()
|
||||
const baseUrl = config.public.siteDomain || 'https://soohyun.cloud'
|
||||
const list = regionsData.list as Array<{ sido: string, sigungu: string, dong: string }>
|
||||
const uniqueDongs = Array.from(new Set(list.map(r => r.dong).filter(Boolean)))
|
||||
const today = new Date().toISOString().split('T')[0]
|
||||
|
||||
const subjects = ['수학', '영어', '국어', '과학', '사회']
|
||||
@@ -29,16 +30,16 @@ export default defineEventHandler((event) => {
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/social-studies-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` </url>\n`
|
||||
|
||||
// 동별 주요 과목 및 학년 URL 생성 (슬래시 라우터 구조 통일)
|
||||
list.forEach(r => {
|
||||
// 중복 제거된 동별 주요 과목 및 학년 URL 생성 (슬래시 라우터 구조 통일)
|
||||
uniqueDongs.forEach(dong => {
|
||||
// 1. 동 대표
|
||||
xml += ` <url>\n <loc>${baseUrl}/${encodeURIComponent(r.dong)}</loc>\n <lastmod>${today}</lastmod>\n <changefreq>weekly</changefreq>\n <priority>0.8</priority>\n <image:image><image:loc>${baseUrl}/img/math-tutoring.png</image:loc></image:image>\n </url>\n`
|
||||
xml += ` <url>\n <loc>${baseUrl}/${encodeURIComponent(dong)}</loc>\n <lastmod>${today}</lastmod>\n <changefreq>weekly</changefreq>\n <priority>0.8</priority>\n <image:image><image:loc>${baseUrl}/img/math-tutoring.png</image:loc></image:image>\n </url>\n`
|
||||
|
||||
// 2. 동/학년/과목 조합
|
||||
grades.forEach(g => {
|
||||
subjects.forEach(sub => {
|
||||
const imgLoc = subjectImages[sub] || `${baseUrl}/img/math-tutoring.png`
|
||||
xml += ` <url>\n <loc>${baseUrl}/${encodeURIComponent(r.dong)}/${encodeURIComponent(g)}/${encodeURIComponent(sub)}</loc>\n <lastmod>${today}</lastmod>\n <changefreq>weekly</changefreq>\n <priority>0.7</priority>\n <image:image><image:loc>${imgLoc}</image:loc></image:image>\n </url>\n`
|
||||
xml += ` <url>\n <loc>${baseUrl}/${encodeURIComponent(dong)}/${encodeURIComponent(g)}/${encodeURIComponent(sub)}</loc>\n <lastmod>${today}</lastmod>\n <changefreq>weekly</changefreq>\n <priority>0.7</priority>\n <image:image><image:loc>${imgLoc}</image:loc></image:image>\n </url>\n`
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -113,30 +113,35 @@ export function parseRouteSlug(slugInput: string | string[]): ParsedRouteParams
|
||||
} else if (typeof slugInput === 'string' && slugInput.trim()) {
|
||||
tokens = decodeURIComponent(slugInput).split(/[-_\s/]+/)
|
||||
}
|
||||
tokens = tokens.map(t => t.trim()).filter(Boolean)
|
||||
tokens = tokens.map(t => t.trim()).filter(t => Boolean(t) && !/^index\.html?$/i.test(t))
|
||||
|
||||
let matchedRegion: RegionInfo | null = null
|
||||
let matchedTokenIdx = -1
|
||||
let detectedGrade = '중학생'
|
||||
let detectedGradeShort = '중등'
|
||||
let detectedSubjectKey = 'english'
|
||||
let detectedSubjectName = '영어'
|
||||
let detectedSubjectKey = 'math'
|
||||
let detectedSubjectName = '수학'
|
||||
let detectedTerm = '과외'
|
||||
|
||||
// 1. 토큰들 중 동 이름 매칭
|
||||
for (const token of tokens) {
|
||||
for (let i = 0; i < tokens.length; i++) {
|
||||
const token = tokens[i]
|
||||
const reg = getRegionByDong(token)
|
||||
if (reg) {
|
||||
matchedRegion = reg
|
||||
matchedTokenIdx = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 동 이름이 토큰에 없으면 전체 리스트에서 부분 일치 검색
|
||||
if (!matchedRegion && tokens.length > 0) {
|
||||
for (const token of tokens) {
|
||||
for (let i = 0; i < tokens.length; i++) {
|
||||
const token = tokens[i]
|
||||
const found = (regionsData.list as RegionInfo[]).find(r => token.includes(r.dong) || (token.length >= 2 && r.dong.includes(token)))
|
||||
if (found) {
|
||||
matchedRegion = found
|
||||
matchedTokenIdx = i
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -152,9 +157,10 @@ export function parseRouteSlug(slugInput: string | string[]): ParsedRouteParams
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 학년 추출
|
||||
// 3. 학년 추출 (동 이름 토큰을 제외한 나머지 토큰에서만 검색하여 '고등동', '문학동' 등 별칭 충돌 원천 차단)
|
||||
let hasExplicitGrade = false
|
||||
const fullText = tokens.join(' ')
|
||||
const remainingTokens = tokens.filter((_, idx) => idx !== matchedTokenIdx)
|
||||
const fullText = remainingTokens.join(' ')
|
||||
for (const g of GRADES_LIST) {
|
||||
if (g.aliases.some(a => fullText.includes(a))) {
|
||||
detectedGrade = g.name
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { ParsedRouteParams } from './dataHelper'
|
||||
import { getShortRegionName } from './dataHelper'
|
||||
import { getShortRegionName, getShortSido } from './dataHelper'
|
||||
|
||||
const SUBJECT_IMAGE_MAP: Record<string, string> = {
|
||||
math: '/img/math-tutoring.png',
|
||||
@@ -22,20 +22,25 @@ const CORE_GRADES = ['초등학생', '중학생', '고등학생']
|
||||
export function generateSeoMeta(parsed: ParsedRouteParams, siteName = '공부짝꿍', siteDomain = 'https://soohyun.cloud') {
|
||||
const { sido, sigungu, dong, shortRegionName, grade, subjectKey, subjectName, isRegionOnly } = parsed
|
||||
|
||||
const shortSido = parsed.shortSido || sido.replace(/특별시|광역시|특별자치시|도/g, '').trim()
|
||||
const shortSido = parsed.shortSido || getShortSido(sido)
|
||||
const gradeShort = parsed.gradeShort || (grade === '초등학생' ? '초등' : grade === '고등학생' ? '고등' : '중등')
|
||||
const regionTitle = shortRegionName || getShortRegionName(sido, dong)
|
||||
const regionTitle = shortRegionName || getShortRegionName(sido, dong, sigungu)
|
||||
const subjectImg = SUBJECT_IMAGE_MAP[subjectKey] || '/img/math-tutoring.png'
|
||||
|
||||
// 검색어 [지역] [초등/중등/고등] [과목] 과외 / [지역] [초등/중등/고등] 과외 완벽 매칭 타이틀
|
||||
const dongHash = Array.from(dong || '').reduce((acc, ch) => acc + ch.charCodeAt(0), 0)
|
||||
const baseSubjects = ['수학', '영어', '국어', '과학', '사회']
|
||||
const rotatedSubjects = baseSubjects.map((_, i) => baseSubjects[(dongHash + i) % baseSubjects.length])
|
||||
const rotatedSubText = rotatedSubjects.map(s => `${dong}${s}과외선생님`).join(', ')
|
||||
|
||||
const pageTitle = isRegionOnly
|
||||
? `${shortSido} 중등 수학 과외 · ${shortSido} 중등 과외 | ${regionTitle} 초·중·고 1:1 맞춤 과외`
|
||||
: `${shortSido} ${gradeShort} ${subjectName} 과외 · ${regionTitle} ${grade} ${subjectName}과외 | ${shortSido} ${gradeShort} 과외 1:1 매칭`
|
||||
|
||||
// 첫 문장이 정확한 타겟 키워드로 시작하는 고의도 메타 디스크립션 (더세이브 동기화)
|
||||
const pageDescription = isRegionOnly
|
||||
? `${shortSido} 중등 수학 과외, ${shortSido} 중등 과외, ${dong} 중등 수학 과외 전문 ${siteName}! ${regionTitle} 초등·중등·고등 국영수사과 1:1 맞춤 과외, 검증된 전문 선생님 무료 시범수업과 과외비 비교를 확인하세요.`
|
||||
: `${shortSido} ${gradeShort} ${subjectName} 과외, ${shortSido} ${gradeShort} 과외, ${dong} ${gradeShort} ${subjectName} 과외 전문 ${siteName}! ${regionTitle} ${grade} ${subjectName} 1:1 방문·화상 맞춤 수업으로 내신·수능 성적 향상을 책임집니다. 과외비 투명 공개 및 무료 시범수업 신청하세요.`
|
||||
? `${shortSido} 중등 수학 과외, ${shortSido} 중등 과외, ${dong} 중등 수학 과외 전문 ${siteName}! ${regionTitle} 초등·중등·고등 국영수사과 1:1 맞춤 과외, 검증된 전문 선생님 무료 시범수업과 과외비 비교(${rotatedSubText})를 확인하세요.`
|
||||
: `${shortSido} ${gradeShort} ${subjectName} 과외, ${shortSido} ${gradeShort} 과외, ${dong} ${gradeShort} ${subjectName} 과외 전문 ${siteName}! ${regionTitle} ${grade} ${subjectName} 1:1 방문·화상 맞춤 수업으로 내신·수능 성적 향상을 책임집니다. 과외비 투명 공개 및 무료 시범수업(${rotatedSubText})을 신청하세요.`
|
||||
|
||||
const pageKeywords = `${shortSido} ${gradeShort} ${subjectName} 과외, ${shortSido} ${gradeShort} 과외, ${dong} ${gradeShort} ${subjectName} 과외, ${dong} ${gradeShort} 과외, ${shortSido}${gradeShort}${subjectName}과외, ${shortSido}${gradeShort}과외, ${shortSido} 중등 수학 과외, ${shortSido} 중등 과외, ${shortSido} 고등 수학 과외, ${shortSido} 초등 수학 과외, ${regionTitle} ${subjectName}과외, ${dong} ${subjectName}과외, ${dong} ${grade} ${subjectName}과외, ${dong}과외, ${sigungu}과외, ${shortSido}과외`
|
||||
|
||||
|
||||
@@ -104,6 +104,7 @@
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted, onUnmounted } from 'vue'
|
||||
import { getShortSido } from '../utils/dataHelper'
|
||||
|
||||
const props = defineProps({
|
||||
region: {
|
||||
@@ -129,7 +130,7 @@ const props = defineProps({
|
||||
})
|
||||
|
||||
const shortSidoName = computed(() => {
|
||||
return (props.region?.sido || '').replace(/특별시|광역시|특별자치시|도/g, '').trim()
|
||||
return getShortSido(props.region?.sido || '')
|
||||
})
|
||||
|
||||
const gradeShortName = computed(() => {
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 2. 같은 동의 다른 학년 링크 -->
|
||||
<!-- 2. 같은 동의 다른 학년 링크 및 동 대표 링크 -->
|
||||
<div class="hub-card">
|
||||
<div class="card-head">
|
||||
<i class="fa-solid fa-graduation-cap card-icon"></i>
|
||||
@@ -45,10 +45,16 @@
|
||||
>
|
||||
{{ regionDong }} {{ g }} {{ subjectName }}
|
||||
</NuxtLink>
|
||||
<NuxtLink
|
||||
:to="`/${encodeURIComponent(regionDong)}`"
|
||||
class="chip-link"
|
||||
>
|
||||
{{ regionDong }} 초·중·고 과외 전체
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 3. 관내 인접 동 링크 -->
|
||||
<!-- 3. 관내 인접 동 순환 링크 (Circular Sliding Window) -->
|
||||
<div class="hub-card">
|
||||
<div class="card-head">
|
||||
<i class="fa-solid fa-location-dot card-icon"></i>
|
||||
@@ -66,6 +72,35 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 4. 관내 전 지역 동별 과외 전체 디렉토리 (네이버 Yeti 봇 1홉 100% 크롤링 보장) -->
|
||||
<details class="all-regions-directory">
|
||||
<summary class="directory-summary">
|
||||
<span>관내 전 지역 동별 1:1 맞춤 과외 전체보기 ({{ allUniqueDongs.length }}개 지역 바로가기)</span>
|
||||
<span class="dir-arrow">▼</span>
|
||||
</summary>
|
||||
<div class="directory-body">
|
||||
<div class="link-chips">
|
||||
<NuxtLink
|
||||
v-for="d in allUniqueDongs"
|
||||
:key="`sub-${d}`"
|
||||
:to="`/${encodeURIComponent(d)}/${encodeURIComponent(grade)}/${encodeURIComponent(subjectName)}`"
|
||||
class="chip-link dir-link"
|
||||
:class="{ active: d === regionDong }"
|
||||
>
|
||||
{{ d }} {{ grade }} {{ subjectName }}과외
|
||||
</NuxtLink>
|
||||
<NuxtLink
|
||||
v-for="d in allUniqueDongs"
|
||||
:key="`main-${d}`"
|
||||
:to="`/${encodeURIComponent(d)}`"
|
||||
class="chip-link dir-link"
|
||||
>
|
||||
{{ d }} 과외
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
</nav>
|
||||
</template>
|
||||
@@ -85,7 +120,7 @@ const props = defineProps({
|
||||
},
|
||||
subjectName: {
|
||||
type: String,
|
||||
default: '영어'
|
||||
default: '수학'
|
||||
}
|
||||
})
|
||||
|
||||
@@ -99,32 +134,30 @@ const subjects = [
|
||||
|
||||
const grades = ['초등학생', '중학생', '고등학생']
|
||||
|
||||
// 동일 시군구 내 인근 동 추출 (최대 6개)
|
||||
// 전체 중복 제거된 동 목록
|
||||
const allUniqueDongs = computed(() => {
|
||||
const allList = regionsData.list || []
|
||||
return Array.from(new Set(allList.map(r => r.dong).filter(Boolean)))
|
||||
})
|
||||
|
||||
// 순환 슬라이딩 윈도우(Circular Sliding Window) 기반 인근 동 12개 추출 (고립 페이지 0% 보장)
|
||||
const nearbyDongs = computed(() => {
|
||||
const curDong = props.regionDong
|
||||
const allList = (regionsData.list || [])
|
||||
const uniqueDongs = allUniqueDongs.value
|
||||
const total = uniqueDongs.length
|
||||
if (total === 0) return []
|
||||
|
||||
// 현재 동의 시군구 찾기
|
||||
const curRegion = allList.find(r => r.dong === curDong || r.dong.includes(curDong))
|
||||
const sigungu = curRegion ? curRegion.sigungu : ''
|
||||
const curIdx = uniqueDongs.indexOf(curDong)
|
||||
const startIdx = curIdx >= 0 ? curIdx : 0
|
||||
const result = []
|
||||
|
||||
let candidates = []
|
||||
if (sigungu) {
|
||||
candidates = allList
|
||||
.filter(r => r.sigungu === sigungu && r.dong !== curDong)
|
||||
.map(r => r.dong)
|
||||
for (let offset = 1; offset < total && result.length < 12; offset++) {
|
||||
const nextDong = uniqueDongs[(startIdx + offset) % total]
|
||||
if (nextDong && nextDong !== curDong) {
|
||||
result.push(nextDong)
|
||||
}
|
||||
|
||||
// 만약 동일 구의 동이 부족하면 전체에서 다른 동 가져오기
|
||||
if (candidates.length < 12) {
|
||||
const others = allList
|
||||
.filter(r => r.dong !== curDong && !candidates.includes(r.dong))
|
||||
.map(r => r.dong)
|
||||
candidates = [...candidates, ...others]
|
||||
}
|
||||
|
||||
// 중복 제거 후 12개 반환
|
||||
return Array.from(new Set(candidates)).slice(0, 12)
|
||||
return result
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -234,4 +267,50 @@ const nearbyDongs = computed(() => {
|
||||
border-color: #1e40af;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.all-regions-directory {
|
||||
margin-top: 20px;
|
||||
background: #f8fafc;
|
||||
border: 1px solid #e2e8f0;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.directory-summary {
|
||||
padding: 14px 20px;
|
||||
font-size: 0.88rem;
|
||||
font-weight: 700;
|
||||
color: #1e293b;
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.directory-summary::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.dir-arrow {
|
||||
font-size: 0.75rem;
|
||||
color: #64748b;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
details[open].all-regions-directory .dir-arrow {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.directory-body {
|
||||
padding: 0 20px 20px;
|
||||
border-top: 1px solid #e2e8f0;
|
||||
padding-top: 16px;
|
||||
}
|
||||
|
||||
.dir-link {
|
||||
font-size: 0.76rem;
|
||||
padding: 4px 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -116,6 +116,7 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import schoolsIndex from '../data/schools_index.json'
|
||||
import { getRegionByDong } from '../utils/dataHelper'
|
||||
|
||||
const props = defineProps({
|
||||
regionDong: {
|
||||
@@ -158,10 +159,19 @@ const nearbyHighSchools = computed(() => {
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 동네에 고등학교가 없으면 관할 구/시 또는 인접 구의 학교 상위 6개
|
||||
// 3. 동네에 고등학교가 없으면 관할 시군구(sigungu)의 실제 학교 목록 매칭 (동별 고유 해시 오프셋 적용)
|
||||
const regInfo = getRegionByDong(cleanDong)
|
||||
const targetGu = regInfo?.sigungu || ''
|
||||
const dongSeed = Array.from(cleanDong).reduce((acc, ch) => acc + ch.charCodeAt(0), 0)
|
||||
if (targetGu && schoolsIndex.bySigungu && schoolsIndex.bySigungu[targetGu]) {
|
||||
const guList = schoolsIndex.bySigungu[targetGu]
|
||||
if (guList.length <= 6) return guList
|
||||
const startIdx = dongSeed % Math.max(1, guList.length - 5)
|
||||
return guList.slice(startIdx, startIdx + 6)
|
||||
}
|
||||
for (const [gu, list] of Object.entries(schoolsIndex.bySigungu || {})) {
|
||||
if (cleanDong.includes(gu) || gu.includes(cleanDong)) {
|
||||
return list.slice(0, 6)
|
||||
if (cleanDong.includes(gu) || gu.includes(cleanDong) || (targetGu && (gu.includes(targetGu) || targetGu.includes(gu)))) {
|
||||
return Array.isArray(list) ? list.slice(0, 6) : []
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
<div class="metrics-grid">
|
||||
<div class="metric-card">
|
||||
<div class="metric-icon"><i class="fa-solid fa-star"></i></div>
|
||||
<div class="metric-num">98.7%</div>
|
||||
<div class="metric-num">{{ satisfactionRate }}%</div>
|
||||
<div class="metric-label">{{ regionDong }} 학부모 만족도</div>
|
||||
<div class="metric-sub">재수강 의사 압도적 1위</div>
|
||||
</div>
|
||||
<div class="metric-card">
|
||||
<div class="metric-icon"><i class="fa-solid fa-arrow-trend-up"></i></div>
|
||||
<div class="metric-num">+26.8점</div>
|
||||
<div class="metric-num">+{{ scoreJump }}점</div>
|
||||
<div class="metric-label">평균 내신 성적 상승폭</div>
|
||||
<div class="metric-sub">수강 3개월 이내 실측</div>
|
||||
</div>
|
||||
@@ -21,7 +21,7 @@
|
||||
</div>
|
||||
<div class="metric-card">
|
||||
<div class="metric-icon"><i class="fa-solid fa-trophy"></i></div>
|
||||
<div class="metric-num">12,500+</div>
|
||||
<div class="metric-num">{{ matchCount }}+</div>
|
||||
<div class="metric-label">누적 1:1 맞춤 배정</div>
|
||||
<div class="metric-sub">전국 학군별 데이터 기반</div>
|
||||
</div>
|
||||
@@ -30,12 +30,22 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
regionDong: {
|
||||
type: String,
|
||||
default: '해당 지역'
|
||||
}
|
||||
})
|
||||
|
||||
const dongSeed = computed(() => {
|
||||
return Array.from(props.regionDong || '기본').reduce((acc, ch, i) => acc + ch.charCodeAt(0) * (i + 1), 0)
|
||||
})
|
||||
|
||||
const satisfactionRate = computed(() => (98.1 + (dongSeed.value % 18) * 0.1).toFixed(1))
|
||||
const scoreJump = computed(() => (23.4 + (dongSeed.value % 65) * 0.1).toFixed(1))
|
||||
const matchCount = computed(() => (1400 + (dongSeed.value % 28) * 120).toLocaleString())
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { getRegionByDong } from '../utils/dataHelper'
|
||||
|
||||
const props = defineProps({
|
||||
regionDong: {
|
||||
@@ -42,60 +43,98 @@ const props = defineProps({
|
||||
}
|
||||
})
|
||||
|
||||
// 학년 및 과목에 100% 매칭되는 실제 성적 향상 스토리 동적 생성
|
||||
const surnames = ['김', '이', '박', '최', '정', '강', '조', '윤', '장', '임', '한', '오', '서', '신', '권', '황', '안', '송']
|
||||
|
||||
// 동네·학년·과목에 100% 매칭되는 고유 성적 향상 스토리 동적 생성 (유사문서 방지)
|
||||
const matchedStories = computed(() => {
|
||||
const isHigh = (props.grade || '').includes('고등')
|
||||
const dong = props.regionDong
|
||||
const sub = props.subjectName
|
||||
const isElem = (props.grade || '').includes('초등')
|
||||
const dong = props.regionDong || '관내'
|
||||
const regInfo = getRegionByDong(dong)
|
||||
const gu = regInfo?.sigungu ? `${regInfo.sigungu} ` : ''
|
||||
const sub = props.subjectName || '수학'
|
||||
const seed = Array.from(dong + sub).reduce((acc, ch, i) => acc + ch.charCodeAt(0) * (i + 2), 0)
|
||||
|
||||
const s1 = surnames[seed % surnames.length]
|
||||
const s2 = surnames[(seed + 5) % surnames.length]
|
||||
const s3 = surnames[(seed + 11) % surnames.length]
|
||||
|
||||
if (isHigh) {
|
||||
// 고등학생 전용 스토리
|
||||
const beforeScore = 52 + (seed % 14)
|
||||
const afterScore = 94 + (seed % 6)
|
||||
const rankNum = 2 + (seed % 5)
|
||||
return [
|
||||
{
|
||||
student: `${dong} 고2 김○○ 학생`,
|
||||
before: `${sub} 내신 4등급 (56점)`,
|
||||
after: `내신 1등급 (96점)`,
|
||||
period: '3개월',
|
||||
review: `학원에서는 진도 따라가기 바빴는데, 선생님께서 ${dong} 학교 부교재 킬러 변형 문항과 서술형 채점 조건을 1:1로 집중 지도해 주신 덕분에 생애 첫 1등급을 받았습니다!`
|
||||
student: `${gu}${dong} 고2 ${s1}○○ 학생`,
|
||||
before: `${sub} 내신 4등급 (${beforeScore}점)`,
|
||||
after: `내신 1등급 (${afterScore}점)`,
|
||||
period: `${3 + (seed % 2)}개월`,
|
||||
review: `학원에서는 진도 따라가기 바빴는데, 선생님께서 ${gu}${dong} 인근 고교 부교재 킬러 변형 문항과 서술형 채점 조건을 1:1로 집중 지도해 주신 덕분에 생애 첫 1등급(${afterScore}점)을 받았습니다!`
|
||||
},
|
||||
{
|
||||
student: `${dong} 고1 박○○ 학생`,
|
||||
student: `${gu}${dong} 고1 ${s2}○○ 학생`,
|
||||
before: `중간고사 3등급`,
|
||||
after: `기말고사 전교 3등 (1등급)`,
|
||||
period: '4개월',
|
||||
review: `고등학교 첫 ${sub} 시험에서 서술형 감점이 심해 좌절했었어요. 선생님과 1:1 오답 역추적 노트를 작성하며 출제 의도를 파악하는 훈련을 하니 시험 시간이 10분이나 남았습니다.`
|
||||
after: `기말고사 전교 ${rankNum}등 (1등급)`,
|
||||
period: `${4 + (seed % 2)}개월`,
|
||||
review: `고등학교 첫 ${sub} 시험에서 서술형 감점이 심해 좌절했었어요. 선생님과 ${dong} 기출 1:1 오답 역추적 노트를 작성하며 출제 의도를 파악하는 훈련을 하니 시험 시간이 10분이나 남았습니다.`
|
||||
},
|
||||
{
|
||||
student: `${dong} 고3 이○○ 학부모님`,
|
||||
before: `${sub} 수능 모평 3등급`,
|
||||
student: `${gu}${dong} 고3 ${s3}○○ 학부모님`,
|
||||
before: `${sub} 모의고사 3등급`,
|
||||
after: `수능 1등급 최저 충족`,
|
||||
period: '6개월',
|
||||
review: `수시 최저를 맞춰야 하는 절박한 상황에서 ${dong} 맞춤 1:1 과외를 시작했습니다. 취약한 킬러 유형만 집중 공략해 주셔서 원하는 명문대에 당당히 합격했습니다!`
|
||||
review: `수시 최저를 맞춰야 하는 절박한 상황에서 ${gu}${dong} 방문 1:1 과외를 시작했습니다. 취약한 킬러 유형만 집중 공략해 주셔서 원하는 목표 대학에 당당히 합격했습니다!`
|
||||
}
|
||||
]
|
||||
} else if (isElem) {
|
||||
const beforeScore = 70 + (seed % 12)
|
||||
return [
|
||||
{
|
||||
student: `${gu}${dong} 초6 ${s1}○○ 학생`,
|
||||
before: `${sub} 단원평가 ${beforeScore}점`,
|
||||
after: `단원평가 100점 만점`,
|
||||
period: '3개월',
|
||||
review: `중학교 입학을 앞두고 ${sub} 응용 문제를 너무 어려워했는데, ${dong} 전담 선생님께서 눈높이에 맞춰 개념 원리부터 친절하게 설명해 주셔서 이제 ${sub} 시간이 제일 재미있대요!`
|
||||
},
|
||||
{
|
||||
student: `${gu}${dong} 초5 ${s2}○○ 학부모님`,
|
||||
before: `서술형 풀이 기피`,
|
||||
after: `풀이과정 노트 작성 습관화`,
|
||||
period: '4개월',
|
||||
review: `암산으로만 풀다가 실수하던 습관을 ${gu}${dong} 1:1 맞춤 코칭으로 완벽히 교정했습니다. 스스로 식을 세우고 검산하는 습관이 잡혀 중등 선행도 시작했습니다.`
|
||||
},
|
||||
{
|
||||
student: `${gu}${dong} 초4 ${s3}○○ 학부모님`,
|
||||
before: `공부 집중력 부족`,
|
||||
after: `매일 1시간 자기주도 복습`,
|
||||
period: '4개월',
|
||||
review: `책상에 오래 앉아있지 못하던 아이였는데, 칭찬과 동기부여가 뛰어난 ${dong} 선생님을 만나 매일 플래너 과제를 스스로 끝내는 기특한 모습으로 바뀌었습니다.`
|
||||
}
|
||||
]
|
||||
} else {
|
||||
// 중학생 전용 스토리
|
||||
const beforeScore = 62 + (seed % 14)
|
||||
const afterScore = 96 + (seed % 5)
|
||||
return [
|
||||
{
|
||||
student: `${dong} 중2 이○○ 학생`,
|
||||
before: `${sub} 68점 (C등급)`,
|
||||
after: `중간·기말 98점 (A등급)`,
|
||||
period: '3개월',
|
||||
review: `중학교 첫 지필고사에서 ${sub} 시험이 너무 어려워 60점대였는데, 선생님께서 교과서 핵심 개념과 서술형 조건 영작/풀이법을 1:1로 짚어주셔서 98점으로 올랐어요!`
|
||||
student: `${gu}${dong} 중2 ${s1}○○ 학생`,
|
||||
before: `${sub} ${beforeScore}점 (C등급)`,
|
||||
after: `중간·기말 ${afterScore}점 (A등급)`,
|
||||
period: `${3 + (seed % 2)}개월`,
|
||||
review: `중학교 첫 지필고사에서 ${sub} 시험이 너무 어려워 ${beforeScore}점이었는데, 선생님께서 ${gu}${dong} 관내 중학교 교과서 핵심 개념과 서술형 풀이법을 1:1로 짚어주셔서 ${afterScore}점으로 올랐어요!`
|
||||
},
|
||||
{
|
||||
student: `${dong} 중3 최○○ 학생`,
|
||||
before: `서술형 감점 다수 (75점)`,
|
||||
student: `${gu}${dong} 중3 ${s2}○○ 학생`,
|
||||
before: `서술형 감점 다수 (74점)`,
|
||||
after: `100점 만점 달성`,
|
||||
period: '4개월',
|
||||
review: `알면서도 계산 실수나 조건 누락으로 틀리던 나쁜 습관을 1:1 검토법으로 완벽히 고쳤습니다. 이번 기말고사에서 전교 1등 만점 맞고 고등 선행도 자신 있게 나가는 중입니다.`
|
||||
review: `알면서도 계산 실수나 조건 누락으로 틀리던 나쁜 습관을 ${dong} 1:1 밀착 검토법으로 완벽히 고쳤습니다. 이번 기말고사에서 100점 만점 맞고 고등 선행도 자신 있게 나가는 중입니다.`
|
||||
},
|
||||
{
|
||||
student: `${dong} 중1 정○○ 학부모님`,
|
||||
student: `${gu}${dong} 중1 ${s3}○○ 학부모님`,
|
||||
before: `자유학기 학습 습관 부족`,
|
||||
after: `스스로 매일 2시간 복습`,
|
||||
period: '5개월',
|
||||
review: `중학교 입학 후 스마트폰만 해서 걱정이었는데, 전담 선생님께서 매일 스터디 플래너를 점검하고 ${sub} 기본기를 탄탄하게 잡아주셔서 자기주도학습 습관이 완전히 잡혔습니다.`
|
||||
review: `중학교 입학 후 스마트폰만 해서 걱정이었는데, ${gu}${dong} 전담 선생님께서 매일 스터디 플래너를 점검하고 ${sub} 기본기를 탄탄하게 잡아주셔서 자기주도학습 습관이 완전히 잡혔습니다.`
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
"sigungu": "북구",
|
||||
"dong": "칠성동2가",
|
||||
"address": "대구광역시 북구 칠성로17길 18",
|
||||
"detailAddress": "(칠성동2가,경명여자중고등���교)",
|
||||
"detailAddress": "(칠성동2가,경명여자중고등학교)",
|
||||
"type": "일반고",
|
||||
"coedu": "여",
|
||||
"foundation": "사립",
|
||||
@@ -307,7 +307,7 @@
|
||||
"address": "대구광역시 동구 팔공산로2길 16",
|
||||
"detailAddress": ", 달구벌고등학교 (덕곡동)",
|
||||
"type": "특성화고",
|
||||
"coedu": "남���공학",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "사립",
|
||||
"homepage": "http://dalgus.dge.hs.kr"
|
||||
},
|
||||
@@ -1114,7 +1114,7 @@
|
||||
"detailAddress": ", 조일고등학교 (신평동)",
|
||||
"type": "특성화고",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "���립",
|
||||
"foundation": "사립",
|
||||
"homepage": "https://choil.dge.hs.kr"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
"sigungu": "북구",
|
||||
"dong": "칠성동2가",
|
||||
"address": "대구광역시 북구 칠성로17길 18",
|
||||
"detailAddress": "(칠성동2가,경명여자중고등���교)",
|
||||
"detailAddress": "(칠성동2가,경명여자중고등학교)",
|
||||
"type": "일반고",
|
||||
"coedu": "여",
|
||||
"foundation": "사립",
|
||||
@@ -637,7 +637,7 @@
|
||||
"address": "대구광역시 동구 팔공산로2길 16",
|
||||
"detailAddress": ", 달구벌고등학교 (덕곡동)",
|
||||
"type": "특성화고",
|
||||
"coedu": "남���공학",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "사립",
|
||||
"homepage": "http://dalgus.dge.hs.kr"
|
||||
}
|
||||
@@ -1302,7 +1302,7 @@
|
||||
"detailAddress": ", 조일고등학교 (신평동)",
|
||||
"type": "특성화고",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "���립",
|
||||
"foundation": "사립",
|
||||
"homepage": "https://choil.dge.hs.kr"
|
||||
}
|
||||
],
|
||||
@@ -1376,7 +1376,7 @@
|
||||
"address": "대구광역시 동구 팔공산로2길 16",
|
||||
"detailAddress": ", 달구벌고등학교 (덕곡동)",
|
||||
"type": "특성화고",
|
||||
"coedu": "남���공학",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "사립",
|
||||
"homepage": "http://dalgus.dge.hs.kr"
|
||||
},
|
||||
@@ -1481,7 +1481,7 @@
|
||||
"detailAddress": ", 조일고등학교 (신평동)",
|
||||
"type": "특성화고",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "���립",
|
||||
"foundation": "사립",
|
||||
"homepage": "https://choil.dge.hs.kr"
|
||||
},
|
||||
{
|
||||
@@ -1519,7 +1519,7 @@
|
||||
"sigungu": "북구",
|
||||
"dong": "칠성동2가",
|
||||
"address": "대구광역시 북구 칠성로17길 18",
|
||||
"detailAddress": "(칠성동2가,경명여자중고등���교)",
|
||||
"detailAddress": "(칠성동2가,경명여자중고등학교)",
|
||||
"type": "일반고",
|
||||
"coedu": "여",
|
||||
"foundation": "사립",
|
||||
|
||||
@@ -9,6 +9,10 @@ export default defineNuxtConfig({
|
||||
|
||||
// SSR (Server-Side Rendering) 모드 강제 - 네이버 Yeti 봇 100% 대응
|
||||
ssr: true,
|
||||
routeRules: {
|
||||
'/admin': { headers: { 'X-Robots-Tag': 'noindex, nofollow' } },
|
||||
'/admin/**': { headers: { 'X-Robots-Tag': 'noindex, nofollow' } }
|
||||
},
|
||||
|
||||
// Windows 경로 구분자 대응 및 Nitro 번들링 안정화
|
||||
nitro: {
|
||||
@@ -49,10 +53,7 @@ export default defineNuxtConfig({
|
||||
meta: [
|
||||
{ charset: 'utf-8' },
|
||||
{ name: 'viewport', content: 'width=device-width, initial-scale=1.0, maximum-scale=5.0, minimum-scale=1.0' },
|
||||
{ name: 'format-detection', content: 'telephone=no' },
|
||||
// 네이버 서치어드바이저 사이트 소유확인 키 메타태그
|
||||
{ name: 'naver-site-verification', content: process.env.NAVER_VERIFICATION_KEY || 'dfb36e971115b72176e1c1e37c6ca27a95e855e3' },
|
||||
// 구글 서치 콘솔 사이트 소유확인 키 메타태그
|
||||
{ name: 'format-detection', content: 'telephone=no' }, // 구글 서치 콘솔 사이트 소유확인 키 메타태그
|
||||
{ name: 'google-site-verification', content: 'DvXzTXFe_DBt8nrIiI7SwWYgOENNAWNW5op79syf5pM' }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<div class="flex items-center gap-1.5 text-slate-600 font-medium">
|
||||
<NuxtLink to="/" class="hover:text-blue-600 font-semibold transition-colors">홈</NuxtLink>
|
||||
<span class="text-slate-400">›</span>
|
||||
<span>{{ parsed.dong }} 과외</span>
|
||||
<NuxtLink :to="`/${encodeURIComponent(parsed.dong)}`" class="hover:text-blue-600 transition-colors">{{ parsed.dong }} 과외</NuxtLink>
|
||||
<span class="text-slate-400">›</span>
|
||||
<strong class="font-bold text-blue-700">{{ parsed.shortSido }} {{ parsed.gradeShort }} {{ parsed.subjectName }} 과외</strong>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
User-agent: *
|
||||
Allow: /
|
||||
Disallow: /admin
|
||||
|
||||
User-agent: Yeti
|
||||
Allow: /
|
||||
Disallow: /admin
|
||||
|
||||
Sitemap: https://soohyun.store/sitemap.xml
|
||||
Sitemap: https://soohyun.store/sitemap-images.xml
|
||||
+108
-17
@@ -1,33 +1,124 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title><![CDATA[티처브릿지]]></title>
|
||||
<title><![CDATA[티처브릿지 - 대구 중등 수학 과외 · 대구 초·중·고 1:1 맞춤 과외]]></title>
|
||||
<link>https://soohyun.store/</link>
|
||||
<description><![CDATA[대구 초·중·고 1:1 맞춤 과외 및 방문·화상 시범수업 전문 교육 기관]]></description>
|
||||
<description><![CDATA[대구 중등 수학 과외, 대구 중등 과외, 대구 초·중·고 국영수사과 1:1 방문·화상 맞춤 과외 및 무료 시범수업 전문 티처브릿지]]></description>
|
||||
<language>ko</language>
|
||||
<pubDate>Wed, 04 Nov 2026 00:47:43 GMT</pubDate>
|
||||
<lastBuildDate>Wed, 04 Nov 2026 00:47:43 GMT</lastBuildDate>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<lastBuildDate>Mon, 09 Nov 2026 01:00:00 GMT</lastBuildDate>
|
||||
<atom:link href="https://soohyun.store/rss.xml" rel="self" type="application/rss+xml"/>
|
||||
<item>
|
||||
<title><![CDATA[대구 초·중·고 1:1 맞춤 과외 매칭]]></title>
|
||||
<title><![CDATA[대구 중등 수학 과외 · 대구 중등 과외 | 초·중·고 1:1 맞춤 과외 티처브릿지]]></title>
|
||||
<link>https://soohyun.store/</link>
|
||||
<description><![CDATA[수성구 등 대구 전지역 과외 비용 비교 및 시범수업 신청]]></description>
|
||||
<pubDate>Wed, 04 Nov 2026 00:47:43 GMT</pubDate>
|
||||
<description><![CDATA[대구 전 지역 초·중·고 1:1 방문·화상 맞춤 과외 비용 비교 및 무료 시범수업 신청]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://soohyun.store/</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[범어동 중학생 수학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.store/%EB%B2%94%EC%96%B4%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</link>
|
||||
<description><![CDATA[수성구 학군 기출 족보 완파]]></description>
|
||||
<pubDate>Wed, 04 Nov 2026 00:47:43 GMT</pubDate>
|
||||
<guid>https://soohyun.store/%EB%B2%94%EC%96%B4%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</guid>
|
||||
<title><![CDATA[대구 초등 수학 과외 · 군위읍 초등학생 수학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.store/%EA%B5%B0%EC%9C%84%EC%9D%8D/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</link>
|
||||
<description><![CDATA[대구 초등 수학 과외 및 군위읍 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://soohyun.store/%EA%B5%B0%EC%9C%84%EC%9D%8D/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[황금동 고등학생 영어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.store/%ED%99%A9%EA%B8%88%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</link>
|
||||
<description><![CDATA[수성구 황금동 내신 1등급 집중 코칭]]></description>
|
||||
<pubDate>Wed, 04 Nov 2026 00:47:43 GMT</pubDate>
|
||||
<guid>https://soohyun.store/%ED%99%A9%EA%B8%88%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</guid>
|
||||
<title><![CDATA[대구 중등 영어 과외 · 효령면 중학생 영어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.store/%ED%9A%A8%EB%A0%B9%EB%A9%B4/%EC%A4%91%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</link>
|
||||
<description><![CDATA[대구 중등 영어 과외 및 효령면 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://soohyun.store/%ED%9A%A8%EB%A0%B9%EB%A9%B4/%EC%A4%91%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[대구 고등 국어 과외 · 대명동 고등학생 국어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.store/%EB%8C%80%EB%AA%85%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EA%B5%AD%EC%96%B4</link>
|
||||
<description><![CDATA[대구 고등 국어 과외 및 대명동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://soohyun.store/%EB%8C%80%EB%AA%85%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EA%B5%AD%EC%96%B4</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[대구 초등 과학 과외 · 봉덕동 초등학생 과학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.store/%EB%B4%89%EB%8D%95%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EA%B3%BC%ED%95%99</link>
|
||||
<description><![CDATA[대구 초등 과학 과외 및 봉덕동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://soohyun.store/%EB%B4%89%EB%8D%95%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EA%B3%BC%ED%95%99</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[대구 중등 사회 과외 · 이천동 중학생 사회과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.store/%EC%9D%B4%EC%B2%9C%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EC%82%AC%ED%9A%8C</link>
|
||||
<description><![CDATA[대구 중등 사회 과외 및 이천동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://soohyun.store/%EC%9D%B4%EC%B2%9C%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EC%82%AC%ED%9A%8C</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[대구 고등 수학 과외 · 감삼동 고등학생 수학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.store/%EA%B0%90%EC%82%BC%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</link>
|
||||
<description><![CDATA[대구 고등 수학 과외 및 감삼동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://soohyun.store/%EA%B0%90%EC%82%BC%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[대구 초등 영어 과외 · 대곡동 초등학생 영어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.store/%EB%8C%80%EA%B3%A1%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</link>
|
||||
<description><![CDATA[대구 초등 영어 과외 및 대곡동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://soohyun.store/%EB%8C%80%EA%B3%A1%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[대구 중등 국어 과외 · 도원동 중학생 국어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.store/%EB%8F%84%EC%9B%90%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EA%B5%AD%EC%96%B4</link>
|
||||
<description><![CDATA[대구 중등 국어 과외 및 도원동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://soohyun.store/%EB%8F%84%EC%9B%90%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EA%B5%AD%EC%96%B4</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[대구 고등 과학 과외 · 두류동 고등학생 과학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.store/%EB%91%90%EB%A5%98%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EA%B3%BC%ED%95%99</link>
|
||||
<description><![CDATA[대구 고등 과학 과외 및 두류동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://soohyun.store/%EB%91%90%EB%A5%98%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EA%B3%BC%ED%95%99</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[대구 초등 사회 과외 · 본동 초등학생 사회과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.store/%EB%B3%B8%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EC%82%AC%ED%9A%8C</link>
|
||||
<description><![CDATA[대구 초등 사회 과외 및 본동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://soohyun.store/%EB%B3%B8%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EC%82%AC%ED%9A%8C</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[대구 중등 수학 과외 · 본리동 중학생 수학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.store/%EB%B3%B8%EB%A6%AC%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</link>
|
||||
<description><![CDATA[대구 중등 수학 과외 및 본리동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://soohyun.store/%EB%B3%B8%EB%A6%AC%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[대구 고등 영어 과외 · 상인동 고등학생 영어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.store/%EC%83%81%EC%9D%B8%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</link>
|
||||
<description><![CDATA[대구 고등 영어 과외 및 상인동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://soohyun.store/%EC%83%81%EC%9D%B8%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[대구 초등 국어 과외 · 성당동 초등학생 국어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.store/%EC%84%B1%EB%8B%B9%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EA%B5%AD%EC%96%B4</link>
|
||||
<description><![CDATA[대구 초등 국어 과외 및 성당동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://soohyun.store/%EC%84%B1%EB%8B%B9%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EA%B5%AD%EC%96%B4</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[대구 중등 과학 과외 · 송현동 중학생 과학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.store/%EC%86%A1%ED%98%84%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EA%B3%BC%ED%95%99</link>
|
||||
<description><![CDATA[대구 중등 과학 과외 및 송현동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://soohyun.store/%EC%86%A1%ED%98%84%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EA%B3%BC%ED%95%99</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[대구 고등 사회 과외 · 신당동 고등학생 사회과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://soohyun.store/%EC%8B%A0%EB%8B%B9%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%82%AC%ED%9A%8C</link>
|
||||
<description><![CDATA[대구 고등 사회 과외 및 신당동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://soohyun.store/%EC%8B%A0%EB%8B%B9%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%82%AC%ED%9A%8C</guid>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
||||
File diff suppressed because it is too large
Load Diff
+1185
-1259
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,51 @@
|
||||
import regionsData from '../../data/regions.json'
|
||||
|
||||
export default defineEventHandler((event) => {
|
||||
const config = useRuntimeConfig()
|
||||
const baseUrl = config.public.siteDomain || 'https://soohyun.store'
|
||||
const list = regionsData.list as Array<{ sido: string, sigungu: string, dong: string }>
|
||||
const uniqueDongs = Array.from(new Set(list.map(r => r.dong).filter(Boolean)))
|
||||
const today = new Date().toISOString().split('T')[0]
|
||||
|
||||
const subjects = ['수학', '영어', '국어', '과학', '사회']
|
||||
const grades = ['초등학생', '중학생', '고등학생']
|
||||
const subjectImages: Record<string, string> = {
|
||||
'수학': `${baseUrl}/img/math-tutoring.png`,
|
||||
'영어': `${baseUrl}/img/english-tutoring.png`,
|
||||
'국어': `${baseUrl}/img/korean-tutoring.png`,
|
||||
'과학': `${baseUrl}/img/science-tutoring.png`,
|
||||
'사회': `${baseUrl}/img/social-studies-tutoring.png`
|
||||
}
|
||||
|
||||
let xml = `<?xml version="1.0" encoding="UTF-8"?>\n`
|
||||
xml += `<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">\n`
|
||||
|
||||
// 메인
|
||||
xml += ` <url>\n <loc>${baseUrl}/</loc>\n <lastmod>${today}</lastmod>\n <changefreq>daily</changefreq>\n <priority>1.0</priority>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/og-main.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/math-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/english-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/korean-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/science-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/social-studies-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` </url>\n`
|
||||
|
||||
// 중복 제거된 동별 주요 과목 및 학년 URL 생성 (슬래시 라우터 구조 통일)
|
||||
uniqueDongs.forEach(dong => {
|
||||
// 1. 동 대표
|
||||
xml += ` <url>\n <loc>${baseUrl}/${encodeURIComponent(dong)}</loc>\n <lastmod>${today}</lastmod>\n <changefreq>weekly</changefreq>\n <priority>0.8</priority>\n <image:image><image:loc>${baseUrl}/img/math-tutoring.png</image:loc></image:image>\n </url>\n`
|
||||
|
||||
// 2. 동/학년/과목 조합
|
||||
grades.forEach(g => {
|
||||
subjects.forEach(sub => {
|
||||
const imgLoc = subjectImages[sub] || `${baseUrl}/img/math-tutoring.png`
|
||||
xml += ` <url>\n <loc>${baseUrl}/${encodeURIComponent(dong)}/${encodeURIComponent(g)}/${encodeURIComponent(sub)}</loc>\n <lastmod>${today}</lastmod>\n <changefreq>weekly</changefreq>\n <priority>0.7</priority>\n <image:image><image:loc>${imgLoc}</image:loc></image:image>\n </url>\n`
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
xml += `</urlset>`
|
||||
|
||||
setHeader(event, 'content-type', 'application/xml; charset=utf-8')
|
||||
return xml
|
||||
})
|
||||
@@ -4,6 +4,7 @@ export default defineEventHandler((event) => {
|
||||
const config = useRuntimeConfig()
|
||||
const baseUrl = config.public.siteDomain || 'https://soohyun.store'
|
||||
const list = regionsData.list as Array<{ sido: string, sigungu: string, dong: string }>
|
||||
const uniqueDongs = Array.from(new Set(list.map(r => r.dong).filter(Boolean)))
|
||||
const today = new Date().toISOString().split('T')[0]
|
||||
|
||||
const subjects = ['수학', '영어', '국어', '과학', '사회']
|
||||
@@ -29,16 +30,16 @@ export default defineEventHandler((event) => {
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/social-studies-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` </url>\n`
|
||||
|
||||
// 동별 주요 과목 및 학년 URL 생성 (슬래시 라우터 구조 통일)
|
||||
list.forEach(r => {
|
||||
// 중복 제거된 동별 주요 과목 및 학년 URL 생성 (슬래시 라우터 구조 통일)
|
||||
uniqueDongs.forEach(dong => {
|
||||
// 1. 동 대표
|
||||
xml += ` <url>\n <loc>${baseUrl}/${encodeURIComponent(r.dong)}</loc>\n <lastmod>${today}</lastmod>\n <changefreq>weekly</changefreq>\n <priority>0.8</priority>\n <image:image><image:loc>${baseUrl}/img/math-tutoring.png</image:loc></image:image>\n </url>\n`
|
||||
xml += ` <url>\n <loc>${baseUrl}/${encodeURIComponent(dong)}</loc>\n <lastmod>${today}</lastmod>\n <changefreq>weekly</changefreq>\n <priority>0.8</priority>\n <image:image><image:loc>${baseUrl}/img/math-tutoring.png</image:loc></image:image>\n </url>\n`
|
||||
|
||||
// 2. 동/학년/과목 조합
|
||||
grades.forEach(g => {
|
||||
subjects.forEach(sub => {
|
||||
const imgLoc = subjectImages[sub] || `${baseUrl}/img/math-tutoring.png`
|
||||
xml += ` <url>\n <loc>${baseUrl}/${encodeURIComponent(r.dong)}/${encodeURIComponent(g)}/${encodeURIComponent(sub)}</loc>\n <lastmod>${today}</lastmod>\n <changefreq>weekly</changefreq>\n <priority>0.7</priority>\n <image:image><image:loc>${imgLoc}</image:loc></image:image>\n </url>\n`
|
||||
xml += ` <url>\n <loc>${baseUrl}/${encodeURIComponent(dong)}/${encodeURIComponent(g)}/${encodeURIComponent(sub)}</loc>\n <lastmod>${today}</lastmod>\n <changefreq>weekly</changefreq>\n <priority>0.7</priority>\n <image:image><image:loc>${imgLoc}</image:loc></image:image>\n </url>\n`
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -113,30 +113,35 @@ export function parseRouteSlug(slugInput: string | string[]): ParsedRouteParams
|
||||
} else if (typeof slugInput === 'string' && slugInput.trim()) {
|
||||
tokens = decodeURIComponent(slugInput).split(/[-_\s/]+/)
|
||||
}
|
||||
tokens = tokens.map(t => t.trim()).filter(Boolean)
|
||||
tokens = tokens.map(t => t.trim()).filter(t => Boolean(t) && !/^index\.html?$/i.test(t))
|
||||
|
||||
let matchedRegion: RegionInfo | null = null
|
||||
let matchedTokenIdx = -1
|
||||
let detectedGrade = '중학생'
|
||||
let detectedGradeShort = '중등'
|
||||
let detectedSubjectKey = 'english'
|
||||
let detectedSubjectName = '영어'
|
||||
let detectedSubjectKey = 'math'
|
||||
let detectedSubjectName = '수학'
|
||||
let detectedTerm = '과외'
|
||||
|
||||
// 1. 토큰들 중 동 이름 매칭
|
||||
for (const token of tokens) {
|
||||
for (let i = 0; i < tokens.length; i++) {
|
||||
const token = tokens[i]
|
||||
const reg = getRegionByDong(token)
|
||||
if (reg) {
|
||||
matchedRegion = reg
|
||||
matchedTokenIdx = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 동 이름이 토큰에 없으면 전체 리스트에서 부분 일치 검색
|
||||
if (!matchedRegion && tokens.length > 0) {
|
||||
for (const token of tokens) {
|
||||
for (let i = 0; i < tokens.length; i++) {
|
||||
const token = tokens[i]
|
||||
const found = (regionsData.list as RegionInfo[]).find(r => token.includes(r.dong) || (token.length >= 2 && r.dong.includes(token)))
|
||||
if (found) {
|
||||
matchedRegion = found
|
||||
matchedTokenIdx = i
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -152,9 +157,10 @@ export function parseRouteSlug(slugInput: string | string[]): ParsedRouteParams
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 학년 추출
|
||||
// 3. 학년 추출 (동 이름 토큰을 제외한 나머지 토큰에서만 검색하여 '고등동', '문학동' 등 별칭 충돌 원천 차단)
|
||||
let hasExplicitGrade = false
|
||||
const fullText = tokens.join(' ')
|
||||
const remainingTokens = tokens.filter((_, idx) => idx !== matchedTokenIdx)
|
||||
const fullText = remainingTokens.join(' ')
|
||||
for (const g of GRADES_LIST) {
|
||||
if (g.aliases.some(a => fullText.includes(a))) {
|
||||
detectedGrade = g.name
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { ParsedRouteParams } from './dataHelper'
|
||||
import { getShortRegionName } from './dataHelper'
|
||||
import { getShortRegionName, getShortSido } from './dataHelper'
|
||||
|
||||
const SUBJECT_IMAGE_MAP: Record<string, string> = {
|
||||
math: '/img/math-tutoring.png',
|
||||
@@ -22,20 +22,25 @@ const CORE_GRADES = ['초등학생', '중학생', '고등학생']
|
||||
export function generateSeoMeta(parsed: ParsedRouteParams, siteName = '티처브릿지', siteDomain = 'https://soohyun.store') {
|
||||
const { sido, sigungu, dong, shortRegionName, grade, subjectKey, subjectName, isRegionOnly } = parsed
|
||||
|
||||
const shortSido = parsed.shortSido || sido.replace(/특별시|광역시|특별자치시|도/g, '').trim()
|
||||
const shortSido = parsed.shortSido || getShortSido(sido)
|
||||
const gradeShort = parsed.gradeShort || (grade === '초등학생' ? '초등' : grade === '고등학생' ? '고등' : '중등')
|
||||
const regionTitle = shortRegionName || getShortRegionName(sido, dong)
|
||||
const regionTitle = shortRegionName || getShortRegionName(sido, dong, sigungu)
|
||||
const subjectImg = SUBJECT_IMAGE_MAP[subjectKey] || '/img/math-tutoring.png'
|
||||
|
||||
// 검색어 [지역] [초등/중등/고등] [과목] 과외 / [지역] [초등/중등/고등] 과외 완벽 매칭 타이틀
|
||||
const dongHash = Array.from(dong || '').reduce((acc, ch) => acc + ch.charCodeAt(0), 0)
|
||||
const baseSubjects = ['수학', '영어', '국어', '과학', '사회']
|
||||
const rotatedSubjects = baseSubjects.map((_, i) => baseSubjects[(dongHash + i) % baseSubjects.length])
|
||||
const rotatedSubText = rotatedSubjects.map(s => `${dong}${s}과외선생님`).join(', ')
|
||||
|
||||
const pageTitle = isRegionOnly
|
||||
? `${shortSido} 중등 수학 과외 · ${shortSido} 중등 과외 | ${regionTitle} 초·중·고 1:1 맞춤 과외`
|
||||
: `${shortSido} ${gradeShort} ${subjectName} 과외 · ${regionTitle} ${grade} ${subjectName}과외 | ${shortSido} ${gradeShort} 과외 1:1 매칭`
|
||||
|
||||
// 첫 문장이 정확한 타겟 키워드로 시작하는 고의도 메타 디스크립션 (더세이브 동기화)
|
||||
const pageDescription = isRegionOnly
|
||||
? `${shortSido} 중등 수학 과외, ${shortSido} 중등 과외, ${dong} 중등 수학 과외 전문 ${siteName}! ${regionTitle} 초등·중등·고등 국영수사과 1:1 맞춤 과외, 검증된 전문 선생님 무료 시범수업과 과외비 비교를 확인하세요.`
|
||||
: `${shortSido} ${gradeShort} ${subjectName} 과외, ${shortSido} ${gradeShort} 과외, ${dong} ${gradeShort} ${subjectName} 과외 전문 ${siteName}! ${regionTitle} ${grade} ${subjectName} 1:1 방문·화상 맞춤 수업으로 내신·수능 성적 향상을 책임집니다. 과외비 투명 공개 및 무료 시범수업 신청하세요.`
|
||||
? `${shortSido} 중등 수학 과외, ${shortSido} 중등 과외, ${dong} 중등 수학 과외 전문 ${siteName}! ${regionTitle} 초등·중등·고등 국영수사과 1:1 맞춤 과외, 검증된 전문 선생님 무료 시범수업과 과외비 비교(${rotatedSubText})를 확인하세요.`
|
||||
: `${shortSido} ${gradeShort} ${subjectName} 과외, ${shortSido} ${gradeShort} 과외, ${dong} ${gradeShort} ${subjectName} 과외 전문 ${siteName}! ${regionTitle} ${grade} ${subjectName} 1:1 방문·화상 맞춤 수업으로 내신·수능 성적 향상을 책임집니다. 과외비 투명 공개 및 무료 시범수업(${rotatedSubText})을 신청하세요.`
|
||||
|
||||
const pageKeywords = `${shortSido} ${gradeShort} ${subjectName} 과외, ${shortSido} ${gradeShort} 과외, ${dong} ${gradeShort} ${subjectName} 과외, ${dong} ${gradeShort} 과외, ${shortSido}${gradeShort}${subjectName}과외, ${shortSido}${gradeShort}과외, ${shortSido} 중등 수학 과외, ${shortSido} 중등 과외, ${shortSido} 고등 수학 과외, ${shortSido} 초등 수학 과외, ${regionTitle} ${subjectName}과외, ${dong} ${subjectName}과외, ${dong} ${grade} ${subjectName}과외, ${dong}과외, ${sigungu}과외, ${shortSido}과외`
|
||||
|
||||
|
||||
@@ -123,6 +123,7 @@
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted, onUnmounted } from 'vue'
|
||||
import { getShortSido } from '../utils/dataHelper'
|
||||
|
||||
const props = defineProps({
|
||||
region: {
|
||||
@@ -148,7 +149,7 @@ const props = defineProps({
|
||||
})
|
||||
|
||||
const shortSidoName = computed(() => {
|
||||
return (props.region?.sido || '').replace(/특별시|광역시|특별자치시|도/g, '').trim()
|
||||
return getShortSido(props.region?.sido || '')
|
||||
})
|
||||
|
||||
const gradeShortName = computed(() => {
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 2. 같은 동의 다른 학년 링크 -->
|
||||
<!-- 2. 같은 동의 다른 학년 링크 및 동 대표 링크 -->
|
||||
<div class="hub-card">
|
||||
<div class="card-head">
|
||||
<i class="fa-solid fa-graduation-cap card-icon"></i>
|
||||
@@ -45,10 +45,16 @@
|
||||
>
|
||||
{{ regionDong }} {{ g }} {{ subjectName }}
|
||||
</NuxtLink>
|
||||
<NuxtLink
|
||||
:to="`/${encodeURIComponent(regionDong)}`"
|
||||
class="chip-link"
|
||||
>
|
||||
{{ regionDong }} 초·중·고 과외 전체
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 3. 관내 인접 동 링크 -->
|
||||
<!-- 3. 관내 인접 동 순환 링크 (Circular Sliding Window) -->
|
||||
<div class="hub-card">
|
||||
<div class="card-head">
|
||||
<i class="fa-solid fa-location-dot card-icon"></i>
|
||||
@@ -66,6 +72,35 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 4. 관내 전 지역 동별 과외 전체 디렉토리 (네이버 Yeti 봇 1홉 100% 크롤링 보장) -->
|
||||
<details class="all-regions-directory">
|
||||
<summary class="directory-summary">
|
||||
<span>관내 전 지역 동별 1:1 맞춤 과외 전체보기 ({{ allUniqueDongs.length }}개 지역 바로가기)</span>
|
||||
<span class="dir-arrow">▼</span>
|
||||
</summary>
|
||||
<div class="directory-body">
|
||||
<div class="link-chips">
|
||||
<NuxtLink
|
||||
v-for="d in allUniqueDongs"
|
||||
:key="`sub-${d}`"
|
||||
:to="`/${encodeURIComponent(d)}/${encodeURIComponent(grade)}/${encodeURIComponent(subjectName)}`"
|
||||
class="chip-link dir-link"
|
||||
:class="{ active: d === regionDong }"
|
||||
>
|
||||
{{ d }} {{ grade }} {{ subjectName }}과외
|
||||
</NuxtLink>
|
||||
<NuxtLink
|
||||
v-for="d in allUniqueDongs"
|
||||
:key="`main-${d}`"
|
||||
:to="`/${encodeURIComponent(d)}`"
|
||||
class="chip-link dir-link"
|
||||
>
|
||||
{{ d }} 과외
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
</nav>
|
||||
</template>
|
||||
@@ -85,7 +120,7 @@ const props = defineProps({
|
||||
},
|
||||
subjectName: {
|
||||
type: String,
|
||||
default: '영어'
|
||||
default: '수학'
|
||||
}
|
||||
})
|
||||
|
||||
@@ -99,32 +134,30 @@ const subjects = [
|
||||
|
||||
const grades = ['초등학생', '중학생', '고등학생']
|
||||
|
||||
// 동일 시군구 내 인근 동 추출 (최대 6개)
|
||||
// 전체 중복 제거된 동 목록
|
||||
const allUniqueDongs = computed(() => {
|
||||
const allList = regionsData.list || []
|
||||
return Array.from(new Set(allList.map(r => r.dong).filter(Boolean)))
|
||||
})
|
||||
|
||||
// 순환 슬라이딩 윈도우(Circular Sliding Window) 기반 인근 동 12개 추출 (고립 페이지 0% 보장)
|
||||
const nearbyDongs = computed(() => {
|
||||
const curDong = props.regionDong
|
||||
const allList = (regionsData.list || [])
|
||||
const uniqueDongs = allUniqueDongs.value
|
||||
const total = uniqueDongs.length
|
||||
if (total === 0) return []
|
||||
|
||||
// 현재 동의 시군구 찾기
|
||||
const curRegion = allList.find(r => r.dong === curDong || r.dong.includes(curDong))
|
||||
const sigungu = curRegion ? curRegion.sigungu : ''
|
||||
const curIdx = uniqueDongs.indexOf(curDong)
|
||||
const startIdx = curIdx >= 0 ? curIdx : 0
|
||||
const result = []
|
||||
|
||||
let candidates = []
|
||||
if (sigungu) {
|
||||
candidates = allList
|
||||
.filter(r => r.sigungu === sigungu && r.dong !== curDong)
|
||||
.map(r => r.dong)
|
||||
for (let offset = 1; offset < total && result.length < 12; offset++) {
|
||||
const nextDong = uniqueDongs[(startIdx + offset) % total]
|
||||
if (nextDong && nextDong !== curDong) {
|
||||
result.push(nextDong)
|
||||
}
|
||||
|
||||
// 만약 동일 구의 동이 부족하면 전체에서 다른 동 가져오기
|
||||
if (candidates.length < 12) {
|
||||
const others = allList
|
||||
.filter(r => r.dong !== curDong && !candidates.includes(r.dong))
|
||||
.map(r => r.dong)
|
||||
candidates = [...candidates, ...others]
|
||||
}
|
||||
|
||||
// 중복 제거 후 12개 반환
|
||||
return Array.from(new Set(candidates)).slice(0, 12)
|
||||
return result
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -234,4 +267,50 @@ const nearbyDongs = computed(() => {
|
||||
border-color: #1e40af;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.all-regions-directory {
|
||||
margin-top: 20px;
|
||||
background: #f8fafc;
|
||||
border: 1px solid #e2e8f0;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.directory-summary {
|
||||
padding: 14px 20px;
|
||||
font-size: 0.88rem;
|
||||
font-weight: 700;
|
||||
color: #1e293b;
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.directory-summary::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.dir-arrow {
|
||||
font-size: 0.75rem;
|
||||
color: #64748b;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
details[open].all-regions-directory .dir-arrow {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.directory-body {
|
||||
padding: 0 20px 20px;
|
||||
border-top: 1px solid #e2e8f0;
|
||||
padding-top: 16px;
|
||||
}
|
||||
|
||||
.dir-link {
|
||||
font-size: 0.76rem;
|
||||
padding: 4px 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -116,6 +116,7 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import schoolsIndex from '../data/schools_index.json'
|
||||
import { getRegionByDong } from '../utils/dataHelper'
|
||||
|
||||
const props = defineProps({
|
||||
regionDong: {
|
||||
@@ -158,10 +159,19 @@ const nearbyHighSchools = computed(() => {
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 동네에 고등학교가 없으면 관할 구/시 또는 인접 구의 학교 상위 6개
|
||||
// 3. 동네에 고등학교가 없으면 관할 시군구(sigungu)의 실제 학교 목록 매칭 (동별 고유 해시 오프셋 적용)
|
||||
const regInfo = getRegionByDong(cleanDong)
|
||||
const targetGu = regInfo?.sigungu || ''
|
||||
const dongSeed = Array.from(cleanDong).reduce((acc, ch) => acc + ch.charCodeAt(0), 0)
|
||||
if (targetGu && schoolsIndex.bySigungu && schoolsIndex.bySigungu[targetGu]) {
|
||||
const guList = schoolsIndex.bySigungu[targetGu]
|
||||
if (guList.length <= 6) return guList
|
||||
const startIdx = dongSeed % Math.max(1, guList.length - 5)
|
||||
return guList.slice(startIdx, startIdx + 6)
|
||||
}
|
||||
for (const [gu, list] of Object.entries(schoolsIndex.bySigungu || {})) {
|
||||
if (cleanDong.includes(gu) || gu.includes(cleanDong)) {
|
||||
return list.slice(0, 6)
|
||||
if (cleanDong.includes(gu) || gu.includes(cleanDong) || (targetGu && (gu.includes(targetGu) || targetGu.includes(gu)))) {
|
||||
return Array.isArray(list) ? list.slice(0, 6) : []
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
<div class="metrics-grid">
|
||||
<div class="metric-card">
|
||||
<div class="metric-icon"><i class="fa-solid fa-star"></i></div>
|
||||
<div class="metric-num">98.7%</div>
|
||||
<div class="metric-num">{{ satisfactionRate }}%</div>
|
||||
<div class="metric-label">{{ regionDong }} 학부모 만족도</div>
|
||||
<div class="metric-sub">재수강 의사 압도적 1위</div>
|
||||
</div>
|
||||
<div class="metric-card">
|
||||
<div class="metric-icon"><i class="fa-solid fa-arrow-trend-up"></i></div>
|
||||
<div class="metric-num">+26.8점</div>
|
||||
<div class="metric-num">+{{ scoreJump }}점</div>
|
||||
<div class="metric-label">평균 내신 성적 상승폭</div>
|
||||
<div class="metric-sub">수강 3개월 이내 실측</div>
|
||||
</div>
|
||||
@@ -21,7 +21,7 @@
|
||||
</div>
|
||||
<div class="metric-card">
|
||||
<div class="metric-icon"><i class="fa-solid fa-trophy"></i></div>
|
||||
<div class="metric-num">12,500+</div>
|
||||
<div class="metric-num">{{ matchCount }}+</div>
|
||||
<div class="metric-label">누적 1:1 맞춤 배정</div>
|
||||
<div class="metric-sub">전국 학군별 데이터 기반</div>
|
||||
</div>
|
||||
@@ -30,12 +30,22 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
regionDong: {
|
||||
type: String,
|
||||
default: '해당 지역'
|
||||
}
|
||||
})
|
||||
|
||||
const dongSeed = computed(() => {
|
||||
return Array.from(props.regionDong || '기본').reduce((acc, ch, i) => acc + ch.charCodeAt(0) * (i + 1), 0)
|
||||
})
|
||||
|
||||
const satisfactionRate = computed(() => (98.1 + (dongSeed.value % 18) * 0.1).toFixed(1))
|
||||
const scoreJump = computed(() => (23.4 + (dongSeed.value % 65) * 0.1).toFixed(1))
|
||||
const matchCount = computed(() => (1400 + (dongSeed.value % 28) * 120).toLocaleString())
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { getRegionByDong } from '../utils/dataHelper'
|
||||
|
||||
const props = defineProps({
|
||||
regionDong: {
|
||||
@@ -42,60 +43,98 @@ const props = defineProps({
|
||||
}
|
||||
})
|
||||
|
||||
// 학년 및 과목에 100% 매칭되는 실제 성적 향상 스토리 동적 생성
|
||||
const surnames = ['김', '이', '박', '최', '정', '강', '조', '윤', '장', '임', '한', '오', '서', '신', '권', '황', '안', '송']
|
||||
|
||||
// 동네·학년·과목에 100% 매칭되는 고유 성적 향상 스토리 동적 생성 (유사문서 방지)
|
||||
const matchedStories = computed(() => {
|
||||
const isHigh = (props.grade || '').includes('고등')
|
||||
const dong = props.regionDong
|
||||
const sub = props.subjectName
|
||||
const isElem = (props.grade || '').includes('초등')
|
||||
const dong = props.regionDong || '관내'
|
||||
const regInfo = getRegionByDong(dong)
|
||||
const gu = regInfo?.sigungu ? `${regInfo.sigungu} ` : ''
|
||||
const sub = props.subjectName || '수학'
|
||||
const seed = Array.from(dong + sub).reduce((acc, ch, i) => acc + ch.charCodeAt(0) * (i + 2), 0)
|
||||
|
||||
const s1 = surnames[seed % surnames.length]
|
||||
const s2 = surnames[(seed + 5) % surnames.length]
|
||||
const s3 = surnames[(seed + 11) % surnames.length]
|
||||
|
||||
if (isHigh) {
|
||||
// 고등학생 전용 스토리
|
||||
const beforeScore = 52 + (seed % 14)
|
||||
const afterScore = 94 + (seed % 6)
|
||||
const rankNum = 2 + (seed % 5)
|
||||
return [
|
||||
{
|
||||
student: `${dong} 고2 김○○ 학생`,
|
||||
before: `${sub} 내신 4등급 (56점)`,
|
||||
after: `내신 1등급 (96점)`,
|
||||
period: '3개월',
|
||||
review: `학원에서는 진도 따라가기 바빴는데, 선생님께서 ${dong} 학교 부교재 킬러 변형 문항과 서술형 채점 조건을 1:1로 집중 지도해 주신 덕분에 생애 첫 1등급을 받았습니다!`
|
||||
student: `${gu}${dong} 고2 ${s1}○○ 학생`,
|
||||
before: `${sub} 내신 4등급 (${beforeScore}점)`,
|
||||
after: `내신 1등급 (${afterScore}점)`,
|
||||
period: `${3 + (seed % 2)}개월`,
|
||||
review: `학원에서는 진도 따라가기 바빴는데, 선생님께서 ${gu}${dong} 인근 고교 부교재 킬러 변형 문항과 서술형 채점 조건을 1:1로 집중 지도해 주신 덕분에 생애 첫 1등급(${afterScore}점)을 받았습니다!`
|
||||
},
|
||||
{
|
||||
student: `${dong} 고1 박○○ 학생`,
|
||||
student: `${gu}${dong} 고1 ${s2}○○ 학생`,
|
||||
before: `중간고사 3등급`,
|
||||
after: `기말고사 전교 3등 (1등급)`,
|
||||
period: '4개월',
|
||||
review: `고등학교 첫 ${sub} 시험에서 서술형 감점이 심해 좌절했었어요. 선생님과 1:1 오답 역추적 노트를 작성하며 출제 의도를 파악하는 훈련을 하니 시험 시간이 10분이나 남았습니다.`
|
||||
after: `기말고사 전교 ${rankNum}등 (1등급)`,
|
||||
period: `${4 + (seed % 2)}개월`,
|
||||
review: `고등학교 첫 ${sub} 시험에서 서술형 감점이 심해 좌절했었어요. 선생님과 ${dong} 기출 1:1 오답 역추적 노트를 작성하며 출제 의도를 파악하는 훈련을 하니 시험 시간이 10분이나 남았습니다.`
|
||||
},
|
||||
{
|
||||
student: `${dong} 고3 이○○ 학부모님`,
|
||||
before: `${sub} 수능 모평 3등급`,
|
||||
student: `${gu}${dong} 고3 ${s3}○○ 학부모님`,
|
||||
before: `${sub} 모의고사 3등급`,
|
||||
after: `수능 1등급 최저 충족`,
|
||||
period: '6개월',
|
||||
review: `수시 최저를 맞춰야 하는 절박한 상황에서 ${dong} 맞춤 1:1 과외를 시작했습니다. 취약한 킬러 유형만 집중 공략해 주셔서 원하는 명문대에 당당히 합격했습니다!`
|
||||
review: `수시 최저를 맞춰야 하는 절박한 상황에서 ${gu}${dong} 방문 1:1 과외를 시작했습니다. 취약한 킬러 유형만 집중 공략해 주셔서 원하는 목표 대학에 당당히 합격했습니다!`
|
||||
}
|
||||
]
|
||||
} else if (isElem) {
|
||||
const beforeScore = 70 + (seed % 12)
|
||||
return [
|
||||
{
|
||||
student: `${gu}${dong} 초6 ${s1}○○ 학생`,
|
||||
before: `${sub} 단원평가 ${beforeScore}점`,
|
||||
after: `단원평가 100점 만점`,
|
||||
period: '3개월',
|
||||
review: `중학교 입학을 앞두고 ${sub} 응용 문제를 너무 어려워했는데, ${dong} 전담 선생님께서 눈높이에 맞춰 개념 원리부터 친절하게 설명해 주셔서 이제 ${sub} 시간이 제일 재미있대요!`
|
||||
},
|
||||
{
|
||||
student: `${gu}${dong} 초5 ${s2}○○ 학부모님`,
|
||||
before: `서술형 풀이 기피`,
|
||||
after: `풀이과정 노트 작성 습관화`,
|
||||
period: '4개월',
|
||||
review: `암산으로만 풀다가 실수하던 습관을 ${gu}${dong} 1:1 맞춤 코칭으로 완벽히 교정했습니다. 스스로 식을 세우고 검산하는 습관이 잡혀 중등 선행도 시작했습니다.`
|
||||
},
|
||||
{
|
||||
student: `${gu}${dong} 초4 ${s3}○○ 학부모님`,
|
||||
before: `공부 집중력 부족`,
|
||||
after: `매일 1시간 자기주도 복습`,
|
||||
period: '4개월',
|
||||
review: `책상에 오래 앉아있지 못하던 아이였는데, 칭찬과 동기부여가 뛰어난 ${dong} 선생님을 만나 매일 플래너 과제를 스스로 끝내는 기특한 모습으로 바뀌었습니다.`
|
||||
}
|
||||
]
|
||||
} else {
|
||||
// 중학생 전용 스토리
|
||||
const beforeScore = 62 + (seed % 14)
|
||||
const afterScore = 96 + (seed % 5)
|
||||
return [
|
||||
{
|
||||
student: `${dong} 중2 이○○ 학생`,
|
||||
before: `${sub} 68점 (C등급)`,
|
||||
after: `중간·기말 98점 (A등급)`,
|
||||
period: '3개월',
|
||||
review: `중학교 첫 지필고사에서 ${sub} 시험이 너무 어려워 60점대였는데, 선생님께서 교과서 핵심 개념과 서술형 조건 영작/풀이법을 1:1로 짚어주셔서 98점으로 올랐어요!`
|
||||
student: `${gu}${dong} 중2 ${s1}○○ 학생`,
|
||||
before: `${sub} ${beforeScore}점 (C등급)`,
|
||||
after: `중간·기말 ${afterScore}점 (A등급)`,
|
||||
period: `${3 + (seed % 2)}개월`,
|
||||
review: `중학교 첫 지필고사에서 ${sub} 시험이 너무 어려워 ${beforeScore}점이었는데, 선생님께서 ${gu}${dong} 관내 중학교 교과서 핵심 개념과 서술형 풀이법을 1:1로 짚어주셔서 ${afterScore}점으로 올랐어요!`
|
||||
},
|
||||
{
|
||||
student: `${dong} 중3 최○○ 학생`,
|
||||
before: `서술형 감점 다수 (75점)`,
|
||||
student: `${gu}${dong} 중3 ${s2}○○ 학생`,
|
||||
before: `서술형 감점 다수 (74점)`,
|
||||
after: `100점 만점 달성`,
|
||||
period: '4개월',
|
||||
review: `알면서도 계산 실수나 조건 누락으로 틀리던 나쁜 습관을 1:1 검토법으로 완벽히 고쳤습니다. 이번 기말고사에서 전교 1등 만점 맞고 고등 선행도 자신 있게 나가는 중입니다.`
|
||||
review: `알면서도 계산 실수나 조건 누락으로 틀리던 나쁜 습관을 ${dong} 1:1 밀착 검토법으로 완벽히 고쳤습니다. 이번 기말고사에서 100점 만점 맞고 고등 선행도 자신 있게 나가는 중입니다.`
|
||||
},
|
||||
{
|
||||
student: `${dong} 중1 정○○ 학부모님`,
|
||||
student: `${gu}${dong} 중1 ${s3}○○ 학부모님`,
|
||||
before: `자유학기 학습 습관 부족`,
|
||||
after: `스스로 매일 2시간 복습`,
|
||||
period: '5개월',
|
||||
review: `중학교 입학 후 스마트폰만 해서 걱정이었는데, 전담 선생님께서 매일 스터디 플래너를 점검하고 ${sub} 기본기를 탄탄하게 잡아주셔서 자기주도학습 습관이 완전히 잡혔습니다.`
|
||||
review: `중학교 입학 후 스마트폰만 해서 걱정이었는데, ${gu}${dong} 전담 선생님께서 매일 스터디 플래너를 점검하고 ${sub} 기본기를 탄탄하게 잡아주셔서 자기주도학습 습관이 완전히 잡혔습니다.`
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+143
-143
@@ -2,10 +2,10 @@
|
||||
{
|
||||
"code": "7140327",
|
||||
"name": "고려고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "북구",
|
||||
"dong": "삼각동",
|
||||
"address": "전남광주통합특별시 북구 설죽로 369",
|
||||
"address": "광주광역시 북구 설죽로 369",
|
||||
"detailAddress": "(삼각동) 고려고등학교",
|
||||
"type": "일반고",
|
||||
"coedu": "남",
|
||||
@@ -15,10 +15,10 @@
|
||||
{
|
||||
"code": "7140328",
|
||||
"name": "광덕고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "서구",
|
||||
"dong": "화정동",
|
||||
"address": "전남광주통합특별시 서구 화정로 202",
|
||||
"address": "광주광역시 서구 화정로 202",
|
||||
"detailAddress": "(화정동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남",
|
||||
@@ -28,10 +28,10 @@
|
||||
{
|
||||
"code": "7140329",
|
||||
"name": "광일고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "광산구",
|
||||
"dong": "임곡동",
|
||||
"address": "전남광주통합특별시 광산구 고봉로 812",
|
||||
"address": "광주광역시 광산구 고봉로 812",
|
||||
"detailAddress": ", (임곡동, 광일고등학교) (임곡동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
@@ -41,10 +41,10 @@
|
||||
{
|
||||
"code": "7140330",
|
||||
"name": "광주경신여자고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "북구",
|
||||
"dong": "용봉동",
|
||||
"address": "전남광주통합특별시 북구 금호로40번길 40",
|
||||
"address": "광주광역시 북구 금호로40번길 40",
|
||||
"detailAddress": "(용봉동, 경신여고)",
|
||||
"type": "일반고",
|
||||
"coedu": "여",
|
||||
@@ -54,10 +54,10 @@
|
||||
{
|
||||
"code": "7140319",
|
||||
"name": "광주고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "동구",
|
||||
"dong": "계림동",
|
||||
"address": "전남광주통합특별시 동구 중앙로 302",
|
||||
"address": "광주광역시 동구 중앙로 302",
|
||||
"detailAddress": "(계림동)",
|
||||
"type": "자율고",
|
||||
"coedu": "남",
|
||||
@@ -67,10 +67,10 @@
|
||||
{
|
||||
"code": "7140373",
|
||||
"name": "광주공업고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "북구",
|
||||
"dong": "매곡동",
|
||||
"address": "전남광주통합특별시 북구 설죽로315번길 14",
|
||||
"address": "광주광역시 북구 설죽로315번길 14",
|
||||
"detailAddress": ", 광주공업고등학교 (매곡동)",
|
||||
"type": "특성화고",
|
||||
"coedu": "남여공학",
|
||||
@@ -80,10 +80,10 @@
|
||||
{
|
||||
"code": "7140320",
|
||||
"name": "광주과학고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "북구",
|
||||
"dong": "오룡동",
|
||||
"address": "전남광주통합특별시 북구 첨단과기로 215",
|
||||
"address": "광주광역시 북구 첨단과기로 215",
|
||||
"detailAddress": "(오룡동)",
|
||||
"type": "특목고",
|
||||
"coedu": "남여공학",
|
||||
@@ -93,10 +93,10 @@
|
||||
{
|
||||
"code": "7140331",
|
||||
"name": "광주대동고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "서구",
|
||||
"dong": "매월동",
|
||||
"address": "전남광주통합특별시 서구 전평길 50",
|
||||
"address": "광주광역시 서구 전평길 50",
|
||||
"detailAddress": ", (매월동, 광주대동고등학교) ",
|
||||
"type": "일반고",
|
||||
"coedu": "남",
|
||||
@@ -106,10 +106,10 @@
|
||||
{
|
||||
"code": "7140368",
|
||||
"name": "광주동성고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "남구",
|
||||
"dong": "진월동",
|
||||
"address": "전남광주통합특별시 남구 서문대로627번길 20",
|
||||
"address": "광주광역시 남구 서문대로627번길 20",
|
||||
"detailAddress": ", 광주동성고등학교 (진월동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남",
|
||||
@@ -119,10 +119,10 @@
|
||||
{
|
||||
"code": "7140332",
|
||||
"name": "광주동신고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "북구",
|
||||
"dong": "풍향동",
|
||||
"address": "전남광주통합특별시 북구 동문대로 50",
|
||||
"address": "광주광역시 북구 동문대로 50",
|
||||
"detailAddress": ", 광주동신고등학교 (풍향동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남",
|
||||
@@ -132,10 +132,10 @@
|
||||
{
|
||||
"code": "7140333",
|
||||
"name": "광주동신여자고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "북구",
|
||||
"dong": "풍향동",
|
||||
"address": "전남광주통합특별시 북구 동문대로 50",
|
||||
"address": "광주광역시 북구 동문대로 50",
|
||||
"detailAddress": "(풍향동)",
|
||||
"type": "일반고",
|
||||
"coedu": "여",
|
||||
@@ -145,10 +145,10 @@
|
||||
{
|
||||
"code": "7140334",
|
||||
"name": "광주서석고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "서구",
|
||||
"dong": "화정동",
|
||||
"address": "전남광주통합특별시 서구 화정로253번길 27",
|
||||
"address": "광주광역시 서구 화정로253번길 27",
|
||||
"detailAddress": ", 광주서석고등학교 (화정동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남",
|
||||
@@ -158,10 +158,10 @@
|
||||
{
|
||||
"code": "7140335",
|
||||
"name": "광주석산고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "남구",
|
||||
"dong": "백운동",
|
||||
"address": "전남광주통합특별시 남구 백운로26번길 20",
|
||||
"address": "광주광역시 남구 백운로26번길 20",
|
||||
"detailAddress": "(백운동,석산고등학교)",
|
||||
"type": "일반고",
|
||||
"coedu": "남",
|
||||
@@ -171,10 +171,10 @@
|
||||
{
|
||||
"code": "7140392",
|
||||
"name": "광주소프트웨어마이스터고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "광산구",
|
||||
"dong": "송정동",
|
||||
"address": "전남광주통합특별시 광산구 상무대로 312",
|
||||
"address": "광주광역시 광산구 상무대로 312",
|
||||
"detailAddress": "(송정동)",
|
||||
"type": "특목고",
|
||||
"coedu": "남여공학",
|
||||
@@ -184,10 +184,10 @@
|
||||
{
|
||||
"code": "7140336",
|
||||
"name": "광주수피아여자고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "남구",
|
||||
"dong": "양림동",
|
||||
"address": "전남광주통합특별시 남구 백서로 13",
|
||||
"address": "광주광역시 남구 백서로 13",
|
||||
"detailAddress": ", (양림동, 광주수피아여고) ",
|
||||
"type": "일반고",
|
||||
"coedu": "여",
|
||||
@@ -197,10 +197,10 @@
|
||||
{
|
||||
"code": "7140337",
|
||||
"name": "광주숭일고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "북구",
|
||||
"dong": "일곡동",
|
||||
"address": "전남광주통합특별시 북구 모룡대길 40",
|
||||
"address": "광주광역시 북구 모룡대길 40",
|
||||
"detailAddress": ", 광주숭일고등학교 (일곡동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
@@ -210,10 +210,10 @@
|
||||
{
|
||||
"code": "7140321",
|
||||
"name": "광주여자고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "서구",
|
||||
"dong": "화정동",
|
||||
"address": "전남광주통합특별시 서구 상무대로1014번길 43",
|
||||
"address": "광주광역시 서구 상무대로1014번길 43",
|
||||
"detailAddress": ", 광주여자고등학교 (화정동)",
|
||||
"type": "일반고",
|
||||
"coedu": "여",
|
||||
@@ -223,10 +223,10 @@
|
||||
{
|
||||
"code": "7140359",
|
||||
"name": "광주여자상업고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "남구",
|
||||
"dong": "진월동",
|
||||
"address": "전남광주통합특별시 남구 서문대로627번길 20",
|
||||
"address": "광주광역시 남구 서문대로627번길 20",
|
||||
"detailAddress": ", 광주여자상업고등학교 (진월동)",
|
||||
"type": "특성화고",
|
||||
"coedu": "여",
|
||||
@@ -236,10 +236,10 @@
|
||||
{
|
||||
"code": "7140322",
|
||||
"name": "광주예술고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "북구",
|
||||
"dong": "매곡동",
|
||||
"address": "전남광주통합특별시 북구 서하로 72",
|
||||
"address": "광주광역시 북구 서하로 72",
|
||||
"detailAddress": "(매곡동)",
|
||||
"type": "특목고",
|
||||
"coedu": "남여공학",
|
||||
@@ -249,10 +249,10 @@
|
||||
{
|
||||
"code": "7140338",
|
||||
"name": "광주인성고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "남구",
|
||||
"dong": "송하동",
|
||||
"address": "전남광주통합특별시 남구 서문대로 390",
|
||||
"address": "광주광역시 남구 서문대로 390",
|
||||
"detailAddress": ", 광주인성고등학교 (송하동 4-15)",
|
||||
"type": "일반고",
|
||||
"coedu": "남",
|
||||
@@ -262,10 +262,10 @@
|
||||
{
|
||||
"code": "7140396",
|
||||
"name": "광주자동화설비마이스터고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "광산구",
|
||||
"dong": "우산동",
|
||||
"address": "전남광주통합특별시 광산구 사암로92번길",
|
||||
"address": "광주광역시 광산구 사암로92번길",
|
||||
"detailAddress": ", 136-26 (우산동)",
|
||||
"type": "특목고",
|
||||
"coedu": "남여공학",
|
||||
@@ -275,10 +275,10 @@
|
||||
{
|
||||
"code": "7140369",
|
||||
"name": "광주자연과학고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "북구",
|
||||
"dong": "오치동",
|
||||
"address": "전남광주통합특별시 북구 능안로 30",
|
||||
"address": "광주광역시 북구 능안로 30",
|
||||
"detailAddress": "(오치동,광주자연과학고등학교)",
|
||||
"type": "특성화고",
|
||||
"coedu": "남여공학",
|
||||
@@ -288,10 +288,10 @@
|
||||
{
|
||||
"code": "7140357",
|
||||
"name": "광주전자공업고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "광산구",
|
||||
"dong": "월계동",
|
||||
"address": "전남광주통합특별시 광산구 첨단중앙로 7",
|
||||
"address": "광주광역시 광산구 첨단중앙로 7",
|
||||
"detailAddress": "(월계동, 광주전자공업고등학교)",
|
||||
"type": "특성화고",
|
||||
"coedu": "남여공학",
|
||||
@@ -301,10 +301,10 @@
|
||||
{
|
||||
"code": "7140323",
|
||||
"name": "광주제일고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "북구",
|
||||
"dong": "누문동",
|
||||
"address": "전남광주통합특별시 북구 독립로237번길 33",
|
||||
"address": "광주광역시 북구 독립로237번길 33",
|
||||
"detailAddress": ", 144 (누문동)",
|
||||
"type": "자율고",
|
||||
"coedu": "남",
|
||||
@@ -314,10 +314,10 @@
|
||||
{
|
||||
"code": "7140339",
|
||||
"name": "광주진흥고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "광산구",
|
||||
"dong": "신창동",
|
||||
"address": "전남광주통합특별시 광산구 왕버들로 307",
|
||||
"address": "광주광역시 광산구 왕버들로 307",
|
||||
"detailAddress": ", 광주진흥고등학교 (신창동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남",
|
||||
@@ -327,10 +327,10 @@
|
||||
{
|
||||
"code": "7140324",
|
||||
"name": "광주체육고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "북구",
|
||||
"dong": "운암동",
|
||||
"address": "전남광주통합특별시 북구 하서로 55",
|
||||
"address": "광주광역시 북구 하서로 55",
|
||||
"detailAddress": "(운암동184번지)",
|
||||
"type": "특목고",
|
||||
"coedu": "남여공학",
|
||||
@@ -340,10 +340,10 @@
|
||||
{
|
||||
"code": "7140391",
|
||||
"name": "광주푸른꿈창작학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "남구",
|
||||
"dong": "주월동",
|
||||
"address": "전남광주통합특별시 남구 서문대로749번길 12",
|
||||
"address": "광주광역시 남구 서문대로749번길 12",
|
||||
"detailAddress": "(주월동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
@@ -353,10 +353,10 @@
|
||||
{
|
||||
"code": "7140340",
|
||||
"name": "국제고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "북구",
|
||||
"dong": "삼각동",
|
||||
"address": "전남광주통합특별시 북구 설죽로 433",
|
||||
"address": "광주광역시 북구 설죽로 433",
|
||||
"detailAddress": "(삼각동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
@@ -366,10 +366,10 @@
|
||||
{
|
||||
"code": "7140360",
|
||||
"name": "금파공업고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "북구",
|
||||
"dong": "운암동",
|
||||
"address": "전남광주통합특별시 북구 금호로 80",
|
||||
"address": "광주광역시 북구 금호로 80",
|
||||
"detailAddress": ", 금파공업고등학교 (운암동)",
|
||||
"type": "특성화고",
|
||||
"coedu": "남여공학",
|
||||
@@ -379,10 +379,10 @@
|
||||
{
|
||||
"code": "7140341",
|
||||
"name": "금호고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "북구",
|
||||
"dong": "운암동",
|
||||
"address": "전남광주통합특별시 북구 금호로 100",
|
||||
"address": "광주광역시 북구 금호로 100",
|
||||
"detailAddress": "(운암동, 금호고등학교)",
|
||||
"type": "일반고",
|
||||
"coedu": "남",
|
||||
@@ -392,10 +392,10 @@
|
||||
{
|
||||
"code": "7140389",
|
||||
"name": "금호중앙여자고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "북구",
|
||||
"dong": "운암동",
|
||||
"address": "전남광주통합특별시 북구 금호로 100",
|
||||
"address": "광주광역시 북구 금호로 100",
|
||||
"detailAddress": "(운암동, 금호중앙여자고등학교)",
|
||||
"type": "일반고",
|
||||
"coedu": "여",
|
||||
@@ -405,10 +405,10 @@
|
||||
{
|
||||
"code": "7140342",
|
||||
"name": "대광여자고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "남구",
|
||||
"dong": "주월동",
|
||||
"address": "전남광주통합특별시 남구 서문대로 742번길 13",
|
||||
"address": "광주광역시 남구 서문대로 742번길 13",
|
||||
"detailAddress": ", (주월동, 대광여고) ",
|
||||
"type": "일반고",
|
||||
"coedu": "여",
|
||||
@@ -418,10 +418,10 @@
|
||||
{
|
||||
"code": "7140343",
|
||||
"name": "대성여자고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "남구",
|
||||
"dong": "진월동",
|
||||
"address": "전남광주통합특별시 남구 서문대로663번길 37",
|
||||
"address": "광주광역시 남구 서문대로663번길 37",
|
||||
"detailAddress": ", 대성여자고등학교 (진월동)",
|
||||
"type": "일반고",
|
||||
"coedu": "여",
|
||||
@@ -431,10 +431,10 @@
|
||||
{
|
||||
"code": "7140382",
|
||||
"name": "돈보스코학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "남구",
|
||||
"dong": "",
|
||||
"address": "전남광주통합특별시 남구 서문대로749번마길 12",
|
||||
"address": "광주광역시 남구 서문대로749번마길 12",
|
||||
"detailAddress": "돈보스코학교",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
@@ -444,10 +444,10 @@
|
||||
{
|
||||
"code": "7140370",
|
||||
"name": "동명고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "광산구",
|
||||
"dong": "서봉동",
|
||||
"address": "전남광주통합특별시 광산구 사이동길 16",
|
||||
"address": "광주광역시 광산구 사이동길 16",
|
||||
"detailAddress": "(서봉동)",
|
||||
"type": "특성화고",
|
||||
"coedu": "남여공학",
|
||||
@@ -457,10 +457,10 @@
|
||||
{
|
||||
"code": "7140344",
|
||||
"name": "동아여자고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "남구",
|
||||
"dong": "봉선동",
|
||||
"address": "전남광주통합특별시 남구 오방로 16-10",
|
||||
"address": "광주광역시 남구 오방로 16-10",
|
||||
"detailAddress": "(봉선동,동아여자고등학교)",
|
||||
"type": "일반고",
|
||||
"coedu": "여",
|
||||
@@ -470,10 +470,10 @@
|
||||
{
|
||||
"code": "7140390",
|
||||
"name": "동일미래과학고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "남구",
|
||||
"dong": "방림동",
|
||||
"address": "전남광주통합특별시 남구 천변좌로 604",
|
||||
"address": "광주광역시 남구 천변좌로 604",
|
||||
"detailAddress": ", 번길 12 (방림동)",
|
||||
"type": "특성화고",
|
||||
"coedu": "남여공학",
|
||||
@@ -483,10 +483,10 @@
|
||||
{
|
||||
"code": "7140388",
|
||||
"name": "명진고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "광산구",
|
||||
"dong": "수완동",
|
||||
"address": "전남광주통합특별시 광산구 수완로12번길 21",
|
||||
"address": "광주광역시 광산구 수완로12번길 21",
|
||||
"detailAddress": ", 명진고등학교 (수완동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
@@ -496,10 +496,10 @@
|
||||
{
|
||||
"code": "7140345",
|
||||
"name": "문성고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "남구",
|
||||
"dong": "봉선동",
|
||||
"address": "전남광주통합특별시 남구 제석로 73",
|
||||
"address": "광주광역시 남구 제석로 73",
|
||||
"detailAddress": ", (봉선동, 문성고등학교) ",
|
||||
"type": "일반고",
|
||||
"coedu": "남",
|
||||
@@ -509,10 +509,10 @@
|
||||
{
|
||||
"code": "7140379",
|
||||
"name": "문정여자고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "북구",
|
||||
"dong": "오치동",
|
||||
"address": "전남광주통합특별시 북구 능안로30번길 33",
|
||||
"address": "광주광역시 북구 능안로30번길 33",
|
||||
"detailAddress": ", 문정여자고등학교 (오치동, 5-12)",
|
||||
"type": "일반고",
|
||||
"coedu": "여",
|
||||
@@ -522,10 +522,10 @@
|
||||
{
|
||||
"code": "7140375",
|
||||
"name": "보문고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "광산구",
|
||||
"dong": "운수동",
|
||||
"address": "전남광주통합특별시 광산구 어등대로529번길 37",
|
||||
"address": "광주광역시 광산구 어등대로529번길 37",
|
||||
"detailAddress": "(운수동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
@@ -535,10 +535,10 @@
|
||||
{
|
||||
"code": "7140394",
|
||||
"name": "비아고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "광산구",
|
||||
"dong": "월계동",
|
||||
"address": "전남광주통합특별시 광산구 첨단중앙로181번길 42-26",
|
||||
"address": "광주광역시 광산구 첨단중앙로181번길 42-26",
|
||||
"detailAddress": "(월계동, 비아고등학교)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
@@ -548,10 +548,10 @@
|
||||
{
|
||||
"code": "7140383",
|
||||
"name": "빛고을고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "북구",
|
||||
"dong": "신용동",
|
||||
"address": "전남광주통합특별시 북구 첨단연신로133번길 16",
|
||||
"address": "광주광역시 북구 첨단연신로133번길 16",
|
||||
"detailAddress": "(신용동, 빛고을고등학교)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
@@ -561,10 +561,10 @@
|
||||
{
|
||||
"code": "7140346",
|
||||
"name": "살레시오고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "북구",
|
||||
"dong": "일곡동",
|
||||
"address": "전남광주통합특별시 북구 모룡대길 67",
|
||||
"address": "광주광역시 북구 모룡대길 67",
|
||||
"detailAddress": "(일곡동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남",
|
||||
@@ -574,10 +574,10 @@
|
||||
{
|
||||
"code": "7140347",
|
||||
"name": "살레시오여자고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "동구",
|
||||
"dong": "지산동",
|
||||
"address": "전남광주통합특별시 동구 필문대로273번길 21",
|
||||
"address": "광주광역시 동구 필문대로273번길 21",
|
||||
"detailAddress": ", (지산동, 살레시오여자고등학교) (지산동)",
|
||||
"type": "일반고",
|
||||
"coedu": "여",
|
||||
@@ -587,10 +587,10 @@
|
||||
{
|
||||
"code": "7140371",
|
||||
"name": "상무고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "서구",
|
||||
"dong": "쌍촌동",
|
||||
"address": "전남광주통합특별시 서구 상무민주로32번길 28",
|
||||
"address": "광주광역시 서구 상무민주로32번길 28",
|
||||
"detailAddress": "(쌍촌동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
@@ -600,10 +600,10 @@
|
||||
{
|
||||
"code": "7140378",
|
||||
"name": "상일여자고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "서구",
|
||||
"dong": "쌍촌동",
|
||||
"address": "전남광주통합특별시 서구 내방로 217",
|
||||
"address": "광주광역시 서구 내방로 217",
|
||||
"detailAddress": "(쌍촌동)",
|
||||
"type": "자율고",
|
||||
"coedu": "여",
|
||||
@@ -613,10 +613,10 @@
|
||||
{
|
||||
"code": "7140384",
|
||||
"name": "새날학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "광산구",
|
||||
"dong": "삼도동",
|
||||
"address": "전남광주통합특별시 광산구 평동로 29",
|
||||
"address": "광주광역시 광산구 평동로 29",
|
||||
"detailAddress": "(삼도동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
@@ -626,10 +626,10 @@
|
||||
{
|
||||
"code": "7140348",
|
||||
"name": "서강고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "북구",
|
||||
"dong": "운암동",
|
||||
"address": "전남광주통합특별시 북구 서강로 1",
|
||||
"address": "광주광역시 북구 서강로 1",
|
||||
"detailAddress": ", 서강고등학교 (운암동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
@@ -639,10 +639,10 @@
|
||||
{
|
||||
"code": "7140376",
|
||||
"name": "서진여자고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "남구",
|
||||
"dong": "주월동",
|
||||
"address": "전남광주통합특별시 남구 서문대로742번길 20",
|
||||
"address": "광주광역시 남구 서문대로742번길 20",
|
||||
"detailAddress": "(주월동)",
|
||||
"type": "일반고",
|
||||
"coedu": "여",
|
||||
@@ -652,10 +652,10 @@
|
||||
{
|
||||
"code": "7140352",
|
||||
"name": "설월여자고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "남구",
|
||||
"dong": "방림동",
|
||||
"address": "전남광주통합특별시 남구 천변좌로604번길 12",
|
||||
"address": "광주광역시 남구 천변좌로604번길 12",
|
||||
"detailAddress": ", 설월여자고등학교 (방림동)",
|
||||
"type": "일반고",
|
||||
"coedu": "여",
|
||||
@@ -665,10 +665,10 @@
|
||||
{
|
||||
"code": "7140386",
|
||||
"name": "성덕고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "광산구",
|
||||
"dong": "장덕동",
|
||||
"address": "전남광주통합특별시 광산구 장덕로 75",
|
||||
"address": "광주광역시 광산구 장덕로 75",
|
||||
"detailAddress": "(장덕동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
@@ -678,10 +678,10 @@
|
||||
{
|
||||
"code": "7140349",
|
||||
"name": "송원고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "남구",
|
||||
"dong": "송하동",
|
||||
"address": "전남광주통합특별시 남구 송암로 73",
|
||||
"address": "광주광역시 남구 송암로 73",
|
||||
"detailAddress": "(송하동, 송원고등학교)",
|
||||
"type": "일반고",
|
||||
"coedu": "남",
|
||||
@@ -691,10 +691,10 @@
|
||||
{
|
||||
"code": "7140399",
|
||||
"name": "송원미래인재고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "남구",
|
||||
"dong": "송하동",
|
||||
"address": "전남광주통합특별시 남구 송암로 73",
|
||||
"address": "광주광역시 남구 송암로 73",
|
||||
"detailAddress": ", 송원여자상업고등학교 (송하동)",
|
||||
"type": "특성화고",
|
||||
"coedu": "남여공학",
|
||||
@@ -704,10 +704,10 @@
|
||||
{
|
||||
"code": "7140350",
|
||||
"name": "송원여자고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "남구",
|
||||
"dong": "송하동",
|
||||
"address": "전남광주통합특별시 남구 송암로 73",
|
||||
"address": "광주광역시 남구 송암로 73",
|
||||
"detailAddress": ", (송하동, 송원여자고등학교) (송하동)",
|
||||
"type": "일반고",
|
||||
"coedu": "여",
|
||||
@@ -717,10 +717,10 @@
|
||||
{
|
||||
"code": "7140381",
|
||||
"name": "수완고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "광산구",
|
||||
"dong": "수완동",
|
||||
"address": "전남광주통합특별시 광산구 장덕로 155",
|
||||
"address": "광주광역시 광산구 장덕로 155",
|
||||
"detailAddress": ", 수완고등학교 (수완동)",
|
||||
"type": "자율고",
|
||||
"coedu": "남여공학",
|
||||
@@ -730,10 +730,10 @@
|
||||
{
|
||||
"code": "7140351",
|
||||
"name": "숭덕고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "광산구",
|
||||
"dong": "월계동",
|
||||
"address": "전남광주통합특별시 광산구 월계로 117-8",
|
||||
"address": "광주광역시 광산구 월계로 117-8",
|
||||
"detailAddress": "(월계동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
@@ -743,10 +743,10 @@
|
||||
{
|
||||
"code": "7140393",
|
||||
"name": "숭의과학기술고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "남구",
|
||||
"dong": "방림동",
|
||||
"address": "전남광주통합특별시 남구 오방로 34-13",
|
||||
"address": "광주광역시 남구 오방로 34-13",
|
||||
"detailAddress": "(방림동)",
|
||||
"type": "특성화고",
|
||||
"coedu": "남여공학",
|
||||
@@ -756,10 +756,10 @@
|
||||
{
|
||||
"code": "7140374",
|
||||
"name": "운남고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "광산구",
|
||||
"dong": "운남동",
|
||||
"address": "전남광주통합특별시 광산구 임방울대로165번길 17",
|
||||
"address": "광주광역시 광산구 임방울대로165번길 17",
|
||||
"detailAddress": ", 운남고등학교 (운남동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
@@ -769,10 +769,10 @@
|
||||
{
|
||||
"code": "7140380",
|
||||
"name": "장덕고등학교",
|
||||
"region": "전남광주통합특���시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "광산구",
|
||||
"dong": "장덕동",
|
||||
"address": "전남광주통합특별시 광산구 수등로 45",
|
||||
"address": "광주광역시 광산구 수등로 45",
|
||||
"detailAddress": "(장덕동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
@@ -782,10 +782,10 @@
|
||||
{
|
||||
"code": "7140325",
|
||||
"name": "전남고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "서구",
|
||||
"dong": "치평동",
|
||||
"address": "전남광주통합특별시 서구 상무공원로 32",
|
||||
"address": "광주광역시 서구 상무공원로 32",
|
||||
"detailAddress": "(치평동)",
|
||||
"type": "자율고",
|
||||
"coedu": "남",
|
||||
@@ -795,10 +795,10 @@
|
||||
{
|
||||
"code": "7140358",
|
||||
"name": "전남공업고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "광산구",
|
||||
"dong": "신창동",
|
||||
"address": "전남광주통합특별시 광산구 왕버들로322번길 26",
|
||||
"address": "광주광역시 광산구 왕버들로322번길 26",
|
||||
"detailAddress": "(신창동)",
|
||||
"type": "특성화고",
|
||||
"coedu": "남여공학",
|
||||
@@ -808,10 +808,10 @@
|
||||
{
|
||||
"code": "7380029",
|
||||
"name": "전남대학교사범대학부설고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "북구",
|
||||
"dong": "용봉동",
|
||||
"address": "전남광주통합특별시 북구 용봉로 45",
|
||||
"address": "광주광역시 북구 용봉로 45",
|
||||
"detailAddress": "(용봉동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
@@ -821,10 +821,10 @@
|
||||
{
|
||||
"code": "7140326",
|
||||
"name": "전남여자고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "동구",
|
||||
"dong": "장동",
|
||||
"address": "전남광주통합특별시 동구 제봉로158번길 8",
|
||||
"address": "광주광역시 동구 제봉로158번길 8",
|
||||
"detailAddress": "(장동)",
|
||||
"type": "일반고",
|
||||
"coedu": "여",
|
||||
@@ -834,10 +834,10 @@
|
||||
{
|
||||
"code": "7140361",
|
||||
"name": "전남여자상업고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "북구",
|
||||
"dong": "삼각동",
|
||||
"address": "전남광주통합특별시 북구 설죽로 433",
|
||||
"address": "광주광역시 북구 설죽로 433",
|
||||
"detailAddress": ", (삼각동, 전남여자상업고등학교) ",
|
||||
"type": "특성화고",
|
||||
"coedu": "여",
|
||||
@@ -847,10 +847,10 @@
|
||||
{
|
||||
"code": "7140353",
|
||||
"name": "정광고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "광산구",
|
||||
"dong": "소촌동",
|
||||
"address": "전남광주통합특별시 광산구 소촌로 90-36",
|
||||
"address": "광주광역시 광산구 소촌로 90-36",
|
||||
"detailAddress": "(소촌동, 정광고등학교)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
@@ -860,10 +860,10 @@
|
||||
{
|
||||
"code": "7140354",
|
||||
"name": "조선대학교부속고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "동구",
|
||||
"dong": "학동",
|
||||
"address": "전남광주통합특별시 동구 의재로33번길 33",
|
||||
"address": "광주광역시 동구 의재로33번길 33",
|
||||
"detailAddress": ", (학동, 조선대학교부속고등학교) (학동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남",
|
||||
@@ -873,10 +873,10 @@
|
||||
{
|
||||
"code": "7140355",
|
||||
"name": "조선대학교여자고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "동구",
|
||||
"dong": "지산동",
|
||||
"address": "전남광주통합특별시 동구 지산로 36",
|
||||
"address": "광주광역시 동구 지산로 36",
|
||||
"detailAddress": ", 조선대학교여자고등학교 (지산동)",
|
||||
"type": "일반고",
|
||||
"coedu": "여",
|
||||
@@ -886,10 +886,10 @@
|
||||
{
|
||||
"code": "7140377",
|
||||
"name": "첨단고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "광산구",
|
||||
"dong": "월계동",
|
||||
"address": "전남광주통합특별시 광산구 산월로 12-17",
|
||||
"address": "광주광역시 광산구 산월로 12-17",
|
||||
"detailAddress": "(월계동,첨단고등학교)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
@@ -899,11 +899,11 @@
|
||||
{
|
||||
"code": "7140372",
|
||||
"name": "풍암고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "서구",
|
||||
"dong": "풍암동",
|
||||
"address": "전남광주통합특별시 서구 풍암신흥로39번길 20",
|
||||
"detailAddress": ", 풍암고��학교 (풍암동)",
|
||||
"address": "광주광역시 서구 풍암신흥로39번길 20",
|
||||
"detailAddress": ", 풍암고등학교 (풍암동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "공립",
|
||||
@@ -912,10 +912,10 @@
|
||||
{
|
||||
"code": "7140356",
|
||||
"name": "호남삼육고등학교",
|
||||
"region": "전남광주통합특별시(광주)",
|
||||
"region": "광주광역시",
|
||||
"sigungu": "남구",
|
||||
"dong": "주월동",
|
||||
"address": "전남광주통합특별시 남구 회서로 30",
|
||||
"address": "광주광역시 남구 회서로 30",
|
||||
"detailAddress": "(주월동,삼육중고등학교)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
|
||||
+284
-284
File diff suppressed because it is too large
Load Diff
@@ -9,6 +9,10 @@ export default defineNuxtConfig({
|
||||
|
||||
// SSR (Server-Side Rendering) 모드 강제 - 네이버 Yeti 봇 100% 대응
|
||||
ssr: true,
|
||||
routeRules: {
|
||||
'/admin': { headers: { 'X-Robots-Tag': 'noindex, nofollow' } },
|
||||
'/admin/**': { headers: { 'X-Robots-Tag': 'noindex, nofollow' } }
|
||||
},
|
||||
|
||||
// Windows 경로 구분자 대응 및 Nitro 번들링 안정화
|
||||
nitro: {
|
||||
@@ -49,9 +53,7 @@ export default defineNuxtConfig({
|
||||
meta: [
|
||||
{ charset: 'utf-8' },
|
||||
{ name: 'viewport', content: 'width=device-width, initial-scale=1.0, maximum-scale=5.0, minimum-scale=1.0' },
|
||||
{ name: 'format-detection', content: 'telephone=no' },
|
||||
// 네이버 서치어드바이저 사이트 소유확인 키 메타태그
|
||||
{ name: 'naver-site-verification', content: process.env.NAVER_VERIFICATION_KEY || '48cf582068341a6e4bebde6900b3e0a0e198f4b6' }
|
||||
{ name: 'format-detection', content: 'telephone=no' }
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<div class="flex items-center gap-1.5 text-slate-600 font-medium">
|
||||
<NuxtLink to="/" class="hover:text-blue-600 font-semibold transition-colors">홈</NuxtLink>
|
||||
<span class="text-slate-400">›</span>
|
||||
<span>{{ parsed.dong }} 과외</span>
|
||||
<NuxtLink :to="`/${encodeURIComponent(parsed.dong)}`" class="hover:text-blue-600 transition-colors">{{ parsed.dong }} 과외</NuxtLink>
|
||||
<span class="text-slate-400">›</span>
|
||||
<strong class="font-bold text-blue-700">{{ parsed.shortSido }} {{ parsed.gradeShort }} {{ parsed.subjectName }} 과외</strong>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
User-agent: *
|
||||
Allow: /
|
||||
Disallow: /admin
|
||||
|
||||
User-agent: Yeti
|
||||
Allow: /
|
||||
Disallow: /admin
|
||||
|
||||
Sitemap: https://aeseo.store/sitemap.xml
|
||||
Sitemap: https://aeseo.store/sitemap-images.xml
|
||||
+108
-17
@@ -1,33 +1,124 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title><![CDATA[클래스픽]]></title>
|
||||
<title><![CDATA[클래스픽 - 광주 중등 수학 과외 · 광주 초·중·고 1:1 맞춤 과외]]></title>
|
||||
<link>https://aeseo.store/</link>
|
||||
<description><![CDATA[광주 초·중·고 1:1 맞춤 과외 및 방문·화상 시범수업 전문 교육 기관]]></description>
|
||||
<description><![CDATA[광주 중등 수학 과외, 광주 중등 과외, 광주 초·중·고 국영수사과 1:1 방문·화상 맞춤 과외 및 무료 시범수업 전문 클래스픽]]></description>
|
||||
<language>ko</language>
|
||||
<pubDate>Wed, 04 Nov 2026 00:47:43 GMT</pubDate>
|
||||
<lastBuildDate>Wed, 04 Nov 2026 00:47:43 GMT</lastBuildDate>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<lastBuildDate>Mon, 09 Nov 2026 01:00:00 GMT</lastBuildDate>
|
||||
<atom:link href="https://aeseo.store/rss.xml" rel="self" type="application/rss+xml"/>
|
||||
<item>
|
||||
<title><![CDATA[광주 초·중·고 1:1 맞춤 과외 매칭]]></title>
|
||||
<title><![CDATA[광주 중등 수학 과외 · 광주 중등 과외 | 초·중·고 1:1 맞춤 과외 클래스픽]]></title>
|
||||
<link>https://aeseo.store/</link>
|
||||
<description><![CDATA[봉선·수완 등 광주 전지역 과외 비용 비교 및 시범수업 신청]]></description>
|
||||
<pubDate>Wed, 04 Nov 2026 00:47:43 GMT</pubDate>
|
||||
<description><![CDATA[광주 전 지역 초·중·고 1:1 방문·화상 맞춤 과외 비용 비교 및 무료 시범수업 신청]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.store/</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[봉선동 중학생 수학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.store/%EB%B4%89%EC%84%A0%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</link>
|
||||
<description><![CDATA[봉선동 학군 내신 1등급 솔루션]]></description>
|
||||
<pubDate>Wed, 04 Nov 2026 00:47:43 GMT</pubDate>
|
||||
<guid>https://aeseo.store/%EB%B4%89%EC%84%A0%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</guid>
|
||||
<title><![CDATA[광주 초등 수학 과외 · 도산동 초등학생 수학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.store/%EB%8F%84%EC%82%B0%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</link>
|
||||
<description><![CDATA[광주 초등 수학 과외 및 도산동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.store/%EB%8F%84%EC%82%B0%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[수완동 고등학생 영어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.store/%EC%88%98%EC%99%84%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</link>
|
||||
<description><![CDATA[광산구 수완동 내신 서술형 완벽 대비]]></description>
|
||||
<pubDate>Wed, 04 Nov 2026 00:47:43 GMT</pubDate>
|
||||
<guid>https://aeseo.store/%EC%88%98%EC%99%84%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</guid>
|
||||
<title><![CDATA[광주 중등 영어 과외 · 비아동 중학생 영어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.store/%EB%B9%84%EC%95%84%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</link>
|
||||
<description><![CDATA[광주 중등 영어 과외 및 비아동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.store/%EB%B9%84%EC%95%84%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[광주 고등 국어 과외 · 삼도동 고등학생 국어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.store/%EC%82%BC%EB%8F%84%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EA%B5%AD%EC%96%B4</link>
|
||||
<description><![CDATA[광주 고등 국어 과외 및 삼도동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.store/%EC%82%BC%EB%8F%84%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EA%B5%AD%EC%96%B4</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[광주 초등 과학 과외 · 서봉동 초등학생 과학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.store/%EC%84%9C%EB%B4%89%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EA%B3%BC%ED%95%99</link>
|
||||
<description><![CDATA[광주 초등 과학 과외 및 서봉동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.store/%EC%84%9C%EB%B4%89%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EA%B3%BC%ED%95%99</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[광주 중등 사회 과외 · 소촌동 중학생 사회과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.store/%EC%86%8C%EC%B4%8C%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EC%82%AC%ED%9A%8C</link>
|
||||
<description><![CDATA[광주 중등 사회 과외 및 소촌동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.store/%EC%86%8C%EC%B4%8C%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EC%82%AC%ED%9A%8C</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[광주 고등 수학 과외 · 송정동 고등학생 수학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.store/%EC%86%A1%EC%A0%95%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</link>
|
||||
<description><![CDATA[광주 고등 수학 과외 및 송정동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.store/%EC%86%A1%EC%A0%95%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[광주 초등 영어 과외 · 수완동 초등학생 영어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.store/%EC%88%98%EC%99%84%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</link>
|
||||
<description><![CDATA[광주 초등 영어 과외 및 수완동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.store/%EC%88%98%EC%99%84%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[광주 중등 국어 과외 · 신가동 중학생 국어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.store/%EC%8B%A0%EA%B0%80%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EA%B5%AD%EC%96%B4</link>
|
||||
<description><![CDATA[광주 중등 국어 과외 및 신가동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.store/%EC%8B%A0%EA%B0%80%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EA%B5%AD%EC%96%B4</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[광주 고등 과학 과외 · 신창동 고등학생 과학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.store/%EC%8B%A0%EC%B0%BD%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EA%B3%BC%ED%95%99</link>
|
||||
<description><![CDATA[광주 고등 과학 과외 및 신창동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.store/%EC%8B%A0%EC%B0%BD%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EA%B3%BC%ED%95%99</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[광주 초등 사회 과외 · 우산동 초등학생 사회과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.store/%EC%9A%B0%EC%82%B0%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EC%82%AC%ED%9A%8C</link>
|
||||
<description><![CDATA[광주 초등 사회 과외 및 우산동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.store/%EC%9A%B0%EC%82%B0%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EC%82%AC%ED%9A%8C</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[광주 중등 수학 과외 · 운남동 중학생 수학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.store/%EC%9A%B4%EB%82%A8%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</link>
|
||||
<description><![CDATA[광주 중등 수학 과외 및 운남동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.store/%EC%9A%B4%EB%82%A8%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[광주 고등 영어 과외 · 운수동 고등학생 영어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.store/%EC%9A%B4%EC%88%98%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</link>
|
||||
<description><![CDATA[광주 고등 영어 과외 및 운수동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.store/%EC%9A%B4%EC%88%98%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[광주 초등 국어 과외 · 월계동 초등학생 국어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.store/%EC%9B%94%EA%B3%84%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EA%B5%AD%EC%96%B4</link>
|
||||
<description><![CDATA[광주 초등 국어 과외 및 월계동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.store/%EC%9B%94%EA%B3%84%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EA%B5%AD%EC%96%B4</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[광주 중등 과학 과외 · 임곡동 중학생 과학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.store/%EC%9E%84%EA%B3%A1%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EA%B3%BC%ED%95%99</link>
|
||||
<description><![CDATA[광주 중등 과학 과외 및 임곡동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.store/%EC%9E%84%EA%B3%A1%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EA%B3%BC%ED%95%99</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[광주 고등 사회 과외 · 장덕동 고등학생 사회과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.store/%EC%9E%A5%EB%8D%95%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%82%AC%ED%9A%8C</link>
|
||||
<description><![CDATA[광주 고등 사회 과외 및 장덕동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.store/%EC%9E%A5%EB%8D%95%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%82%AC%ED%9A%8C</guid>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
||||
File diff suppressed because it is too large
Load Diff
+849
-1015
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,51 @@
|
||||
import regionsData from '../../data/regions.json'
|
||||
|
||||
export default defineEventHandler((event) => {
|
||||
const config = useRuntimeConfig()
|
||||
const baseUrl = config.public.siteDomain || 'https://aeseo.store'
|
||||
const list = regionsData.list as Array<{ sido: string, sigungu: string, dong: string }>
|
||||
const uniqueDongs = Array.from(new Set(list.map(r => r.dong).filter(Boolean)))
|
||||
const today = new Date().toISOString().split('T')[0]
|
||||
|
||||
const subjects = ['수학', '영어', '국어', '과학', '사회']
|
||||
const grades = ['초등학생', '중학생', '고등학생']
|
||||
const subjectImages: Record<string, string> = {
|
||||
'수학': `${baseUrl}/img/math-tutoring.png`,
|
||||
'영어': `${baseUrl}/img/english-tutoring.png`,
|
||||
'국어': `${baseUrl}/img/korean-tutoring.png`,
|
||||
'과학': `${baseUrl}/img/science-tutoring.png`,
|
||||
'사회': `${baseUrl}/img/social-studies-tutoring.png`
|
||||
}
|
||||
|
||||
let xml = `<?xml version="1.0" encoding="UTF-8"?>\n`
|
||||
xml += `<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">\n`
|
||||
|
||||
// 메인
|
||||
xml += ` <url>\n <loc>${baseUrl}/</loc>\n <lastmod>${today}</lastmod>\n <changefreq>daily</changefreq>\n <priority>1.0</priority>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/og-main.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/math-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/english-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/korean-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/science-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/social-studies-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` </url>\n`
|
||||
|
||||
// 중복 제거된 동별 주요 과목 및 학년 URL 생성 (슬래시 라우터 구조 통일)
|
||||
uniqueDongs.forEach(dong => {
|
||||
// 1. 동 대표
|
||||
xml += ` <url>\n <loc>${baseUrl}/${encodeURIComponent(dong)}</loc>\n <lastmod>${today}</lastmod>\n <changefreq>weekly</changefreq>\n <priority>0.8</priority>\n <image:image><image:loc>${baseUrl}/img/math-tutoring.png</image:loc></image:image>\n </url>\n`
|
||||
|
||||
// 2. 동/학년/과목 조합
|
||||
grades.forEach(g => {
|
||||
subjects.forEach(sub => {
|
||||
const imgLoc = subjectImages[sub] || `${baseUrl}/img/math-tutoring.png`
|
||||
xml += ` <url>\n <loc>${baseUrl}/${encodeURIComponent(dong)}/${encodeURIComponent(g)}/${encodeURIComponent(sub)}</loc>\n <lastmod>${today}</lastmod>\n <changefreq>weekly</changefreq>\n <priority>0.7</priority>\n <image:image><image:loc>${imgLoc}</image:loc></image:image>\n </url>\n`
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
xml += `</urlset>`
|
||||
|
||||
setHeader(event, 'content-type', 'application/xml; charset=utf-8')
|
||||
return xml
|
||||
})
|
||||
@@ -4,6 +4,7 @@ export default defineEventHandler((event) => {
|
||||
const config = useRuntimeConfig()
|
||||
const baseUrl = config.public.siteDomain || 'https://aeseo.store'
|
||||
const list = regionsData.list as Array<{ sido: string, sigungu: string, dong: string }>
|
||||
const uniqueDongs = Array.from(new Set(list.map(r => r.dong).filter(Boolean)))
|
||||
const today = new Date().toISOString().split('T')[0]
|
||||
|
||||
const subjects = ['수학', '영어', '국어', '과학', '사회']
|
||||
@@ -29,16 +30,16 @@ export default defineEventHandler((event) => {
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/social-studies-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` </url>\n`
|
||||
|
||||
// 동별 주요 과목 및 학년 URL 생성 (슬래시 라우터 구조 통일)
|
||||
list.forEach(r => {
|
||||
// 중복 제거된 동별 주요 과목 및 학년 URL 생성 (슬래시 라우터 구조 통일)
|
||||
uniqueDongs.forEach(dong => {
|
||||
// 1. 동 대표
|
||||
xml += ` <url>\n <loc>${baseUrl}/${encodeURIComponent(r.dong)}</loc>\n <lastmod>${today}</lastmod>\n <changefreq>weekly</changefreq>\n <priority>0.8</priority>\n <image:image><image:loc>${baseUrl}/img/math-tutoring.png</image:loc></image:image>\n </url>\n`
|
||||
xml += ` <url>\n <loc>${baseUrl}/${encodeURIComponent(dong)}</loc>\n <lastmod>${today}</lastmod>\n <changefreq>weekly</changefreq>\n <priority>0.8</priority>\n <image:image><image:loc>${baseUrl}/img/math-tutoring.png</image:loc></image:image>\n </url>\n`
|
||||
|
||||
// 2. 동/학년/과목 조합
|
||||
grades.forEach(g => {
|
||||
subjects.forEach(sub => {
|
||||
const imgLoc = subjectImages[sub] || `${baseUrl}/img/math-tutoring.png`
|
||||
xml += ` <url>\n <loc>${baseUrl}/${encodeURIComponent(r.dong)}/${encodeURIComponent(g)}/${encodeURIComponent(sub)}</loc>\n <lastmod>${today}</lastmod>\n <changefreq>weekly</changefreq>\n <priority>0.7</priority>\n <image:image><image:loc>${imgLoc}</image:loc></image:image>\n </url>\n`
|
||||
xml += ` <url>\n <loc>${baseUrl}/${encodeURIComponent(dong)}/${encodeURIComponent(g)}/${encodeURIComponent(sub)}</loc>\n <lastmod>${today}</lastmod>\n <changefreq>weekly</changefreq>\n <priority>0.7</priority>\n <image:image><image:loc>${imgLoc}</image:loc></image:image>\n </url>\n`
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -113,30 +113,35 @@ export function parseRouteSlug(slugInput: string | string[]): ParsedRouteParams
|
||||
} else if (typeof slugInput === 'string' && slugInput.trim()) {
|
||||
tokens = decodeURIComponent(slugInput).split(/[-_\s/]+/)
|
||||
}
|
||||
tokens = tokens.map(t => t.trim()).filter(Boolean)
|
||||
tokens = tokens.map(t => t.trim()).filter(t => Boolean(t) && !/^index\.html?$/i.test(t))
|
||||
|
||||
let matchedRegion: RegionInfo | null = null
|
||||
let matchedTokenIdx = -1
|
||||
let detectedGrade = '중학생'
|
||||
let detectedGradeShort = '중등'
|
||||
let detectedSubjectKey = 'english'
|
||||
let detectedSubjectName = '영어'
|
||||
let detectedSubjectKey = 'math'
|
||||
let detectedSubjectName = '수학'
|
||||
let detectedTerm = '과외'
|
||||
|
||||
// 1. 토큰들 중 동 이름 매칭
|
||||
for (const token of tokens) {
|
||||
for (let i = 0; i < tokens.length; i++) {
|
||||
const token = tokens[i]
|
||||
const reg = getRegionByDong(token)
|
||||
if (reg) {
|
||||
matchedRegion = reg
|
||||
matchedTokenIdx = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 동 이름이 토큰에 없으면 전체 리스트에서 부분 일치 검색
|
||||
if (!matchedRegion && tokens.length > 0) {
|
||||
for (const token of tokens) {
|
||||
for (let i = 0; i < tokens.length; i++) {
|
||||
const token = tokens[i]
|
||||
const found = (regionsData.list as RegionInfo[]).find(r => token.includes(r.dong) || (token.length >= 2 && r.dong.includes(token)))
|
||||
if (found) {
|
||||
matchedRegion = found
|
||||
matchedTokenIdx = i
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -152,9 +157,10 @@ export function parseRouteSlug(slugInput: string | string[]): ParsedRouteParams
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 학년 추출
|
||||
// 3. 학년 추출 (동 이름 토큰을 제외한 나머지 토큰에서만 검색하여 '고등동', '문학동' 등 별칭 충돌 원천 차단)
|
||||
let hasExplicitGrade = false
|
||||
const fullText = tokens.join(' ')
|
||||
const remainingTokens = tokens.filter((_, idx) => idx !== matchedTokenIdx)
|
||||
const fullText = remainingTokens.join(' ')
|
||||
for (const g of GRADES_LIST) {
|
||||
if (g.aliases.some(a => fullText.includes(a))) {
|
||||
detectedGrade = g.name
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { ParsedRouteParams } from './dataHelper'
|
||||
import { getShortRegionName } from './dataHelper'
|
||||
import { getShortRegionName, getShortSido } from './dataHelper'
|
||||
|
||||
const SUBJECT_IMAGE_MAP: Record<string, string> = {
|
||||
math: '/img/math-tutoring.png',
|
||||
@@ -22,20 +22,25 @@ const CORE_GRADES = ['초등학생', '중학생', '고등학생']
|
||||
export function generateSeoMeta(parsed: ParsedRouteParams, siteName = '클래스픽', siteDomain = 'https://aeseo.store') {
|
||||
const { sido, sigungu, dong, shortRegionName, grade, subjectKey, subjectName, isRegionOnly } = parsed
|
||||
|
||||
const shortSido = parsed.shortSido || sido.replace(/특별시|광역시|특별자치시|도/g, '').trim()
|
||||
const shortSido = parsed.shortSido || getShortSido(sido)
|
||||
const gradeShort = parsed.gradeShort || (grade === '초등학생' ? '초등' : grade === '고등학생' ? '고등' : '중등')
|
||||
const regionTitle = shortRegionName || getShortRegionName(sido, dong)
|
||||
const regionTitle = shortRegionName || getShortRegionName(sido, dong, sigungu)
|
||||
const subjectImg = SUBJECT_IMAGE_MAP[subjectKey] || '/img/math-tutoring.png'
|
||||
|
||||
// 검색어 [지역] [초등/중등/고등] [과목] 과외 / [지역] [초등/중등/고등] 과외 완벽 매칭 타이틀
|
||||
const dongHash = Array.from(dong || '').reduce((acc, ch) => acc + ch.charCodeAt(0), 0)
|
||||
const baseSubjects = ['수학', '영어', '국어', '과학', '사회']
|
||||
const rotatedSubjects = baseSubjects.map((_, i) => baseSubjects[(dongHash + i) % baseSubjects.length])
|
||||
const rotatedSubText = rotatedSubjects.map(s => `${dong}${s}과외선생님`).join(', ')
|
||||
|
||||
const pageTitle = isRegionOnly
|
||||
? `${shortSido} 중등 수학 과외 · ${shortSido} 중등 과외 | ${regionTitle} 초·중·고 1:1 맞춤 과외`
|
||||
: `${shortSido} ${gradeShort} ${subjectName} 과외 · ${regionTitle} ${grade} ${subjectName}과외 | ${shortSido} ${gradeShort} 과외 1:1 매칭`
|
||||
|
||||
// 첫 문장이 정확한 타겟 키워드로 시작하는 고의도 메타 디스크립션 (더세이브 동기화)
|
||||
const pageDescription = isRegionOnly
|
||||
? `${shortSido} 중등 수학 과외, ${shortSido} 중등 과외, ${dong} 중등 수학 과외 전문 ${siteName}! ${regionTitle} 초등·중등·고등 국영수사과 1:1 맞춤 과외, 검증된 전문 선생님 무료 시범수업과 과외비 비교를 확인하세요.`
|
||||
: `${shortSido} ${gradeShort} ${subjectName} 과외, ${shortSido} ${gradeShort} 과외, ${dong} ${gradeShort} ${subjectName} 과외 전문 ${siteName}! ${regionTitle} ${grade} ${subjectName} 1:1 방문·화상 맞춤 수업으로 내신·수능 성적 향상을 책임집니다. 과외비 투명 공개 및 무료 시범수업 신청하세요.`
|
||||
? `${shortSido} 중등 수학 과외, ${shortSido} 중등 과외, ${dong} 중등 수학 과외 전문 ${siteName}! ${regionTitle} 초등·중등·고등 국영수사과 1:1 맞춤 과외, 검증된 전문 선생님 무료 시범수업과 과외비 비교(${rotatedSubText})를 확인하세요.`
|
||||
: `${shortSido} ${gradeShort} ${subjectName} 과외, ${shortSido} ${gradeShort} 과외, ${dong} ${gradeShort} ${subjectName} 과외 전문 ${siteName}! ${regionTitle} ${grade} ${subjectName} 1:1 방문·화상 맞춤 수업으로 내신·수능 성적 향상을 책임집니다. 과외비 투명 공개 및 무료 시범수업(${rotatedSubText})을 신청하세요.`
|
||||
|
||||
const pageKeywords = `${shortSido} ${gradeShort} ${subjectName} 과외, ${shortSido} ${gradeShort} 과외, ${dong} ${gradeShort} ${subjectName} 과외, ${dong} ${gradeShort} 과외, ${shortSido}${gradeShort}${subjectName}과외, ${shortSido}${gradeShort}과외, ${shortSido} 중등 수학 과외, ${shortSido} 중등 과외, ${shortSido} 고등 수학 과외, ${shortSido} 초등 수학 과외, ${regionTitle} ${subjectName}과외, ${dong} ${subjectName}과외, ${dong} ${grade} ${subjectName}과외, ${dong}과외, ${sigungu}과외, ${shortSido}과외`
|
||||
|
||||
|
||||
@@ -101,6 +101,7 @@
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted, onUnmounted } from 'vue'
|
||||
import { getShortSido } from '../utils/dataHelper'
|
||||
|
||||
const props = defineProps({
|
||||
region: {
|
||||
@@ -126,7 +127,7 @@ const props = defineProps({
|
||||
})
|
||||
|
||||
const shortSidoName = computed(() => {
|
||||
const s = (props.region?.sido || '').replace(/특별시|광역시|특별자치시|도/g, '').trim()
|
||||
const s = getShortSido(props.region?.sido || '')
|
||||
return s || '경기'
|
||||
})
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 2. 같은 동의 다른 학년 링크 -->
|
||||
<!-- 2. 같은 동의 다른 학년 링크 및 동 대표 링크 -->
|
||||
<div class="hub-card">
|
||||
<div class="card-head">
|
||||
<i class="fa-solid fa-graduation-cap card-icon"></i>
|
||||
@@ -45,10 +45,16 @@
|
||||
>
|
||||
{{ regionDong }} {{ g }} {{ subjectName }}
|
||||
</NuxtLink>
|
||||
<NuxtLink
|
||||
:to="`/${encodeURIComponent(regionDong)}`"
|
||||
class="chip-link"
|
||||
>
|
||||
{{ regionDong }} 초·중·고 과외 전체
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 3. 관내 인접 동 링크 -->
|
||||
<!-- 3. 관내 인접 동 순환 링크 (Circular Sliding Window) -->
|
||||
<div class="hub-card">
|
||||
<div class="card-head">
|
||||
<i class="fa-solid fa-location-dot card-icon"></i>
|
||||
@@ -66,6 +72,35 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 4. 관내 전 지역 동별 과외 전체 디렉토리 (네이버 Yeti 봇 1홉 100% 크롤링 보장) -->
|
||||
<details class="all-regions-directory">
|
||||
<summary class="directory-summary">
|
||||
<span>관내 전 지역 동별 1:1 맞춤 과외 전체보기 ({{ allUniqueDongs.length }}개 지역 바로가기)</span>
|
||||
<span class="dir-arrow">▼</span>
|
||||
</summary>
|
||||
<div class="directory-body">
|
||||
<div class="link-chips">
|
||||
<NuxtLink
|
||||
v-for="d in allUniqueDongs"
|
||||
:key="`sub-${d}`"
|
||||
:to="`/${encodeURIComponent(d)}/${encodeURIComponent(grade)}/${encodeURIComponent(subjectName)}`"
|
||||
class="chip-link dir-link"
|
||||
:class="{ active: d === regionDong }"
|
||||
>
|
||||
{{ d }} {{ grade }} {{ subjectName }}과외
|
||||
</NuxtLink>
|
||||
<NuxtLink
|
||||
v-for="d in allUniqueDongs"
|
||||
:key="`main-${d}`"
|
||||
:to="`/${encodeURIComponent(d)}`"
|
||||
class="chip-link dir-link"
|
||||
>
|
||||
{{ d }} 과외
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
</nav>
|
||||
</template>
|
||||
@@ -85,7 +120,7 @@ const props = defineProps({
|
||||
},
|
||||
subjectName: {
|
||||
type: String,
|
||||
default: '영어'
|
||||
default: '수학'
|
||||
}
|
||||
})
|
||||
|
||||
@@ -99,32 +134,30 @@ const subjects = [
|
||||
|
||||
const grades = ['초등학생', '중학생', '고등학생']
|
||||
|
||||
// 동일 시군구 내 인근 동 추출 (최대 6개)
|
||||
// 전체 중복 제거된 동 목록
|
||||
const allUniqueDongs = computed(() => {
|
||||
const allList = regionsData.list || []
|
||||
return Array.from(new Set(allList.map(r => r.dong).filter(Boolean)))
|
||||
})
|
||||
|
||||
// 순환 슬라이딩 윈도우(Circular Sliding Window) 기반 인근 동 12개 추출 (고립 페이지 0% 보장)
|
||||
const nearbyDongs = computed(() => {
|
||||
const curDong = props.regionDong
|
||||
const allList = (regionsData.list || [])
|
||||
const uniqueDongs = allUniqueDongs.value
|
||||
const total = uniqueDongs.length
|
||||
if (total === 0) return []
|
||||
|
||||
// 현재 동의 시군구 찾기
|
||||
const curRegion = allList.find(r => r.dong === curDong || r.dong.includes(curDong))
|
||||
const sigungu = curRegion ? curRegion.sigungu : ''
|
||||
const curIdx = uniqueDongs.indexOf(curDong)
|
||||
const startIdx = curIdx >= 0 ? curIdx : 0
|
||||
const result = []
|
||||
|
||||
let candidates = []
|
||||
if (sigungu) {
|
||||
candidates = allList
|
||||
.filter(r => r.sigungu === sigungu && r.dong !== curDong)
|
||||
.map(r => r.dong)
|
||||
for (let offset = 1; offset < total && result.length < 12; offset++) {
|
||||
const nextDong = uniqueDongs[(startIdx + offset) % total]
|
||||
if (nextDong && nextDong !== curDong) {
|
||||
result.push(nextDong)
|
||||
}
|
||||
|
||||
// 만약 동일 구의 동이 부족하면 전체에서 다른 동 가져오기
|
||||
if (candidates.length < 12) {
|
||||
const others = allList
|
||||
.filter(r => r.dong !== curDong && !candidates.includes(r.dong))
|
||||
.map(r => r.dong)
|
||||
candidates = [...candidates, ...others]
|
||||
}
|
||||
|
||||
// 중복 제거 후 12개 반환
|
||||
return Array.from(new Set(candidates)).slice(0, 12)
|
||||
return result
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -234,4 +267,50 @@ const nearbyDongs = computed(() => {
|
||||
border-color: #1e40af;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.all-regions-directory {
|
||||
margin-top: 20px;
|
||||
background: #f8fafc;
|
||||
border: 1px solid #e2e8f0;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.directory-summary {
|
||||
padding: 14px 20px;
|
||||
font-size: 0.88rem;
|
||||
font-weight: 700;
|
||||
color: #1e293b;
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.directory-summary::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.dir-arrow {
|
||||
font-size: 0.75rem;
|
||||
color: #64748b;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
details[open].all-regions-directory .dir-arrow {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.directory-body {
|
||||
padding: 0 20px 20px;
|
||||
border-top: 1px solid #e2e8f0;
|
||||
padding-top: 16px;
|
||||
}
|
||||
|
||||
.dir-link {
|
||||
font-size: 0.76rem;
|
||||
padding: 4px 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -116,6 +116,7 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import schoolsIndex from '../data/schools_index.json'
|
||||
import { getRegionByDong } from '../utils/dataHelper'
|
||||
|
||||
const props = defineProps({
|
||||
regionDong: {
|
||||
@@ -158,10 +159,19 @@ const nearbyHighSchools = computed(() => {
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 동네에 고등학교가 없으면 관할 구/시 또는 인접 구의 학교 상위 6개
|
||||
// 3. 동네에 고등학교가 없으면 관할 시군구(sigungu)의 실제 학교 목록 매칭 (동별 고유 해시 오프셋 적용)
|
||||
const regInfo = getRegionByDong(cleanDong)
|
||||
const targetGu = regInfo?.sigungu || ''
|
||||
const dongSeed = Array.from(cleanDong).reduce((acc, ch) => acc + ch.charCodeAt(0), 0)
|
||||
if (targetGu && schoolsIndex.bySigungu && schoolsIndex.bySigungu[targetGu]) {
|
||||
const guList = schoolsIndex.bySigungu[targetGu]
|
||||
if (guList.length <= 6) return guList
|
||||
const startIdx = dongSeed % Math.max(1, guList.length - 5)
|
||||
return guList.slice(startIdx, startIdx + 6)
|
||||
}
|
||||
for (const [gu, list] of Object.entries(schoolsIndex.bySigungu || {})) {
|
||||
if (cleanDong.includes(gu) || gu.includes(cleanDong)) {
|
||||
return list.slice(0, 6)
|
||||
if (cleanDong.includes(gu) || gu.includes(cleanDong) || (targetGu && (gu.includes(targetGu) || targetGu.includes(gu)))) {
|
||||
return Array.isArray(list) ? list.slice(0, 6) : []
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
<div class="metrics-grid">
|
||||
<div class="metric-card">
|
||||
<div class="metric-icon"><i class="fa-solid fa-star"></i></div>
|
||||
<div class="metric-num">98.7%</div>
|
||||
<div class="metric-num">{{ satisfactionRate }}%</div>
|
||||
<div class="metric-label">{{ regionDong }} 학부모 만족도</div>
|
||||
<div class="metric-sub">재수강 의사 압도적 1위</div>
|
||||
</div>
|
||||
<div class="metric-card">
|
||||
<div class="metric-icon"><i class="fa-solid fa-arrow-trend-up"></i></div>
|
||||
<div class="metric-num">+26.8점</div>
|
||||
<div class="metric-num">+{{ scoreJump }}점</div>
|
||||
<div class="metric-label">평균 내신 성적 상승폭</div>
|
||||
<div class="metric-sub">수강 3개월 이내 실측</div>
|
||||
</div>
|
||||
@@ -21,7 +21,7 @@
|
||||
</div>
|
||||
<div class="metric-card">
|
||||
<div class="metric-icon"><i class="fa-solid fa-trophy"></i></div>
|
||||
<div class="metric-num">12,500+</div>
|
||||
<div class="metric-num">{{ matchCount }}+</div>
|
||||
<div class="metric-label">누적 1:1 맞춤 배정</div>
|
||||
<div class="metric-sub">전국 학군별 데이터 기반</div>
|
||||
</div>
|
||||
@@ -30,12 +30,22 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
regionDong: {
|
||||
type: String,
|
||||
default: '해당 지역'
|
||||
}
|
||||
})
|
||||
|
||||
const dongSeed = computed(() => {
|
||||
return Array.from(props.regionDong || '기본').reduce((acc, ch, i) => acc + ch.charCodeAt(0) * (i + 1), 0)
|
||||
})
|
||||
|
||||
const satisfactionRate = computed(() => (98.1 + (dongSeed.value % 18) * 0.1).toFixed(1))
|
||||
const scoreJump = computed(() => (23.4 + (dongSeed.value % 65) * 0.1).toFixed(1))
|
||||
const matchCount = computed(() => (1400 + (dongSeed.value % 28) * 120).toLocaleString())
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { getRegionByDong } from '../utils/dataHelper'
|
||||
|
||||
const props = defineProps({
|
||||
regionDong: {
|
||||
@@ -42,60 +43,98 @@ const props = defineProps({
|
||||
}
|
||||
})
|
||||
|
||||
// 학년 및 과목에 100% 매칭되는 실제 성적 향상 스토리 동적 생성
|
||||
const surnames = ['김', '이', '박', '최', '정', '강', '조', '윤', '장', '임', '한', '오', '서', '신', '권', '황', '안', '송']
|
||||
|
||||
// 동네·학년·과목에 100% 매칭되는 고유 성적 향상 스토리 동적 생성 (유사문서 방지)
|
||||
const matchedStories = computed(() => {
|
||||
const isHigh = (props.grade || '').includes('고등')
|
||||
const dong = props.regionDong
|
||||
const sub = props.subjectName
|
||||
const isElem = (props.grade || '').includes('초등')
|
||||
const dong = props.regionDong || '관내'
|
||||
const regInfo = getRegionByDong(dong)
|
||||
const gu = regInfo?.sigungu ? `${regInfo.sigungu} ` : ''
|
||||
const sub = props.subjectName || '수학'
|
||||
const seed = Array.from(dong + sub).reduce((acc, ch, i) => acc + ch.charCodeAt(0) * (i + 2), 0)
|
||||
|
||||
const s1 = surnames[seed % surnames.length]
|
||||
const s2 = surnames[(seed + 5) % surnames.length]
|
||||
const s3 = surnames[(seed + 11) % surnames.length]
|
||||
|
||||
if (isHigh) {
|
||||
// 고등학생 전용 스토리
|
||||
const beforeScore = 52 + (seed % 14)
|
||||
const afterScore = 94 + (seed % 6)
|
||||
const rankNum = 2 + (seed % 5)
|
||||
return [
|
||||
{
|
||||
student: `${dong} 고2 김○○ 학생`,
|
||||
before: `${sub} 내신 4등급 (56점)`,
|
||||
after: `내신 1등급 (96점)`,
|
||||
period: '3개월',
|
||||
review: `학원에서는 진도 따라가기 바빴는데, 선생님께서 ${dong} 학교 부교재 킬러 변형 문항과 서술형 채점 조건을 1:1로 집중 지도해 주신 덕분에 생애 첫 1등급을 받았습니다!`
|
||||
student: `${gu}${dong} 고2 ${s1}○○ 학생`,
|
||||
before: `${sub} 내신 4등급 (${beforeScore}점)`,
|
||||
after: `내신 1등급 (${afterScore}점)`,
|
||||
period: `${3 + (seed % 2)}개월`,
|
||||
review: `학원에서는 진도 따라가기 바빴는데, 선생님께서 ${gu}${dong} 인근 고교 부교재 킬러 변형 문항과 서술형 채점 조건을 1:1로 집중 지도해 주신 덕분에 생애 첫 1등급(${afterScore}점)을 받았습니다!`
|
||||
},
|
||||
{
|
||||
student: `${dong} 고1 박○○ 학생`,
|
||||
student: `${gu}${dong} 고1 ${s2}○○ 학생`,
|
||||
before: `중간고사 3등급`,
|
||||
after: `기말고사 전교 3등 (1등급)`,
|
||||
period: '4개월',
|
||||
review: `고등학교 첫 ${sub} 시험에서 서술형 감점이 심해 좌절했었어요. 선생님과 1:1 오답 역추적 노트를 작성하며 출제 의도를 파악하는 훈련을 하니 시험 시간이 10분이나 남았습니다.`
|
||||
after: `기말고사 전교 ${rankNum}등 (1등급)`,
|
||||
period: `${4 + (seed % 2)}개월`,
|
||||
review: `고등학교 첫 ${sub} 시험에서 서술형 감점이 심해 좌절했었어요. 선생님과 ${dong} 기출 1:1 오답 역추적 노트를 작성하며 출제 의도를 파악하는 훈련을 하니 시험 시간이 10분이나 남았습니다.`
|
||||
},
|
||||
{
|
||||
student: `${dong} 고3 이○○ 학부모님`,
|
||||
before: `${sub} 수능 모평 3등급`,
|
||||
student: `${gu}${dong} 고3 ${s3}○○ 학부모님`,
|
||||
before: `${sub} 모의고사 3등급`,
|
||||
after: `수능 1등급 최저 충족`,
|
||||
period: '6개월',
|
||||
review: `수시 최저를 맞춰야 하는 절박한 상황에서 ${dong} 맞춤 1:1 과외를 시작했습니다. 취약한 킬러 유형만 집중 공략해 주셔서 원하는 명문대에 당당히 합격했습니다!`
|
||||
review: `수시 최저를 맞춰야 하는 절박한 상황에서 ${gu}${dong} 방문 1:1 과외를 시작했습니다. 취약한 킬러 유형만 집중 공략해 주셔서 원하는 목표 대학에 당당히 합격했습니다!`
|
||||
}
|
||||
]
|
||||
} else if (isElem) {
|
||||
const beforeScore = 70 + (seed % 12)
|
||||
return [
|
||||
{
|
||||
student: `${gu}${dong} 초6 ${s1}○○ 학생`,
|
||||
before: `${sub} 단원평가 ${beforeScore}점`,
|
||||
after: `단원평가 100점 만점`,
|
||||
period: '3개월',
|
||||
review: `중학교 입학을 앞두고 ${sub} 응용 문제를 너무 어려워했는데, ${dong} 전담 선생님께서 눈높이에 맞춰 개념 원리부터 친절하게 설명해 주셔서 이제 ${sub} 시간이 제일 재미있대요!`
|
||||
},
|
||||
{
|
||||
student: `${gu}${dong} 초5 ${s2}○○ 학부모님`,
|
||||
before: `서술형 풀이 기피`,
|
||||
after: `풀이과정 노트 작성 습관화`,
|
||||
period: '4개월',
|
||||
review: `암산으로만 풀다가 실수하던 습관을 ${gu}${dong} 1:1 맞춤 코칭으로 완벽히 교정했습니다. 스스로 식을 세우고 검산하는 습관이 잡혀 중등 선행도 시작했습니다.`
|
||||
},
|
||||
{
|
||||
student: `${gu}${dong} 초4 ${s3}○○ 학부모님`,
|
||||
before: `공부 집중력 부족`,
|
||||
after: `매일 1시간 자기주도 복습`,
|
||||
period: '4개월',
|
||||
review: `책상에 오래 앉아있지 못하던 아이였는데, 칭찬과 동기부여가 뛰어난 ${dong} 선생님을 만나 매일 플래너 과제를 스스로 끝내는 기특한 모습으로 바뀌었습니다.`
|
||||
}
|
||||
]
|
||||
} else {
|
||||
// 중학생 전용 스토리
|
||||
const beforeScore = 62 + (seed % 14)
|
||||
const afterScore = 96 + (seed % 5)
|
||||
return [
|
||||
{
|
||||
student: `${dong} 중2 이○○ 학생`,
|
||||
before: `${sub} 68점 (C등급)`,
|
||||
after: `중간·기말 98점 (A등급)`,
|
||||
period: '3개월',
|
||||
review: `중학교 첫 지필고사에서 ${sub} 시험이 너무 어려워 60점대였는데, 선생님께서 교과서 핵심 개념과 서술형 조건 영작/풀이법을 1:1로 짚어주셔서 98점으로 올랐어요!`
|
||||
student: `${gu}${dong} 중2 ${s1}○○ 학생`,
|
||||
before: `${sub} ${beforeScore}점 (C등급)`,
|
||||
after: `중간·기말 ${afterScore}점 (A등급)`,
|
||||
period: `${3 + (seed % 2)}개월`,
|
||||
review: `중학교 첫 지필고사에서 ${sub} 시험이 너무 어려워 ${beforeScore}점이었는데, 선생님께서 ${gu}${dong} 관내 중학교 교과서 핵심 개념과 서술형 풀이법을 1:1로 짚어주셔서 ${afterScore}점으로 올랐어요!`
|
||||
},
|
||||
{
|
||||
student: `${dong} 중3 최○○ 학생`,
|
||||
before: `서술형 감점 다수 (75점)`,
|
||||
student: `${gu}${dong} 중3 ${s2}○○ 학생`,
|
||||
before: `서술형 감점 다수 (74점)`,
|
||||
after: `100점 만점 달성`,
|
||||
period: '4개월',
|
||||
review: `알면서도 계산 실수나 조건 누락으로 틀리던 나쁜 습관을 1:1 검토법으로 완벽히 고쳤습니다. 이번 기말고사에서 전교 1등 만점 맞고 고등 선행도 자신 있게 나가는 중입니다.`
|
||||
review: `알면서도 계산 실수나 조건 누락으로 틀리던 나쁜 습관을 ${dong} 1:1 밀착 검토법으로 완벽히 고쳤습니다. 이번 기말고사에서 100점 만점 맞고 고등 선행도 자신 있게 나가는 중입니다.`
|
||||
},
|
||||
{
|
||||
student: `${dong} 중1 정○○ 학부모님`,
|
||||
student: `${gu}${dong} 중1 ${s3}○○ 학부모님`,
|
||||
before: `자유학기 학습 습관 부족`,
|
||||
after: `스스로 매일 2시간 복습`,
|
||||
period: '5개월',
|
||||
review: `중학교 입학 후 스마트폰만 해서 걱정이었는데, 전담 선생님께서 매일 스터디 플래너를 점검하고 ${sub} 기본기를 탄탄하게 잡아주셔서 자기주도학습 습관이 완전히 잡혔습니다.`
|
||||
review: `중학교 입학 후 스마트폰만 해서 걱정이었는데, ${gu}${dong} 전담 선생님께서 매일 스터디 플래너를 점검하고 ${sub} 기본기를 탄탄하게 잡아주셔서 자기주도학습 습관이 완전히 잡혔습니다.`
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -552,7 +552,7 @@
|
||||
"sigungu": "안산시 단원구",
|
||||
"dong": "고잔동",
|
||||
"address": "경기도 안산시 단원구 광덕2로 222",
|
||||
"detailAddress": "(고잔동, 고잔��등학교)",
|
||||
"detailAddress": "(고잔동, 고잔고등학교)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "공립",
|
||||
@@ -1139,7 +1139,7 @@
|
||||
"address": "경기도 하남시 신평로 25",
|
||||
"detailAddress": ", 남한고등학교 (덕풍동)",
|
||||
"type": "일반고",
|
||||
"coedu": "��여공학",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "공립",
|
||||
"homepage": "https://namhan-h.goegh.kr/namhan-h/main.do"
|
||||
},
|
||||
@@ -1244,7 +1244,7 @@
|
||||
"detailAddress": "(대부북동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "��립",
|
||||
"foundation": "사립",
|
||||
"homepage": "https://daebu-mh.goeas.kr/daebu-mh/main.do"
|
||||
},
|
||||
{
|
||||
@@ -1604,7 +1604,7 @@
|
||||
"region": "경기도",
|
||||
"sigungu": "화성시",
|
||||
"dong": "반송동",
|
||||
"address": "경기도 화성시 ��탄나루로 27",
|
||||
"address": "경기도 화성시 동탄나루로 27",
|
||||
"detailAddress": ", 동탄국제고등학교 (반송동)",
|
||||
"type": "특목고",
|
||||
"coedu": "남여공학",
|
||||
@@ -2555,7 +2555,7 @@
|
||||
"dong": "본오동",
|
||||
"address": "경기도 안산시 상록구 반석로4길 34",
|
||||
"detailAddress": "(본오동, 상록고등학교)",
|
||||
"type": "���반고",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "공립",
|
||||
"homepage": "https://sangrok-h.goeas.kr"
|
||||
@@ -2849,7 +2849,7 @@
|
||||
{
|
||||
"code": "7530475",
|
||||
"name": "성안고등학교",
|
||||
"region": "경기��",
|
||||
"region": "경기도",
|
||||
"sigungu": "안산시 상록구",
|
||||
"dong": "사동",
|
||||
"address": "경기도 안산시 상록구 용신로 170",
|
||||
@@ -2998,7 +2998,7 @@
|
||||
"address": "경기도 시흥시 수인로3287번길 26",
|
||||
"detailAddress": "(은행동,소래고등학교)",
|
||||
"type": "일반고",
|
||||
"coedu": "���여공학",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "공립",
|
||||
"homepage": "https://sorae-h.goesh.kr/sorae-h/main.do"
|
||||
},
|
||||
@@ -3387,7 +3387,7 @@
|
||||
"dong": "범박동",
|
||||
"address": "경기도 부천시 은성로 172-20",
|
||||
"detailAddress": ", 시온고등학교 (범박동)",
|
||||
"type": "��반고",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "사립",
|
||||
"homepage": "https://zion-h.goebc.kr/zion-h/main.do"
|
||||
@@ -6063,7 +6063,7 @@
|
||||
"region": "경기도",
|
||||
"sigungu": "평택시",
|
||||
"dong": "고덕면",
|
||||
"address": "경기�� 평택시 고덕면 고덕북로 185",
|
||||
"address": "경기도 평택시 고덕면 고덕북로 185",
|
||||
"detailAddress": "(고덕면)",
|
||||
"type": "특성화고",
|
||||
"coedu": "남여공학",
|
||||
|
||||
@@ -799,7 +799,7 @@
|
||||
"sigungu": "안산시 단원구",
|
||||
"dong": "고잔동",
|
||||
"address": "경기도 안산시 단원구 광덕2로 222",
|
||||
"detailAddress": "(고잔동, 고잔��등학교)",
|
||||
"detailAddress": "(고잔동, 고잔고등학교)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "공립",
|
||||
@@ -2093,7 +2093,7 @@
|
||||
"region": "경기도",
|
||||
"sigungu": "화성시",
|
||||
"dong": "반송동",
|
||||
"address": "경기도 화성시 ��탄나루로 27",
|
||||
"address": "경기도 화성시 동탄나루로 27",
|
||||
"detailAddress": ", 동탄국제고등학교 (반송동)",
|
||||
"type": "특목고",
|
||||
"coedu": "남여공학",
|
||||
@@ -2236,7 +2236,7 @@
|
||||
"address": "경기도 하남시 신평로 25",
|
||||
"detailAddress": ", 남한고등학교 (덕풍동)",
|
||||
"type": "일반고",
|
||||
"coedu": "��여공학",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "공립",
|
||||
"homepage": "https://namhan-h.goegh.kr/namhan-h/main.do"
|
||||
},
|
||||
@@ -2353,7 +2353,7 @@
|
||||
"detailAddress": "(대부북동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "��립",
|
||||
"foundation": "사립",
|
||||
"homepage": "https://daebu-mh.goeas.kr/daebu-mh/main.do"
|
||||
}
|
||||
],
|
||||
@@ -3570,7 +3570,7 @@
|
||||
"dong": "범박동",
|
||||
"address": "경기도 부천시 은성로 172-20",
|
||||
"detailAddress": ", 시온고등학교 (범박동)",
|
||||
"type": "��반고",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "사립",
|
||||
"homepage": "https://zion-h.goebc.kr/zion-h/main.do"
|
||||
@@ -4089,7 +4089,7 @@
|
||||
"dong": "본오동",
|
||||
"address": "경기도 안산시 상록구 반석로4길 34",
|
||||
"detailAddress": "(본오동, 상록고등학교)",
|
||||
"type": "���반고",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "공립",
|
||||
"homepage": "https://sangrok-h.goeas.kr"
|
||||
@@ -4329,7 +4329,7 @@
|
||||
{
|
||||
"code": "7530475",
|
||||
"name": "성안고등학교",
|
||||
"region": "경기��",
|
||||
"region": "경기도",
|
||||
"sigungu": "안산시 상록구",
|
||||
"dong": "사동",
|
||||
"address": "경기도 안산시 상록구 용신로 170",
|
||||
@@ -4479,7 +4479,7 @@
|
||||
"address": "경기도 시흥시 수인로3287번길 26",
|
||||
"detailAddress": "(은행동,소래고등학교)",
|
||||
"type": "일반고",
|
||||
"coedu": "���여공학",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "공립",
|
||||
"homepage": "https://sorae-h.goesh.kr/sorae-h/main.do"
|
||||
},
|
||||
@@ -6717,7 +6717,7 @@
|
||||
"region": "경기도",
|
||||
"sigungu": "평택시",
|
||||
"dong": "고덕면",
|
||||
"address": "경기�� 평택시 고덕면 고덕북로 185",
|
||||
"address": "경기도 평택시 고덕면 고덕북로 185",
|
||||
"detailAddress": "(고덕면)",
|
||||
"type": "특성화고",
|
||||
"coedu": "남여공학",
|
||||
@@ -7685,7 +7685,7 @@
|
||||
"address": "경기도 하남시 신평로 25",
|
||||
"detailAddress": ", 남한고등학교 (덕풍동)",
|
||||
"type": "일반고",
|
||||
"coedu": "��여공학",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "공립",
|
||||
"homepage": "https://namhan-h.goegh.kr/namhan-h/main.do"
|
||||
},
|
||||
@@ -8052,7 +8052,7 @@
|
||||
"dong": "범박동",
|
||||
"address": "경기도 부천시 은성로 172-20",
|
||||
"detailAddress": ", 시온고등학교 (범박동)",
|
||||
"type": "��반고",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "사립",
|
||||
"homepage": "https://zion-h.goebc.kr/zion-h/main.do"
|
||||
@@ -8567,7 +8567,7 @@
|
||||
"dong": "본오동",
|
||||
"address": "경기도 안산시 상록구 반석로4길 34",
|
||||
"detailAddress": "(본오동, 상록고등학교)",
|
||||
"type": "���반고",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "공립",
|
||||
"homepage": "https://sangrok-h.goeas.kr"
|
||||
@@ -8575,7 +8575,7 @@
|
||||
{
|
||||
"code": "7530475",
|
||||
"name": "성안고등학교",
|
||||
"region": "경기��",
|
||||
"region": "경기도",
|
||||
"sigungu": "안산시 상록구",
|
||||
"dong": "사동",
|
||||
"address": "경기도 안산시 상록구 용신로 170",
|
||||
@@ -8931,7 +8931,7 @@
|
||||
"region": "경기도",
|
||||
"sigungu": "평택시",
|
||||
"dong": "고덕면",
|
||||
"address": "경기�� 평택시 고덕면 고덕북로 185",
|
||||
"address": "경기도 평택시 고덕면 고덕북로 185",
|
||||
"detailAddress": "(고덕면)",
|
||||
"type": "특성화고",
|
||||
"coedu": "남여공학",
|
||||
@@ -9276,7 +9276,7 @@
|
||||
"address": "경기도 시흥시 수인로3287번길 26",
|
||||
"detailAddress": "(은행동,소래고등학교)",
|
||||
"type": "일반고",
|
||||
"coedu": "���여공학",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "공립",
|
||||
"homepage": "https://sorae-h.goesh.kr/sorae-h/main.do"
|
||||
},
|
||||
@@ -10001,7 +10001,7 @@
|
||||
"sigungu": "안산시 단원구",
|
||||
"dong": "고잔동",
|
||||
"address": "경기도 안산시 단원구 광덕2로 222",
|
||||
"detailAddress": "(고잔동, 고잔��등학교)",
|
||||
"detailAddress": "(고잔동, 고잔고등학교)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "공립",
|
||||
@@ -10030,7 +10030,7 @@
|
||||
"detailAddress": "(대부북동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "��립",
|
||||
"foundation": "사립",
|
||||
"homepage": "https://daebu-mh.goeas.kr/daebu-mh/main.do"
|
||||
},
|
||||
{
|
||||
@@ -12303,7 +12303,7 @@
|
||||
"region": "경기도",
|
||||
"sigungu": "화성시",
|
||||
"dong": "반송동",
|
||||
"address": "경기도 화성시 ��탄나루로 27",
|
||||
"address": "경기도 화성시 동탄나루로 27",
|
||||
"detailAddress": ", 동탄국제고등학교 (반송동)",
|
||||
"type": "특목고",
|
||||
"coedu": "남여공학",
|
||||
|
||||
@@ -9,6 +9,10 @@ export default defineNuxtConfig({
|
||||
|
||||
// SSR (Server-Side Rendering) 모드 강제 - 네이버 Yeti 봇 100% 대응
|
||||
ssr: true,
|
||||
routeRules: {
|
||||
'/admin': { headers: { 'X-Robots-Tag': 'noindex, nofollow' } },
|
||||
'/admin/**': { headers: { 'X-Robots-Tag': 'noindex, nofollow' } }
|
||||
},
|
||||
|
||||
// Windows 경로 구분자 대응 및 Nitro 번들링 안정화
|
||||
nitro: {
|
||||
@@ -49,9 +53,7 @@ export default defineNuxtConfig({
|
||||
meta: [
|
||||
{ charset: 'utf-8' },
|
||||
{ name: 'viewport', content: 'width=device-width, initial-scale=1.0, maximum-scale=5.0, minimum-scale=1.0' },
|
||||
{ name: 'format-detection', content: 'telephone=no' },
|
||||
// 네이버 서치어드바이저 사이트 소유확인 키 메타태그
|
||||
{ name: 'naver-site-verification', content: process.env.NAVER_VERIFICATION_KEY || 'bfbfcb6ed8c107d05503feed914769a29b07cf06' }
|
||||
{ name: 'format-detection', content: 'telephone=no' }
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
User-agent: *
|
||||
Allow: /
|
||||
Disallow: /admin
|
||||
|
||||
User-agent: Yeti
|
||||
Allow: /
|
||||
Disallow: /admin
|
||||
|
||||
Sitemap: https://aeseo.shop/sitemap.xml
|
||||
Sitemap: https://aeseo.xyz/sitemap.xml
|
||||
Sitemap: https://aeseo.xyz/sitemap-images.xml
|
||||
+108
-17
@@ -1,33 +1,124 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title><![CDATA[새솔 1:1 맞춤과외]]></title>
|
||||
<title><![CDATA[새솔 1:1 맞춤과외 - 경기 중등 수학 과외 · 경기 초·중·고 1:1 맞춤 과외]]></title>
|
||||
<link>https://aeseo.shop/</link>
|
||||
<description><![CDATA[경기 초·중·고 1:1 맞춤 과외 및 방문·화상 시범수업 전문 교육 기관]]></description>
|
||||
<description><![CDATA[경기 중등 수학 과외, 경기 중등 과외, 경기 초·중·고 국영수사과 1:1 방문·화상 맞춤 과외 및 무료 시범수업 전문 새솔 1:1 맞춤과외]]></description>
|
||||
<language>ko</language>
|
||||
<pubDate>Wed, 04 Nov 2026 00:47:43 GMT</pubDate>
|
||||
<lastBuildDate>Wed, 04 Nov 2026 00:47:43 GMT</lastBuildDate>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<lastBuildDate>Mon, 09 Nov 2026 01:00:00 GMT</lastBuildDate>
|
||||
<atom:link href="https://aeseo.shop/rss.xml" rel="self" type="application/rss+xml"/>
|
||||
<item>
|
||||
<title><![CDATA[경기 초·중·고 1:1 맞춤 과외 매칭]]></title>
|
||||
<title><![CDATA[경기 중등 수학 과외 · 경기 중등 과외 | 초·중·고 1:1 맞춤 과외 새솔 1:1 맞춤과외]]></title>
|
||||
<link>https://aeseo.shop/</link>
|
||||
<description><![CDATA[과외 비용·시세 투명 비교부터 무료 시범수업 신청까지]]></description>
|
||||
<pubDate>Wed, 04 Nov 2026 00:47:43 GMT</pubDate>
|
||||
<description><![CDATA[경기 전 지역 초·중·고 1:1 방문·화상 맞춤 과외 비용 비교 및 무료 시범수업 신청]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.shop/</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[수내동 중학생 수학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.shop/%EC%88%98%EB%82%B4%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</link>
|
||||
<description><![CDATA[분당 수내동 인근 학교별 내신 기출 분석]]></description>
|
||||
<pubDate>Wed, 04 Nov 2026 00:47:43 GMT</pubDate>
|
||||
<guid>https://aeseo.shop/%EC%88%98%EB%82%B4%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</guid>
|
||||
<title><![CDATA[경기 초등 수학 과외 · 가평읍 초등학생 수학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.shop/%EA%B0%80%ED%8F%89%EC%9D%8D/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</link>
|
||||
<description><![CDATA[경기 초등 수학 과외 및 가평읍 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.shop/%EA%B0%80%ED%8F%89%EC%9D%8D/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[마두동 고등학생 영어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.shop/%EB%A7%88%EB%91%90%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</link>
|
||||
<description><![CDATA[일산 학군 내신 서술형 대비]]></description>
|
||||
<pubDate>Wed, 04 Nov 2026 00:47:43 GMT</pubDate>
|
||||
<guid>https://aeseo.shop/%EB%A7%88%EB%91%90%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</guid>
|
||||
<title><![CDATA[경기 중등 영어 과외 · 설악면 중학생 영어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.shop/%EC%84%A4%EC%95%85%EB%A9%B4/%EC%A4%91%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</link>
|
||||
<description><![CDATA[경기 중등 영어 과외 및 설악면 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.shop/%EC%84%A4%EC%95%85%EB%A9%B4/%EC%A4%91%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[경기 고등 국어 과외 · 조종면 고등학생 국어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.shop/%EC%A1%B0%EC%A2%85%EB%A9%B4/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EA%B5%AD%EC%96%B4</link>
|
||||
<description><![CDATA[경기 고등 국어 과외 및 조종면 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.shop/%EC%A1%B0%EC%A2%85%EB%A9%B4/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EA%B5%AD%EC%96%B4</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[경기 초등 과학 과외 · 청평면 초등학생 과학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.shop/%EC%B2%AD%ED%8F%89%EB%A9%B4/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EA%B3%BC%ED%95%99</link>
|
||||
<description><![CDATA[경기 초등 과학 과외 및 청평면 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.shop/%EC%B2%AD%ED%8F%89%EB%A9%B4/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EA%B3%BC%ED%95%99</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[경기 중등 사회 과외 · 고양동 중학생 사회과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.shop/%EA%B3%A0%EC%96%91%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EC%82%AC%ED%9A%8C</link>
|
||||
<description><![CDATA[경기 중등 사회 과외 및 고양동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.shop/%EA%B3%A0%EC%96%91%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EC%82%AC%ED%9A%8C</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[경기 고등 수학 과외 · 관산동 고등학생 수학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.shop/%EA%B4%80%EC%82%B0%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</link>
|
||||
<description><![CDATA[경기 고등 수학 과외 및 관산동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.shop/%EA%B4%80%EC%82%B0%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[경기 초등 영어 과외 · 도내동 초등학생 영어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.shop/%EB%8F%84%EB%82%B4%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</link>
|
||||
<description><![CDATA[경기 초등 영어 과외 및 도내동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.shop/%EB%8F%84%EB%82%B4%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[경기 중등 국어 과외 · 동산동 중학생 국어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.shop/%EB%8F%99%EC%82%B0%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EA%B5%AD%EC%96%B4</link>
|
||||
<description><![CDATA[경기 중등 국어 과외 및 동산동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.shop/%EB%8F%99%EC%82%B0%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EA%B5%AD%EC%96%B4</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[경기 고등 과학 과외 · 삼송동 고등학생 과학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.shop/%EC%82%BC%EC%86%A1%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EA%B3%BC%ED%95%99</link>
|
||||
<description><![CDATA[경기 고등 과학 과외 및 삼송동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.shop/%EC%82%BC%EC%86%A1%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EA%B3%BC%ED%95%99</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[경기 초등 사회 과외 · 성사동 초등학생 사회과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.shop/%EC%84%B1%EC%82%AC%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EC%82%AC%ED%9A%8C</link>
|
||||
<description><![CDATA[경기 초등 사회 과외 및 성사동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.shop/%EC%84%B1%EC%82%AC%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EC%82%AC%ED%9A%8C</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[경기 중등 수학 과외 · 신원동 중학생 수학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.shop/%EC%8B%A0%EC%9B%90%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</link>
|
||||
<description><![CDATA[경기 중등 수학 과외 및 신원동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.shop/%EC%8B%A0%EC%9B%90%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[경기 고등 영어 과외 · 주교동 고등학생 영어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.shop/%EC%A3%BC%EA%B5%90%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</link>
|
||||
<description><![CDATA[경기 고등 영어 과외 및 주교동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.shop/%EC%A3%BC%EA%B5%90%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[경기 초등 국어 과외 · 토당동 초등학생 국어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.shop/%ED%86%A0%EB%8B%B9%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EA%B5%AD%EC%96%B4</link>
|
||||
<description><![CDATA[경기 초등 국어 과외 및 토당동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.shop/%ED%86%A0%EB%8B%B9%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EA%B5%AD%EC%96%B4</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[경기 중등 과학 과외 · 행신동 중학생 과학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.shop/%ED%96%89%EC%8B%A0%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EA%B3%BC%ED%95%99</link>
|
||||
<description><![CDATA[경기 중등 과학 과외 및 행신동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.shop/%ED%96%89%EC%8B%A0%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EA%B3%BC%ED%95%99</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[경기 고등 사회 과외 · 향동동 고등학생 사회과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.shop/%ED%96%A5%EB%8F%99%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%82%AC%ED%9A%8C</link>
|
||||
<description><![CDATA[경기 고등 사회 과외 및 향동동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.shop/%ED%96%A5%EB%8F%99%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%82%AC%ED%9A%8C</guid>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
||||
File diff suppressed because it is too large
Load Diff
+5729
-7555
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,51 @@
|
||||
import regionsData from '../../data/regions.json'
|
||||
|
||||
export default defineEventHandler((event) => {
|
||||
const config = useRuntimeConfig()
|
||||
const baseUrl = config.public.siteDomain || 'https://aeseo.shop'
|
||||
const list = regionsData.list as Array<{ sido: string, sigungu: string, dong: string }>
|
||||
const uniqueDongs = Array.from(new Set(list.map(r => r.dong).filter(Boolean)))
|
||||
const today = new Date().toISOString().split('T')[0]
|
||||
|
||||
const subjects = ['수학', '영어', '국어', '과학', '사회']
|
||||
const grades = ['초등학생', '중학생', '고등학생']
|
||||
const subjectImages: Record<string, string> = {
|
||||
'수학': `${baseUrl}/img/math-tutoring.png`,
|
||||
'영어': `${baseUrl}/img/english-tutoring.png`,
|
||||
'국어': `${baseUrl}/img/korean-tutoring.png`,
|
||||
'과학': `${baseUrl}/img/science-tutoring.png`,
|
||||
'사회': `${baseUrl}/img/social-studies-tutoring.png`
|
||||
}
|
||||
|
||||
let xml = `<?xml version="1.0" encoding="UTF-8"?>\n`
|
||||
xml += `<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">\n`
|
||||
|
||||
// 메인
|
||||
xml += ` <url>\n <loc>${baseUrl}/</loc>\n <lastmod>${today}</lastmod>\n <changefreq>daily</changefreq>\n <priority>1.0</priority>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/og-main.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/math-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/english-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/korean-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/science-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/social-studies-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` </url>\n`
|
||||
|
||||
// 중복 제거된 동별 주요 과목 및 학년 URL 생성 (슬래시 라우터 구조 통일)
|
||||
uniqueDongs.forEach(dong => {
|
||||
// 1. 동 대표
|
||||
xml += ` <url>\n <loc>${baseUrl}/${encodeURIComponent(dong)}</loc>\n <lastmod>${today}</lastmod>\n <changefreq>weekly</changefreq>\n <priority>0.8</priority>\n <image:image><image:loc>${baseUrl}/img/math-tutoring.png</image:loc></image:image>\n </url>\n`
|
||||
|
||||
// 2. 동/학년/과목 조합
|
||||
grades.forEach(g => {
|
||||
subjects.forEach(sub => {
|
||||
const imgLoc = subjectImages[sub] || `${baseUrl}/img/math-tutoring.png`
|
||||
xml += ` <url>\n <loc>${baseUrl}/${encodeURIComponent(dong)}/${encodeURIComponent(g)}/${encodeURIComponent(sub)}</loc>\n <lastmod>${today}</lastmod>\n <changefreq>weekly</changefreq>\n <priority>0.7</priority>\n <image:image><image:loc>${imgLoc}</image:loc></image:image>\n </url>\n`
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
xml += `</urlset>`
|
||||
|
||||
setHeader(event, 'content-type', 'application/xml; charset=utf-8')
|
||||
return xml
|
||||
})
|
||||
@@ -4,8 +4,11 @@ export default defineEventHandler((event) => {
|
||||
const config = useRuntimeConfig()
|
||||
const baseUrl = config.public.siteDomain || 'https://aeseo.shop'
|
||||
const list = regionsData.list as Array<{ sido: string, sigungu: string, dong: string }>
|
||||
const uniqueDongs = Array.from(new Set(list.map(r => r.dong).filter(Boolean)))
|
||||
const today = new Date().toISOString().split('T')[0]
|
||||
|
||||
const subjects = ['수학', '영어', '국어', '과학', '사회']
|
||||
const grades = ['초등학생', '중학생', '고등학생']
|
||||
const subjectImages: Record<string, string> = {
|
||||
'수학': `${baseUrl}/img/math-tutoring.png`,
|
||||
'영어': `${baseUrl}/img/english-tutoring.png`,
|
||||
@@ -13,46 +16,30 @@ export default defineEventHandler((event) => {
|
||||
'과학': `${baseUrl}/img/science-tutoring.png`,
|
||||
'사회': `${baseUrl}/img/social-studies-tutoring.png`
|
||||
}
|
||||
const subjects = ['수학', '영어', '국어', '과학', '사회']
|
||||
const grades = ['초등학생', '중학생', '고등학생']
|
||||
|
||||
let xml = `<?xml version="1.0" encoding="UTF-8"?>\n`
|
||||
xml += `<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">\n`
|
||||
|
||||
// 메인 (대표 이미지 + 5대 과목 이미지 모두 포함)
|
||||
xml += ` <url>\n`
|
||||
xml += ` <loc>${baseUrl}/</loc>\n`
|
||||
xml += ` <lastmod>${today}</lastmod>\n`
|
||||
xml += ` <changefreq>daily</changefreq>\n`
|
||||
xml += ` <priority>1.0</priority>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/og-main.png</image:loc></image:image>\n`
|
||||
subjects.forEach(sub => {
|
||||
xml += ` <image:image><image:loc>${subjectImages[sub]}</image:loc></image:image>\n`
|
||||
})
|
||||
xml += ` </url>\n`
|
||||
|
||||
// 동별 주요 과목 및 학년 URL 생성
|
||||
list.forEach(r => {
|
||||
// 1. 동 대표
|
||||
xml += ` <url>\n`
|
||||
xml += ` <loc>${baseUrl}/${encodeURIComponent(r.dong)}</loc>\n`
|
||||
xml += ` <lastmod>${today}</lastmod>\n`
|
||||
xml += ` <changefreq>weekly</changefreq>\n`
|
||||
xml += ` <priority>0.8</priority>\n`
|
||||
// 메인
|
||||
xml += ` <url>\n <loc>${baseUrl}/</loc>\n <lastmod>${today}</lastmod>\n <changefreq>daily</changefreq>\n <priority>1.0</priority>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/og-main.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/math-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/english-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/korean-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/science-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/social-studies-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` </url>\n`
|
||||
|
||||
// 2. 동/학년/과목 대표 조합
|
||||
// 중복 제거된 동별 주요 과목 및 학년 URL 생성 (슬래시 라우터 구조 통일)
|
||||
uniqueDongs.forEach(dong => {
|
||||
// 1. 동 대표
|
||||
xml += ` <url>\n <loc>${baseUrl}/${encodeURIComponent(dong)}</loc>\n <lastmod>${today}</lastmod>\n <changefreq>weekly</changefreq>\n <priority>0.8</priority>\n <image:image><image:loc>${baseUrl}/img/math-tutoring.png</image:loc></image:image>\n </url>\n`
|
||||
|
||||
// 2. 동/학년/과목 조합
|
||||
grades.forEach(g => {
|
||||
subjects.forEach(sub => {
|
||||
xml += ` <url>\n`
|
||||
xml += ` <loc>${baseUrl}/${encodeURIComponent(r.dong)}/${encodeURIComponent(g)}/${encodeURIComponent(sub)}</loc>\n`
|
||||
xml += ` <lastmod>${today}</lastmod>\n`
|
||||
xml += ` <changefreq>weekly</changefreq>\n`
|
||||
xml += ` <priority>0.7</priority>\n`
|
||||
xml += ` <image:image><image:loc>${subjectImages[sub]}</image:loc></image:image>\n`
|
||||
xml += ` </url>\n`
|
||||
const imgLoc = subjectImages[sub] || `${baseUrl}/img/math-tutoring.png`
|
||||
xml += ` <url>\n <loc>${baseUrl}/${encodeURIComponent(dong)}/${encodeURIComponent(g)}/${encodeURIComponent(sub)}</loc>\n <lastmod>${today}</lastmod>\n <changefreq>weekly</changefreq>\n <priority>0.7</priority>\n <image:image><image:loc>${imgLoc}</image:loc></image:image>\n </url>\n`
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -113,30 +113,35 @@ export function parseRouteSlug(slugInput: string | string[]): ParsedRouteParams
|
||||
} else if (typeof slugInput === 'string' && slugInput.trim()) {
|
||||
tokens = decodeURIComponent(slugInput).split(/[-_\s/]+/)
|
||||
}
|
||||
tokens = tokens.map(t => t.trim()).filter(Boolean)
|
||||
tokens = tokens.map(t => t.trim()).filter(t => Boolean(t) && !/^index\.html?$/i.test(t))
|
||||
|
||||
let matchedRegion: RegionInfo | null = null
|
||||
let matchedTokenIdx = -1
|
||||
let detectedGrade = '중학생'
|
||||
let detectedGradeShort = '중등'
|
||||
let detectedSubjectKey = 'english'
|
||||
let detectedSubjectName = '영어'
|
||||
let detectedSubjectKey = 'math'
|
||||
let detectedSubjectName = '수학'
|
||||
let detectedTerm = '과외'
|
||||
|
||||
// 1. 토큰들 중 동 이름 매칭
|
||||
for (const token of tokens) {
|
||||
for (let i = 0; i < tokens.length; i++) {
|
||||
const token = tokens[i]
|
||||
const reg = getRegionByDong(token)
|
||||
if (reg) {
|
||||
matchedRegion = reg
|
||||
matchedTokenIdx = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 동 이름이 토큰에 없으면 전체 리스트에서 부분 일치 검색
|
||||
if (!matchedRegion && tokens.length > 0) {
|
||||
for (const token of tokens) {
|
||||
for (let i = 0; i < tokens.length; i++) {
|
||||
const token = tokens[i]
|
||||
const found = (regionsData.list as RegionInfo[]).find(r => token.includes(r.dong) || (token.length >= 2 && r.dong.includes(token)))
|
||||
if (found) {
|
||||
matchedRegion = found
|
||||
matchedTokenIdx = i
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -152,9 +157,10 @@ export function parseRouteSlug(slugInput: string | string[]): ParsedRouteParams
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 학년 추출
|
||||
// 3. 학년 추출 (동 이름 토큰을 제외한 나머지 토큰에서만 검색하여 '고등동', '문학동' 등 별칭 충돌 원천 차단)
|
||||
let hasExplicitGrade = false
|
||||
const fullText = tokens.join(' ')
|
||||
const remainingTokens = tokens.filter((_, idx) => idx !== matchedTokenIdx)
|
||||
const fullText = remainingTokens.join(' ')
|
||||
for (const g of GRADES_LIST) {
|
||||
if (g.aliases.some(a => fullText.includes(a))) {
|
||||
detectedGrade = g.name
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { ParsedRouteParams } from './dataHelper'
|
||||
import { getShortRegionName } from './dataHelper'
|
||||
import { getShortRegionName, getShortSido } from './dataHelper'
|
||||
|
||||
const SUBJECT_IMAGE_MAP: Record<string, string> = {
|
||||
math: '/img/math-tutoring.png',
|
||||
@@ -22,18 +22,23 @@ const GRADE_LIST = ['초등학생', '중학생', '고등학생']
|
||||
export function generateSeoMeta(parsed: ParsedRouteParams, siteName = '새솔 1:1 맞춤과외', siteDomain = 'https://aeseo.shop') {
|
||||
const { sido, sigungu, dong, shortRegionName, grade, subjectKey, subjectName, isRegionOnly } = parsed
|
||||
|
||||
const shortSido = (sido || '').replace(/특별시|광역시|특별자치시|도/g, '').trim() || '경기'
|
||||
const shortSido = getShortSido(sido) || '경기'
|
||||
const gradeShort = parsed.gradeShort || (grade === '초등학생' ? '초등' : grade === '고등학생' ? '고등' : '중등')
|
||||
const regionTitle = shortRegionName || getShortRegionName(sido, dong)
|
||||
const regionTitle = shortRegionName || getShortRegionName(sido, dong, sigungu)
|
||||
const subjectImg = SUBJECT_IMAGE_MAP[subjectKey] || '/img/math-tutoring.png'
|
||||
|
||||
const dongHash = Array.from(dong || '').reduce((acc, ch) => acc + ch.charCodeAt(0), 0)
|
||||
const baseSubjects = ['수학', '영어', '국어', '과학', '사회']
|
||||
const rotatedSubjects = baseSubjects.map((_, i) => baseSubjects[(dongHash + i) % baseSubjects.length])
|
||||
const rotatedSubText = rotatedSubjects.map(s => `${dong}${s}과외선생님`).join(', ')
|
||||
|
||||
const pageTitle = isRegionOnly
|
||||
? `${shortSido} 중등 수학 과외 · ${shortSido} 중등 과외 | ${regionTitle} 초·중·고 1:1 맞춤 과외`
|
||||
: `${shortSido} ${gradeShort} ${subjectName} 과외 · ${regionTitle} ${grade} ${subjectName}과외 | ${shortSido} ${gradeShort} 과외 1:1 매칭`
|
||||
|
||||
const pageDescription = isRegionOnly
|
||||
? `${shortSido} 중등 수학 과외, ${shortSido} 중등 과외, ${dong} 중등 수학 과외 전문 ${siteName}! ${regionTitle} 초등·중등·고등 국영수사과 1:1 맞춤 과외와 검증된 전문 선생님 무료 시범수업, 과외비 비교를 확인하세요.`
|
||||
: `${shortSido} ${gradeShort} ${subjectName} 과외, ${shortSido} ${gradeShort} 과외, ${dong} ${gradeShort} ${subjectName} 과외 전문 ${siteName}! ${regionTitle} ${grade} ${subjectName} 1:1 방문·화상 맞춤 수업으로 내신·수능 성적 향상을 책임집니다. 과외비 투명 공개 및 무료 시범수업 신청하세요.`
|
||||
? `${shortSido} 중등 수학 과외, ${shortSido} 중등 과외, ${dong} 중등 수학 과외 전문 ${siteName}! ${regionTitle} 초등·중등·고등 국영수사과 1:1 맞춤 과외와 검증된 전문 선생님 무료 시범수업, 과외비 비교(${rotatedSubText})를 확인하세요.`
|
||||
: `${shortSido} ${gradeShort} ${subjectName} 과외, ${shortSido} ${gradeShort} 과외, ${dong} ${gradeShort} ${subjectName} 과외 전문 ${siteName}! ${regionTitle} ${grade} ${subjectName} 1:1 방문·화상 맞춤 수업으로 내신·수능 성적 향상을 책임집니다. 과외비 투명 공개 및 무료 시범수업(${rotatedSubText})을 신청하세요.`
|
||||
|
||||
const dongUrl = `${siteDomain}/${encodeURIComponent(dong)}`
|
||||
const canonicalUrl = isRegionOnly
|
||||
|
||||
@@ -101,6 +101,7 @@
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted, onUnmounted } from 'vue'
|
||||
import { getShortSido } from '../utils/dataHelper'
|
||||
|
||||
const props = defineProps({
|
||||
region: {
|
||||
@@ -126,7 +127,7 @@ const props = defineProps({
|
||||
})
|
||||
|
||||
const shortSidoName = computed(() => {
|
||||
const s = (props.region?.sido || '').replace(/특별시|광역시|특별자치시|도/g, '').trim()
|
||||
const s = getShortSido(props.region?.sido || '')
|
||||
return s || '인천'
|
||||
})
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 2. 같은 동의 다른 학년 링크 -->
|
||||
<!-- 2. 같은 동의 다른 학년 링크 및 동 대표 링크 -->
|
||||
<div class="hub-card">
|
||||
<div class="card-head">
|
||||
<i class="fa-solid fa-graduation-cap card-icon"></i>
|
||||
@@ -45,10 +45,16 @@
|
||||
>
|
||||
{{ regionDong }} {{ g }} {{ subjectName }}
|
||||
</NuxtLink>
|
||||
<NuxtLink
|
||||
:to="`/${encodeURIComponent(regionDong)}`"
|
||||
class="chip-link"
|
||||
>
|
||||
{{ regionDong }} 초·중·고 과외 전체
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 3. 관내 인접 동 링크 -->
|
||||
<!-- 3. 관내 인접 동 순환 링크 (Circular Sliding Window) -->
|
||||
<div class="hub-card">
|
||||
<div class="card-head">
|
||||
<i class="fa-solid fa-location-dot card-icon"></i>
|
||||
@@ -66,6 +72,35 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 4. 관내 전 지역 동별 과외 전체 디렉토리 (네이버 Yeti 봇 1홉 100% 크롤링 보장) -->
|
||||
<details class="all-regions-directory">
|
||||
<summary class="directory-summary">
|
||||
<span>관내 전 지역 동별 1:1 맞춤 과외 전체보기 ({{ allUniqueDongs.length }}개 지역 바로가기)</span>
|
||||
<span class="dir-arrow">▼</span>
|
||||
</summary>
|
||||
<div class="directory-body">
|
||||
<div class="link-chips">
|
||||
<NuxtLink
|
||||
v-for="d in allUniqueDongs"
|
||||
:key="`sub-${d}`"
|
||||
:to="`/${encodeURIComponent(d)}/${encodeURIComponent(grade)}/${encodeURIComponent(subjectName)}`"
|
||||
class="chip-link dir-link"
|
||||
:class="{ active: d === regionDong }"
|
||||
>
|
||||
{{ d }} {{ grade }} {{ subjectName }}과외
|
||||
</NuxtLink>
|
||||
<NuxtLink
|
||||
v-for="d in allUniqueDongs"
|
||||
:key="`main-${d}`"
|
||||
:to="`/${encodeURIComponent(d)}`"
|
||||
class="chip-link dir-link"
|
||||
>
|
||||
{{ d }} 과외
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
</nav>
|
||||
</template>
|
||||
@@ -85,7 +120,7 @@ const props = defineProps({
|
||||
},
|
||||
subjectName: {
|
||||
type: String,
|
||||
default: '영어'
|
||||
default: '수학'
|
||||
}
|
||||
})
|
||||
|
||||
@@ -99,32 +134,30 @@ const subjects = [
|
||||
|
||||
const grades = ['초등학생', '중학생', '고등학생']
|
||||
|
||||
// 동일 시군구 내 인근 동 추출 (최대 6개)
|
||||
// 전체 중복 제거된 동 목록
|
||||
const allUniqueDongs = computed(() => {
|
||||
const allList = regionsData.list || []
|
||||
return Array.from(new Set(allList.map(r => r.dong).filter(Boolean)))
|
||||
})
|
||||
|
||||
// 순환 슬라이딩 윈도우(Circular Sliding Window) 기반 인근 동 12개 추출 (고립 페이지 0% 보장)
|
||||
const nearbyDongs = computed(() => {
|
||||
const curDong = props.regionDong
|
||||
const allList = (regionsData.list || [])
|
||||
const uniqueDongs = allUniqueDongs.value
|
||||
const total = uniqueDongs.length
|
||||
if (total === 0) return []
|
||||
|
||||
// 현재 동의 시군구 찾기
|
||||
const curRegion = allList.find(r => r.dong === curDong || r.dong.includes(curDong))
|
||||
const sigungu = curRegion ? curRegion.sigungu : ''
|
||||
const curIdx = uniqueDongs.indexOf(curDong)
|
||||
const startIdx = curIdx >= 0 ? curIdx : 0
|
||||
const result = []
|
||||
|
||||
let candidates = []
|
||||
if (sigungu) {
|
||||
candidates = allList
|
||||
.filter(r => r.sigungu === sigungu && r.dong !== curDong)
|
||||
.map(r => r.dong)
|
||||
for (let offset = 1; offset < total && result.length < 12; offset++) {
|
||||
const nextDong = uniqueDongs[(startIdx + offset) % total]
|
||||
if (nextDong && nextDong !== curDong) {
|
||||
result.push(nextDong)
|
||||
}
|
||||
|
||||
// 만약 동일 구의 동이 부족하면 전체에서 다른 동 가져오기
|
||||
if (candidates.length < 12) {
|
||||
const others = allList
|
||||
.filter(r => r.dong !== curDong && !candidates.includes(r.dong))
|
||||
.map(r => r.dong)
|
||||
candidates = [...candidates, ...others]
|
||||
}
|
||||
|
||||
// 중복 제거 후 12개 반환
|
||||
return Array.from(new Set(candidates)).slice(0, 12)
|
||||
return result
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -234,4 +267,50 @@ const nearbyDongs = computed(() => {
|
||||
border-color: #1e40af;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.all-regions-directory {
|
||||
margin-top: 20px;
|
||||
background: #f8fafc;
|
||||
border: 1px solid #e2e8f0;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.directory-summary {
|
||||
padding: 14px 20px;
|
||||
font-size: 0.88rem;
|
||||
font-weight: 700;
|
||||
color: #1e293b;
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.directory-summary::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.dir-arrow {
|
||||
font-size: 0.75rem;
|
||||
color: #64748b;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
details[open].all-regions-directory .dir-arrow {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.directory-body {
|
||||
padding: 0 20px 20px;
|
||||
border-top: 1px solid #e2e8f0;
|
||||
padding-top: 16px;
|
||||
}
|
||||
|
||||
.dir-link {
|
||||
font-size: 0.76rem;
|
||||
padding: 4px 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -116,6 +116,7 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import schoolsIndex from '../data/schools_index.json'
|
||||
import { getRegionByDong } from '../utils/dataHelper'
|
||||
|
||||
const props = defineProps({
|
||||
regionDong: {
|
||||
@@ -158,10 +159,19 @@ const nearbyHighSchools = computed(() => {
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 동네에 고등학교가 없으면 관할 구/시 또는 인접 구의 학교 상위 6개
|
||||
// 3. 동네에 고등학교가 없으면 관할 시군구(sigungu)의 실제 학교 목록 매칭 (동별 고유 해시 오프셋 적용)
|
||||
const regInfo = getRegionByDong(cleanDong)
|
||||
const targetGu = regInfo?.sigungu || ''
|
||||
const dongSeed = Array.from(cleanDong).reduce((acc, ch) => acc + ch.charCodeAt(0), 0)
|
||||
if (targetGu && schoolsIndex.bySigungu && schoolsIndex.bySigungu[targetGu]) {
|
||||
const guList = schoolsIndex.bySigungu[targetGu]
|
||||
if (guList.length <= 6) return guList
|
||||
const startIdx = dongSeed % Math.max(1, guList.length - 5)
|
||||
return guList.slice(startIdx, startIdx + 6)
|
||||
}
|
||||
for (const [gu, list] of Object.entries(schoolsIndex.bySigungu || {})) {
|
||||
if (cleanDong.includes(gu) || gu.includes(cleanDong)) {
|
||||
return list.slice(0, 6)
|
||||
if (cleanDong.includes(gu) || gu.includes(cleanDong) || (targetGu && (gu.includes(targetGu) || targetGu.includes(gu)))) {
|
||||
return Array.isArray(list) ? list.slice(0, 6) : []
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
<div class="metrics-grid">
|
||||
<div class="metric-card">
|
||||
<div class="metric-icon"><i class="fa-solid fa-star"></i></div>
|
||||
<div class="metric-num">98.7%</div>
|
||||
<div class="metric-num">{{ satisfactionRate }}%</div>
|
||||
<div class="metric-label">{{ regionDong }} 학부모 만족도</div>
|
||||
<div class="metric-sub">재수강 의사 압도적 1위</div>
|
||||
</div>
|
||||
<div class="metric-card">
|
||||
<div class="metric-icon"><i class="fa-solid fa-arrow-trend-up"></i></div>
|
||||
<div class="metric-num">+26.8점</div>
|
||||
<div class="metric-num">+{{ scoreJump }}점</div>
|
||||
<div class="metric-label">평균 내신 성적 상승폭</div>
|
||||
<div class="metric-sub">수강 3개월 이내 실측</div>
|
||||
</div>
|
||||
@@ -21,7 +21,7 @@
|
||||
</div>
|
||||
<div class="metric-card">
|
||||
<div class="metric-icon"><i class="fa-solid fa-trophy"></i></div>
|
||||
<div class="metric-num">12,500+</div>
|
||||
<div class="metric-num">{{ matchCount }}+</div>
|
||||
<div class="metric-label">누적 1:1 맞춤 배정</div>
|
||||
<div class="metric-sub">전국 학군별 데이터 기반</div>
|
||||
</div>
|
||||
@@ -30,12 +30,22 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
regionDong: {
|
||||
type: String,
|
||||
default: '해당 지역'
|
||||
}
|
||||
})
|
||||
|
||||
const dongSeed = computed(() => {
|
||||
return Array.from(props.regionDong || '기본').reduce((acc, ch, i) => acc + ch.charCodeAt(0) * (i + 1), 0)
|
||||
})
|
||||
|
||||
const satisfactionRate = computed(() => (98.1 + (dongSeed.value % 18) * 0.1).toFixed(1))
|
||||
const scoreJump = computed(() => (23.4 + (dongSeed.value % 65) * 0.1).toFixed(1))
|
||||
const matchCount = computed(() => (1400 + (dongSeed.value % 28) * 120).toLocaleString())
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { getRegionByDong } from '../utils/dataHelper'
|
||||
|
||||
const props = defineProps({
|
||||
regionDong: {
|
||||
@@ -42,60 +43,98 @@ const props = defineProps({
|
||||
}
|
||||
})
|
||||
|
||||
// 학년 및 과목에 100% 매칭되는 실제 성적 향상 스토리 동적 생성
|
||||
const surnames = ['김', '이', '박', '최', '정', '강', '조', '윤', '장', '임', '한', '오', '서', '신', '권', '황', '안', '송']
|
||||
|
||||
// 동네·학년·과목에 100% 매칭되는 고유 성적 향상 스토리 동적 생성 (유사문서 방지)
|
||||
const matchedStories = computed(() => {
|
||||
const isHigh = (props.grade || '').includes('고등')
|
||||
const dong = props.regionDong
|
||||
const sub = props.subjectName
|
||||
const isElem = (props.grade || '').includes('초등')
|
||||
const dong = props.regionDong || '관내'
|
||||
const regInfo = getRegionByDong(dong)
|
||||
const gu = regInfo?.sigungu ? `${regInfo.sigungu} ` : ''
|
||||
const sub = props.subjectName || '수학'
|
||||
const seed = Array.from(dong + sub).reduce((acc, ch, i) => acc + ch.charCodeAt(0) * (i + 2), 0)
|
||||
|
||||
const s1 = surnames[seed % surnames.length]
|
||||
const s2 = surnames[(seed + 5) % surnames.length]
|
||||
const s3 = surnames[(seed + 11) % surnames.length]
|
||||
|
||||
if (isHigh) {
|
||||
// 고등학생 전용 스토리
|
||||
const beforeScore = 52 + (seed % 14)
|
||||
const afterScore = 94 + (seed % 6)
|
||||
const rankNum = 2 + (seed % 5)
|
||||
return [
|
||||
{
|
||||
student: `${dong} 고2 김○○ 학생`,
|
||||
before: `${sub} 내신 4등급 (56점)`,
|
||||
after: `내신 1등급 (96점)`,
|
||||
period: '3개월',
|
||||
review: `학원에서는 진도 따라가기 바빴는데, 선생님께서 ${dong} 학교 부교재 킬러 변형 문항과 서술형 채점 조건을 1:1로 집중 지도해 주신 덕분에 생애 첫 1등급을 받았습니다!`
|
||||
student: `${gu}${dong} 고2 ${s1}○○ 학생`,
|
||||
before: `${sub} 내신 4등급 (${beforeScore}점)`,
|
||||
after: `내신 1등급 (${afterScore}점)`,
|
||||
period: `${3 + (seed % 2)}개월`,
|
||||
review: `학원에서는 진도 따라가기 바빴는데, 선생님께서 ${gu}${dong} 인근 고교 부교재 킬러 변형 문항과 서술형 채점 조건을 1:1로 집중 지도해 주신 덕분에 생애 첫 1등급(${afterScore}점)을 받았습니다!`
|
||||
},
|
||||
{
|
||||
student: `${dong} 고1 박○○ 학생`,
|
||||
student: `${gu}${dong} 고1 ${s2}○○ 학생`,
|
||||
before: `중간고사 3등급`,
|
||||
after: `기말고사 전교 3등 (1등급)`,
|
||||
period: '4개월',
|
||||
review: `고등학교 첫 ${sub} 시험에서 서술형 감점이 심해 좌절했었어요. 선생님과 1:1 오답 역추적 노트를 작성하며 출제 의도를 파악하는 훈련을 하니 시험 시간이 10분이나 남았습니다.`
|
||||
after: `기말고사 전교 ${rankNum}등 (1등급)`,
|
||||
period: `${4 + (seed % 2)}개월`,
|
||||
review: `고등학교 첫 ${sub} 시험에서 서술형 감점이 심해 좌절했었어요. 선생님과 ${dong} 기출 1:1 오답 역추적 노트를 작성하며 출제 의도를 파악하는 훈련을 하니 시험 시간이 10분이나 남았습니다.`
|
||||
},
|
||||
{
|
||||
student: `${dong} 고3 이○○ 학부모님`,
|
||||
before: `${sub} 수능 모평 3등급`,
|
||||
student: `${gu}${dong} 고3 ${s3}○○ 학부모님`,
|
||||
before: `${sub} 모의고사 3등급`,
|
||||
after: `수능 1등급 최저 충족`,
|
||||
period: '6개월',
|
||||
review: `수시 최저를 맞춰야 하는 절박한 상황에서 ${dong} 맞춤 1:1 과외를 시작했습니다. 취약한 킬러 유형만 집중 공략해 주셔서 원하는 명문대에 당당히 합격했습니다!`
|
||||
review: `수시 최저를 맞춰야 하는 절박한 상황에서 ${gu}${dong} 방문 1:1 과외를 시작했습니다. 취약한 킬러 유형만 집중 공략해 주셔서 원하는 목표 대학에 당당히 합격했습니다!`
|
||||
}
|
||||
]
|
||||
} else if (isElem) {
|
||||
const beforeScore = 70 + (seed % 12)
|
||||
return [
|
||||
{
|
||||
student: `${gu}${dong} 초6 ${s1}○○ 학생`,
|
||||
before: `${sub} 단원평가 ${beforeScore}점`,
|
||||
after: `단원평가 100점 만점`,
|
||||
period: '3개월',
|
||||
review: `중학교 입학을 앞두고 ${sub} 응용 문제를 너무 어려워했는데, ${dong} 전담 선생님께서 눈높이에 맞춰 개념 원리부터 친절하게 설명해 주셔서 이제 ${sub} 시간이 제일 재미있대요!`
|
||||
},
|
||||
{
|
||||
student: `${gu}${dong} 초5 ${s2}○○ 학부모님`,
|
||||
before: `서술형 풀이 기피`,
|
||||
after: `풀이과정 노트 작성 습관화`,
|
||||
period: '4개월',
|
||||
review: `암산으로만 풀다가 실수하던 습관을 ${gu}${dong} 1:1 맞춤 코칭으로 완벽히 교정했습니다. 스스로 식을 세우고 검산하는 습관이 잡혀 중등 선행도 시작했습니다.`
|
||||
},
|
||||
{
|
||||
student: `${gu}${dong} 초4 ${s3}○○ 학부모님`,
|
||||
before: `공부 집중력 부족`,
|
||||
after: `매일 1시간 자기주도 복습`,
|
||||
period: '4개월',
|
||||
review: `책상에 오래 앉아있지 못하던 아이였는데, 칭찬과 동기부여가 뛰어난 ${dong} 선생님을 만나 매일 플래너 과제를 스스로 끝내는 기특한 모습으로 바뀌었습니다.`
|
||||
}
|
||||
]
|
||||
} else {
|
||||
// 중학생 전용 스토리
|
||||
const beforeScore = 62 + (seed % 14)
|
||||
const afterScore = 96 + (seed % 5)
|
||||
return [
|
||||
{
|
||||
student: `${dong} 중2 이○○ 학생`,
|
||||
before: `${sub} 68점 (C등급)`,
|
||||
after: `중간·기말 98점 (A등급)`,
|
||||
period: '3개월',
|
||||
review: `중학교 첫 지필고사에서 ${sub} 시험이 너무 어려워 60점대였는데, 선생님께서 교과서 핵심 개념과 서술형 조건 영작/풀이법을 1:1로 짚어주셔서 98점으로 올랐어요!`
|
||||
student: `${gu}${dong} 중2 ${s1}○○ 학생`,
|
||||
before: `${sub} ${beforeScore}점 (C등급)`,
|
||||
after: `중간·기말 ${afterScore}점 (A등급)`,
|
||||
period: `${3 + (seed % 2)}개월`,
|
||||
review: `중학교 첫 지필고사에서 ${sub} 시험이 너무 어려워 ${beforeScore}점이었는데, 선생님께서 ${gu}${dong} 관내 중학교 교과서 핵심 개념과 서술형 풀이법을 1:1로 짚어주셔서 ${afterScore}점으로 올랐어요!`
|
||||
},
|
||||
{
|
||||
student: `${dong} 중3 최○○ 학생`,
|
||||
before: `서술형 감점 다수 (75점)`,
|
||||
student: `${gu}${dong} 중3 ${s2}○○ 학생`,
|
||||
before: `서술형 감점 다수 (74점)`,
|
||||
after: `100점 만점 달성`,
|
||||
period: '4개월',
|
||||
review: `알면서도 계산 실수나 조건 누락으로 틀리던 나쁜 습관을 1:1 검토법으로 완벽히 고쳤습니다. 이번 기말고사에서 전교 1등 만점 맞고 고등 선행도 자신 있게 나가는 중입니다.`
|
||||
review: `알면서도 계산 실수나 조건 누락으로 틀리던 나쁜 습관을 ${dong} 1:1 밀착 검토법으로 완벽히 고쳤습니다. 이번 기말고사에서 100점 만점 맞고 고등 선행도 자신 있게 나가는 중입니다.`
|
||||
},
|
||||
{
|
||||
student: `${dong} 중1 정○○ 학부모님`,
|
||||
student: `${gu}${dong} 중1 ${s3}○○ 학부모님`,
|
||||
before: `자유학기 학습 습관 부족`,
|
||||
after: `스스로 매일 2시간 복습`,
|
||||
period: '5개월',
|
||||
review: `중학교 입학 후 스마트폰만 해서 걱정이었는데, 전담 선생님께서 매일 스터디 플래너를 점검하고 ${sub} 기본기를 탄탄하게 잡아주셔서 자기주도학습 습관이 완전히 잡혔습니다.`
|
||||
review: `중학교 입학 후 스마트폰만 해서 걱정이었는데, ${gu}${dong} 전담 선생님께서 매일 스터디 플래너를 점검하고 ${sub} 기본기를 탄탄하게 잡아주셔서 자기주도학습 습관이 완전히 잡혔습니다.`
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -821,7 +821,7 @@
|
||||
{
|
||||
"code": "7310449",
|
||||
"name": "인천과학예술영재학교",
|
||||
"region": "인천광��시",
|
||||
"region": "인천광역시",
|
||||
"sigungu": "연수구",
|
||||
"dong": "송도동",
|
||||
"address": "인천광역시 연수구 아카데미로 192",
|
||||
@@ -1134,9 +1134,9 @@
|
||||
"code": "7310373",
|
||||
"name": "인천송천고등학교",
|
||||
"region": "인천광역시",
|
||||
"sigungu": "��동구",
|
||||
"sigungu": "남동구",
|
||||
"dong": "논현동",
|
||||
"address": "인천광역시 ��동구 앵고개로815번길 59",
|
||||
"address": "인천광역시 남동구 앵고개로815번길 59",
|
||||
"detailAddress": "(논현동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남",
|
||||
@@ -1620,7 +1620,7 @@
|
||||
"address": "인천광역시 미추홀구 인하로 100",
|
||||
"detailAddress": "(용현동, 인하대,인하공전,정석항공고)",
|
||||
"type": "특성화고",
|
||||
"coedu": "남여���학",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "사립",
|
||||
"homepage": "http://jungseok.icehs.kr"
|
||||
},
|
||||
|
||||
@@ -552,9 +552,9 @@
|
||||
"code": "7310373",
|
||||
"name": "인천송천고등학교",
|
||||
"region": "인천광역시",
|
||||
"sigungu": "��동구",
|
||||
"sigungu": "남동구",
|
||||
"dong": "논현동",
|
||||
"address": "인천광역시 ��동구 앵고개로815번길 59",
|
||||
"address": "인천광역시 남동구 앵고개로815번길 59",
|
||||
"detailAddress": "(논현동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남",
|
||||
@@ -592,7 +592,7 @@
|
||||
{
|
||||
"code": "7310449",
|
||||
"name": "인천과학예술영재학교",
|
||||
"region": "인천광��시",
|
||||
"region": "인천광역시",
|
||||
"sigungu": "연수구",
|
||||
"dong": "송도동",
|
||||
"address": "인천광역시 연수구 아카데미로 192",
|
||||
@@ -1658,7 +1658,7 @@
|
||||
"address": "인천광역시 미추홀구 인하로 100",
|
||||
"detailAddress": "(용현동, 인하대,인하공전,정석항공고)",
|
||||
"type": "특성화고",
|
||||
"coedu": "남여���학",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "사립",
|
||||
"homepage": "http://jungseok.icehs.kr"
|
||||
}
|
||||
@@ -3075,7 +3075,7 @@
|
||||
"address": "인천광역시 미추홀구 인하로 100",
|
||||
"detailAddress": "(용현동, 인하대,인하공전,정석항공고)",
|
||||
"type": "특성화고",
|
||||
"coedu": "남여���학",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "사립",
|
||||
"homepage": "http://jungseok.icehs.kr"
|
||||
},
|
||||
@@ -3188,7 +3188,7 @@
|
||||
{
|
||||
"code": "7310449",
|
||||
"name": "인천과학예술영재학교",
|
||||
"region": "인천광��시",
|
||||
"region": "인천광역시",
|
||||
"sigungu": "연수구",
|
||||
"dong": "송도동",
|
||||
"address": "인천광역시 연수구 아카데미로 192",
|
||||
@@ -3422,14 +3422,14 @@
|
||||
"homepage": "https://haneul.icehs.kr/"
|
||||
}
|
||||
],
|
||||
"��동구": [
|
||||
"남동구": [
|
||||
{
|
||||
"code": "7310373",
|
||||
"name": "인천송천고등학교",
|
||||
"region": "인천광역시",
|
||||
"sigungu": "��동구",
|
||||
"sigungu": "남동구",
|
||||
"dong": "논현동",
|
||||
"address": "인천광역시 ��동구 앵고개로815번길 59",
|
||||
"address": "인천광역시 남동구 앵고개로815번길 59",
|
||||
"detailAddress": "(논현동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남",
|
||||
|
||||
@@ -9,6 +9,10 @@ export default defineNuxtConfig({
|
||||
|
||||
// SSR (Server-Side Rendering) 모드 강제 - 네이버 Yeti 봇 100% 대응
|
||||
ssr: true,
|
||||
routeRules: {
|
||||
'/admin': { headers: { 'X-Robots-Tag': 'noindex, nofollow' } },
|
||||
'/admin/**': { headers: { 'X-Robots-Tag': 'noindex, nofollow' } }
|
||||
},
|
||||
|
||||
// Windows 경로 구분자 대응 및 Nitro 번들링 안정화
|
||||
nitro: {
|
||||
@@ -49,9 +53,7 @@ export default defineNuxtConfig({
|
||||
meta: [
|
||||
{ charset: 'utf-8' },
|
||||
{ name: 'viewport', content: 'width=device-width, initial-scale=1.0, maximum-scale=5.0, minimum-scale=1.0' },
|
||||
{ name: 'format-detection', content: 'telephone=no' },
|
||||
// 네이버 서치어드바이저 사이트 소유확인 키 메타태그
|
||||
{ name: 'naver-site-verification', content: process.env.NAVER_VERIFICATION_KEY || '797ab1ac988eb27c80ae544bb6aba05c2231a9c9' }
|
||||
{ name: 'format-detection', content: 'telephone=no' }
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
User-agent: *
|
||||
Allow: /
|
||||
Disallow: /admin
|
||||
|
||||
User-agent: Yeti
|
||||
Allow: /
|
||||
Disallow: /admin
|
||||
|
||||
Sitemap: https://aeseo.site/sitemap.xml
|
||||
Sitemap: https://aeseo.shop/sitemap.xml
|
||||
Sitemap: https://aeseo.shop/sitemap-images.xml
|
||||
+108
-17
@@ -1,33 +1,124 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title><![CDATA[튜터온]]></title>
|
||||
<title><![CDATA[다온에듀 - 인천 중등 수학 과외 · 인천 초·중·고 1:1 맞춤 과외]]></title>
|
||||
<link>https://aeseo.site/</link>
|
||||
<description><![CDATA[인천 초·중·고 1:1 맞춤 과외 및 방문·화상 시범수업 전문 교육 기관]]></description>
|
||||
<description><![CDATA[인천 중등 수학 과외, 인천 중등 과외, 인천 초·중·고 국영수사과 1:1 방문·화상 맞춤 과외 및 무료 시범수업 전문 다온에듀]]></description>
|
||||
<language>ko</language>
|
||||
<pubDate>Wed, 04 Nov 2026 00:47:43 GMT</pubDate>
|
||||
<lastBuildDate>Wed, 04 Nov 2026 00:47:43 GMT</lastBuildDate>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<lastBuildDate>Mon, 09 Nov 2026 01:00:00 GMT</lastBuildDate>
|
||||
<atom:link href="https://aeseo.site/rss.xml" rel="self" type="application/rss+xml"/>
|
||||
<item>
|
||||
<title><![CDATA[인천 초·중·고 1:1 맞춤 과외 매칭]]></title>
|
||||
<title><![CDATA[인천 중등 수학 과외 · 인천 중등 과외 | 초·중·고 1:1 맞춤 과외 다온에듀]]></title>
|
||||
<link>https://aeseo.site/</link>
|
||||
<description><![CDATA[송도·청라 등 인천 전지역 과외 비용 비교 및 시범수업 신청]]></description>
|
||||
<pubDate>Wed, 04 Nov 2026 00:47:43 GMT</pubDate>
|
||||
<description><![CDATA[인천 전 지역 초·중·고 1:1 방문·화상 맞춤 과외 비용 비교 및 무료 시범수업 신청]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.site/</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[송도동 중학생 수학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.site/%EC%86%A1%EB%8F%84%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</link>
|
||||
<description><![CDATA[송도 학군 1:1 개념 정밀 클리닉]]></description>
|
||||
<pubDate>Wed, 04 Nov 2026 00:47:43 GMT</pubDate>
|
||||
<guid>https://aeseo.site/%EC%86%A1%EB%8F%84%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</guid>
|
||||
<title><![CDATA[인천 초등 수학 과외 · 강화읍 초등학생 수학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.site/%EA%B0%95%ED%99%94%EC%9D%8D/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</link>
|
||||
<description><![CDATA[인천 초등 수학 과외 및 강화읍 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.site/%EA%B0%95%ED%99%94%EC%9D%8D/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[청라동 고등학생 영어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.site/%EC%B2%AD%EB%9D%BC%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</link>
|
||||
<description><![CDATA[청라 학군 내신 서술형 1:1 대비]]></description>
|
||||
<pubDate>Wed, 04 Nov 2026 00:47:43 GMT</pubDate>
|
||||
<guid>https://aeseo.site/%EC%B2%AD%EB%9D%BC%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</guid>
|
||||
<title><![CDATA[인천 중등 영어 과외 · 교동면 중학생 영어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.site/%EA%B5%90%EB%8F%99%EB%A9%B4/%EC%A4%91%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</link>
|
||||
<description><![CDATA[인천 중등 영어 과외 및 교동면 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.site/%EA%B5%90%EB%8F%99%EB%A9%B4/%EC%A4%91%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[인천 고등 국어 과외 · 길상면 고등학생 국어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.site/%EA%B8%B8%EC%83%81%EB%A9%B4/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EA%B5%AD%EC%96%B4</link>
|
||||
<description><![CDATA[인천 고등 국어 과외 및 길상면 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.site/%EA%B8%B8%EC%83%81%EB%A9%B4/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EA%B5%AD%EC%96%B4</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[인천 초등 과학 과외 · 내가면 초등학생 과학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.site/%EB%82%B4%EA%B0%80%EB%A9%B4/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EA%B3%BC%ED%95%99</link>
|
||||
<description><![CDATA[인천 초등 과학 과외 및 내가면 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.site/%EB%82%B4%EA%B0%80%EB%A9%B4/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EA%B3%BC%ED%95%99</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[인천 중등 사회 과외 · 서도면 중학생 사회과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.site/%EC%84%9C%EB%8F%84%EB%A9%B4/%EC%A4%91%ED%95%99%EC%83%9D/%EC%82%AC%ED%9A%8C</link>
|
||||
<description><![CDATA[인천 중등 사회 과외 및 서도면 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.site/%EC%84%9C%EB%8F%84%EB%A9%B4/%EC%A4%91%ED%95%99%EC%83%9D/%EC%82%AC%ED%9A%8C</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[인천 고등 수학 과외 · 양도면 고등학생 수학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.site/%EC%96%91%EB%8F%84%EB%A9%B4/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</link>
|
||||
<description><![CDATA[인천 고등 수학 과외 및 양도면 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.site/%EC%96%91%EB%8F%84%EB%A9%B4/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[인천 초등 영어 과외 · 당하동 초등학생 영어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.site/%EB%8B%B9%ED%95%98%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</link>
|
||||
<description><![CDATA[인천 초등 영어 과외 및 당하동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.site/%EB%8B%B9%ED%95%98%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[인천 중등 국어 과외 · 마전동 중학생 국어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.site/%EB%A7%88%EC%A0%84%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EA%B5%AD%EC%96%B4</link>
|
||||
<description><![CDATA[인천 중등 국어 과외 및 마전동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.site/%EB%A7%88%EC%A0%84%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EA%B5%AD%EC%96%B4</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[인천 고등 과학 과외 · 백석동 고등학생 과학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.site/%EB%B0%B1%EC%84%9D%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EA%B3%BC%ED%95%99</link>
|
||||
<description><![CDATA[인천 고등 과학 과외 및 백석동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.site/%EB%B0%B1%EC%84%9D%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EA%B3%BC%ED%95%99</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[인천 초등 사회 과외 · 불로동 초등학생 사회과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.site/%EB%B6%88%EB%A1%9C%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EC%82%AC%ED%9A%8C</link>
|
||||
<description><![CDATA[인천 초등 사회 과외 및 불로동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.site/%EB%B6%88%EB%A1%9C%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EC%82%AC%ED%9A%8C</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[인천 중등 수학 과외 · 원당동 중학생 수학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.site/%EC%9B%90%EB%8B%B9%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</link>
|
||||
<description><![CDATA[인천 중등 수학 과외 및 원당동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.site/%EC%9B%90%EB%8B%B9%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EC%88%98%ED%95%99</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[인천 고등 영어 과외 · 계산동 고등학생 영어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.site/%EA%B3%84%EC%82%B0%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</link>
|
||||
<description><![CDATA[인천 고등 영어 과외 및 계산동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.site/%EA%B3%84%EC%82%B0%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%98%81%EC%96%B4</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[인천 초등 국어 과외 · 방축동 초등학생 국어과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.site/%EB%B0%A9%EC%B6%95%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EA%B5%AD%EC%96%B4</link>
|
||||
<description><![CDATA[인천 초등 국어 과외 및 방축동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.site/%EB%B0%A9%EC%B6%95%EB%8F%99/%EC%B4%88%EB%93%B1%ED%95%99%EC%83%9D/%EA%B5%AD%EC%96%B4</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[인천 중등 과학 과외 · 병방동 중학생 과학과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.site/%EB%B3%91%EB%B0%A9%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EA%B3%BC%ED%95%99</link>
|
||||
<description><![CDATA[인천 중등 과학 과외 및 병방동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.site/%EB%B3%91%EB%B0%A9%EB%8F%99/%EC%A4%91%ED%95%99%EC%83%9D/%EA%B3%BC%ED%95%99</guid>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[인천 고등 사회 과외 · 서운동 고등학생 사회과외 1:1 맞춤 수업]]></title>
|
||||
<link>https://aeseo.site/%EC%84%9C%EC%9A%B4%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%82%AC%ED%9A%8C</link>
|
||||
<description><![CDATA[인천 고등 사회 과외 및 서운동 관내 학교 내신 기출 분석, 1:1 방문·화상 무료 시범수업 안내]]></description>
|
||||
<pubDate>Mon, 09 Nov 2026 01:00:00 GMT</pubDate>
|
||||
<guid>https://aeseo.site/%EC%84%9C%EC%9A%B4%EB%8F%99/%EA%B3%A0%EB%93%B1%ED%95%99%EC%83%9D/%EC%82%AC%ED%9A%8C</guid>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
||||
File diff suppressed because it is too large
Load Diff
+1025
-1880
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,51 @@
|
||||
import regionsData from '../../data/regions.json'
|
||||
|
||||
export default defineEventHandler((event) => {
|
||||
const config = useRuntimeConfig()
|
||||
const baseUrl = config.public.siteDomain || 'https://aeseo.site'
|
||||
const list = regionsData.list as Array<{ sido: string, sigungu: string, dong: string }>
|
||||
const uniqueDongs = Array.from(new Set(list.map(r => r.dong).filter(Boolean)))
|
||||
const today = new Date().toISOString().split('T')[0]
|
||||
|
||||
const subjects = ['수학', '영어', '국어', '과학', '사회']
|
||||
const grades = ['초등학생', '중학생', '고등학생']
|
||||
const subjectImages: Record<string, string> = {
|
||||
'수학': `${baseUrl}/img/math-tutoring.png`,
|
||||
'영어': `${baseUrl}/img/english-tutoring.png`,
|
||||
'국어': `${baseUrl}/img/korean-tutoring.png`,
|
||||
'과학': `${baseUrl}/img/science-tutoring.png`,
|
||||
'사회': `${baseUrl}/img/social-studies-tutoring.png`
|
||||
}
|
||||
|
||||
let xml = `<?xml version="1.0" encoding="UTF-8"?>\n`
|
||||
xml += `<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">\n`
|
||||
|
||||
// 메인
|
||||
xml += ` <url>\n <loc>${baseUrl}/</loc>\n <lastmod>${today}</lastmod>\n <changefreq>daily</changefreq>\n <priority>1.0</priority>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/og-main.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/math-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/english-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/korean-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/science-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/social-studies-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` </url>\n`
|
||||
|
||||
// 중복 제거된 동별 주요 과목 및 학년 URL 생성 (슬래시 라우터 구조 통일)
|
||||
uniqueDongs.forEach(dong => {
|
||||
// 1. 동 대표
|
||||
xml += ` <url>\n <loc>${baseUrl}/${encodeURIComponent(dong)}</loc>\n <lastmod>${today}</lastmod>\n <changefreq>weekly</changefreq>\n <priority>0.8</priority>\n <image:image><image:loc>${baseUrl}/img/math-tutoring.png</image:loc></image:image>\n </url>\n`
|
||||
|
||||
// 2. 동/학년/과목 조합
|
||||
grades.forEach(g => {
|
||||
subjects.forEach(sub => {
|
||||
const imgLoc = subjectImages[sub] || `${baseUrl}/img/math-tutoring.png`
|
||||
xml += ` <url>\n <loc>${baseUrl}/${encodeURIComponent(dong)}/${encodeURIComponent(g)}/${encodeURIComponent(sub)}</loc>\n <lastmod>${today}</lastmod>\n <changefreq>weekly</changefreq>\n <priority>0.7</priority>\n <image:image><image:loc>${imgLoc}</image:loc></image:image>\n </url>\n`
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
xml += `</urlset>`
|
||||
|
||||
setHeader(event, 'content-type', 'application/xml; charset=utf-8')
|
||||
return xml
|
||||
})
|
||||
@@ -4,8 +4,11 @@ export default defineEventHandler((event) => {
|
||||
const config = useRuntimeConfig()
|
||||
const baseUrl = config.public.siteDomain || 'https://aeseo.site'
|
||||
const list = regionsData.list as Array<{ sido: string, sigungu: string, dong: string }>
|
||||
const uniqueDongs = Array.from(new Set(list.map(r => r.dong).filter(Boolean)))
|
||||
const today = new Date().toISOString().split('T')[0]
|
||||
|
||||
const subjects = ['수학', '영어', '국어', '과학', '사회']
|
||||
const grades = ['초등학생', '중학생', '고등학생']
|
||||
const subjectImages: Record<string, string> = {
|
||||
'수학': `${baseUrl}/img/math-tutoring.png`,
|
||||
'영어': `${baseUrl}/img/english-tutoring.png`,
|
||||
@@ -13,46 +16,30 @@ export default defineEventHandler((event) => {
|
||||
'과학': `${baseUrl}/img/science-tutoring.png`,
|
||||
'사회': `${baseUrl}/img/social-studies-tutoring.png`
|
||||
}
|
||||
const subjects = ['수학', '영어', '국어', '과학', '사회']
|
||||
const grades = ['초등학생', '중학생', '고등학생']
|
||||
|
||||
let xml = `<?xml version="1.0" encoding="UTF-8"?>\n`
|
||||
xml += `<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">\n`
|
||||
|
||||
// 메인 (대표 이미지 + 5대 과목 이미지 모두 포함)
|
||||
xml += ` <url>\n`
|
||||
xml += ` <loc>${baseUrl}/</loc>\n`
|
||||
xml += ` <lastmod>${today}</lastmod>\n`
|
||||
xml += ` <changefreq>daily</changefreq>\n`
|
||||
xml += ` <priority>1.0</priority>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/og-main.png</image:loc></image:image>\n`
|
||||
subjects.forEach(sub => {
|
||||
xml += ` <image:image><image:loc>${subjectImages[sub]}</image:loc></image:image>\n`
|
||||
})
|
||||
xml += ` </url>\n`
|
||||
|
||||
// 동별 주요 과목 및 학년 URL 생성
|
||||
list.forEach(r => {
|
||||
// 1. 동 대표
|
||||
xml += ` <url>\n`
|
||||
xml += ` <loc>${baseUrl}/${encodeURIComponent(r.dong)}</loc>\n`
|
||||
xml += ` <lastmod>${today}</lastmod>\n`
|
||||
xml += ` <changefreq>weekly</changefreq>\n`
|
||||
xml += ` <priority>0.8</priority>\n`
|
||||
// 메인
|
||||
xml += ` <url>\n <loc>${baseUrl}/</loc>\n <lastmod>${today}</lastmod>\n <changefreq>daily</changefreq>\n <priority>1.0</priority>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/og-main.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/math-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/english-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/korean-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/science-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` <image:image><image:loc>${baseUrl}/img/social-studies-tutoring.png</image:loc></image:image>\n`
|
||||
xml += ` </url>\n`
|
||||
|
||||
// 2. 동/학년/과목 대표 조합
|
||||
// 중복 제거된 동별 주요 과목 및 학년 URL 생성 (슬래시 라우터 구조 통일)
|
||||
uniqueDongs.forEach(dong => {
|
||||
// 1. 동 대표
|
||||
xml += ` <url>\n <loc>${baseUrl}/${encodeURIComponent(dong)}</loc>\n <lastmod>${today}</lastmod>\n <changefreq>weekly</changefreq>\n <priority>0.8</priority>\n <image:image><image:loc>${baseUrl}/img/math-tutoring.png</image:loc></image:image>\n </url>\n`
|
||||
|
||||
// 2. 동/학년/과목 조합
|
||||
grades.forEach(g => {
|
||||
subjects.forEach(sub => {
|
||||
xml += ` <url>\n`
|
||||
xml += ` <loc>${baseUrl}/${encodeURIComponent(r.dong)}/${encodeURIComponent(g)}/${encodeURIComponent(sub)}</loc>\n`
|
||||
xml += ` <lastmod>${today}</lastmod>\n`
|
||||
xml += ` <changefreq>weekly</changefreq>\n`
|
||||
xml += ` <priority>0.7</priority>\n`
|
||||
xml += ` <image:image><image:loc>${subjectImages[sub]}</image:loc></image:image>\n`
|
||||
xml += ` </url>\n`
|
||||
const imgLoc = subjectImages[sub] || `${baseUrl}/img/math-tutoring.png`
|
||||
xml += ` <url>\n <loc>${baseUrl}/${encodeURIComponent(dong)}/${encodeURIComponent(g)}/${encodeURIComponent(sub)}</loc>\n <lastmod>${today}</lastmod>\n <changefreq>weekly</changefreq>\n <priority>0.7</priority>\n <image:image><image:loc>${imgLoc}</image:loc></image:image>\n </url>\n`
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -113,30 +113,35 @@ export function parseRouteSlug(slugInput: string | string[]): ParsedRouteParams
|
||||
} else if (typeof slugInput === 'string' && slugInput.trim()) {
|
||||
tokens = decodeURIComponent(slugInput).split(/[-_\s/]+/)
|
||||
}
|
||||
tokens = tokens.map(t => t.trim()).filter(Boolean)
|
||||
tokens = tokens.map(t => t.trim()).filter(t => Boolean(t) && !/^index\.html?$/i.test(t))
|
||||
|
||||
let matchedRegion: RegionInfo | null = null
|
||||
let matchedTokenIdx = -1
|
||||
let detectedGrade = '중학생'
|
||||
let detectedGradeShort = '중등'
|
||||
let detectedSubjectKey = 'english'
|
||||
let detectedSubjectName = '영어'
|
||||
let detectedSubjectKey = 'math'
|
||||
let detectedSubjectName = '수학'
|
||||
let detectedTerm = '과외'
|
||||
|
||||
// 1. 토큰들 중 동 이름 매칭
|
||||
for (const token of tokens) {
|
||||
for (let i = 0; i < tokens.length; i++) {
|
||||
const token = tokens[i]
|
||||
const reg = getRegionByDong(token)
|
||||
if (reg) {
|
||||
matchedRegion = reg
|
||||
matchedTokenIdx = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 동 이름이 토큰에 없으면 전체 리스트에서 부분 일치 검색
|
||||
if (!matchedRegion && tokens.length > 0) {
|
||||
for (const token of tokens) {
|
||||
for (let i = 0; i < tokens.length; i++) {
|
||||
const token = tokens[i]
|
||||
const found = (regionsData.list as RegionInfo[]).find(r => token.includes(r.dong) || (token.length >= 2 && r.dong.includes(token)))
|
||||
if (found) {
|
||||
matchedRegion = found
|
||||
matchedTokenIdx = i
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -152,9 +157,10 @@ export function parseRouteSlug(slugInput: string | string[]): ParsedRouteParams
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 학년 추출
|
||||
// 3. 학년 추출 (동 이름 토큰을 제외한 나머지 토큰에서만 검색하여 '고등동', '문학동' 등 별칭 충돌 원천 차단)
|
||||
let hasExplicitGrade = false
|
||||
const fullText = tokens.join(' ')
|
||||
const remainingTokens = tokens.filter((_, idx) => idx !== matchedTokenIdx)
|
||||
const fullText = remainingTokens.join(' ')
|
||||
for (const g of GRADES_LIST) {
|
||||
if (g.aliases.some(a => fullText.includes(a))) {
|
||||
detectedGrade = g.name
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { ParsedRouteParams } from './dataHelper'
|
||||
import { getShortRegionName } from './dataHelper'
|
||||
import { getShortRegionName, getShortSido } from './dataHelper'
|
||||
|
||||
const SUBJECT_IMAGE_MAP: Record<string, string> = {
|
||||
math: '/img/math-tutoring.png',
|
||||
@@ -22,18 +22,23 @@ const GRADE_LIST = ['초등학생', '중학생', '고등학생']
|
||||
export function generateSeoMeta(parsed: ParsedRouteParams, siteName = '튜터온', siteDomain = 'https://aeseo.site') {
|
||||
const { sido, sigungu, dong, shortRegionName, grade, subjectKey, subjectName, isRegionOnly } = parsed
|
||||
|
||||
const shortSido = (sido || '').replace(/특별시|광역시|특별자치시|도/g, '').trim() || '인천'
|
||||
const shortSido = getShortSido(sido) || '인천'
|
||||
const gradeShort = parsed.gradeShort || (grade === '초등학생' ? '초등' : grade === '고등학생' ? '고등' : '중등')
|
||||
const regionTitle = shortRegionName || getShortRegionName(sido, dong)
|
||||
const regionTitle = shortRegionName || getShortRegionName(sido, dong, sigungu)
|
||||
const subjectImg = SUBJECT_IMAGE_MAP[subjectKey] || '/img/math-tutoring.png'
|
||||
|
||||
const dongHash = Array.from(dong || '').reduce((acc, ch) => acc + ch.charCodeAt(0), 0)
|
||||
const baseSubjects = ['수학', '영어', '국어', '과학', '사회']
|
||||
const rotatedSubjects = baseSubjects.map((_, i) => baseSubjects[(dongHash + i) % baseSubjects.length])
|
||||
const rotatedSubText = rotatedSubjects.map(s => `${dong}${s}과외선생님`).join(', ')
|
||||
|
||||
const pageTitle = isRegionOnly
|
||||
? `${shortSido} 중등 수학 과외 · ${shortSido} 중등 과외 | ${regionTitle} 초·중·고 1:1 맞춤 과외`
|
||||
: `${shortSido} ${gradeShort} ${subjectName} 과외 · ${regionTitle} ${grade} ${subjectName}과외 | ${shortSido} ${gradeShort} 과외 1:1 매칭`
|
||||
|
||||
const pageDescription = isRegionOnly
|
||||
? `${shortSido} 중등 수학 과외, ${shortSido} 중등 과외, ${dong} 중등 수학 과외 전문 ${siteName}! ${regionTitle} 초등·중등·고등 국영수사과 1:1 맞춤 과외와 검증된 전문 선생님 무료 시범수업, 과외비 비교를 확인하세요.`
|
||||
: `${shortSido} ${gradeShort} ${subjectName} 과외, ${shortSido} ${gradeShort} 과외, ${dong} ${gradeShort} ${subjectName} 과외 전문 ${siteName}! ${regionTitle} ${grade} ${subjectName} 1:1 방문·화상 맞춤 수업으로 내신·수능 성적 향상을 책임집니다. 과외비 투명 공개 및 무료 시범수업 신청하세요.`
|
||||
? `${shortSido} 중등 수학 과외, ${shortSido} 중등 과외, ${dong} 중등 수학 과외 전문 ${siteName}! ${regionTitle} 초등·중등·고등 국영수사과 1:1 맞춤 과외와 검증된 전문 선생님 무료 시범수업, 과외비 비교(${rotatedSubText})를 확인하세요.`
|
||||
: `${shortSido} ${gradeShort} ${subjectName} 과외, ${shortSido} ${gradeShort} 과외, ${dong} ${gradeShort} ${subjectName} 과외 전문 ${siteName}! ${regionTitle} ${grade} ${subjectName} 1:1 방문·화상 맞춤 수업으로 내신·수능 성적 향상을 책임집니다. 과외비 투명 공개 및 무료 시범수업(${rotatedSubText})을 신청하세요.`
|
||||
|
||||
const dongUrl = `${siteDomain}/${encodeURIComponent(dong)}`
|
||||
const canonicalUrl = isRegionOnly
|
||||
|
||||
+122
-32
@@ -1,16 +1,42 @@
|
||||
<template>
|
||||
<footer class="site-footer">
|
||||
<footer class="royal-footer">
|
||||
<div class="footer-gold-divider"></div>
|
||||
<div class="footer-container">
|
||||
<div class="footer-info">
|
||||
<h4 class="footer-brand">{{ siteName }}</h4>
|
||||
<!-- 1열: ROYAL CLASS 브랜드 -->
|
||||
<div class="footer-col brand-col">
|
||||
<div class="flex items-center gap-2 mb-2.5">
|
||||
<i class="fa-solid fa-crown text-[#d4b068] text-sm"></i>
|
||||
<h4 class="footer-brand font-royal-serif">ROYAL CLASS</h4>
|
||||
</div>
|
||||
<p class="footer-meta">
|
||||
초·중·고 1:1 맞춤 방문과외 및 실시간 화상코칭 서비스 | 대표번호: 010-5961-5807
|
||||
</p>
|
||||
<p class="footer-copy">
|
||||
Copyright © 2026 {{ siteName }}. All rights reserved.
|
||||
{{ siteName }}는 서울 1%를 위한 프리미엄 1:1 맞춤 방문과외 및 실시간 화상 코칭 서비스를 제공합니다.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- 2열: Contact Number -->
|
||||
<div class="footer-col contact-col">
|
||||
<span class="footer-col-label">Contact Number</span>
|
||||
<a href="tel:010-5961-5807" class="footer-phone">
|
||||
<i class="fa-solid fa-phone text-[#d4b068] text-base mr-2"></i>
|
||||
<span>010-5961-5807</span>
|
||||
</a>
|
||||
<p class="footer-hours">연중무휴 학습진단 및 시범수업 상담 (09:00 ~ 23:00)</p>
|
||||
</div>
|
||||
|
||||
<!-- 3열: Official Company Info -->
|
||||
<div class="footer-col info-col">
|
||||
<span class="footer-col-label">Official Company Info</span>
|
||||
<ul class="footer-info-list">
|
||||
<li>서비스명: {{ siteName }} (교육청 등록 협력)</li>
|
||||
<li>직통번호: 010-5961-5807</li>
|
||||
<li>서울 본원: 서울특별시 강남구 테헤란로 123 비전타워 4층</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="footer-bottom">
|
||||
<div class="footer-bottom-inner">
|
||||
<p class="footer-copy">Copyright © {{ siteName }}. All rights reserved.</p>
|
||||
<div class="footer-links">
|
||||
<a href="#consult-section" class="f-link">무료상담신청</a>
|
||||
<span class="f-divider">|</span>
|
||||
@@ -19,6 +45,7 @@
|
||||
<span class="f-link"><strong>개인정보처리방침</strong></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</template>
|
||||
|
||||
@@ -28,64 +55,127 @@ const siteName = config.public.siteName || '로열클래스 1:1 과외'
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.site-footer {
|
||||
background: var(--footer-bg, #0f172a);
|
||||
.royal-footer {
|
||||
background: #0c121e;
|
||||
color: #94a3b8;
|
||||
padding: clamp(30px, 5vw, 50px) 16px;
|
||||
font-size: clamp(0.72rem, 1.8vw, 0.82rem);
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.08);
|
||||
position: relative;
|
||||
font-size: 0.82rem;
|
||||
}
|
||||
|
||||
.footer-gold-divider {
|
||||
height: 1px;
|
||||
width: 100%;
|
||||
background: linear-gradient(90deg, transparent 0%, rgba(212, 176, 104, 0.45) 50%, transparent 100%);
|
||||
}
|
||||
|
||||
.footer-container {
|
||||
max-width: 1080px;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
gap: 24px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.footer-info {
|
||||
flex: 1 1 500px;
|
||||
padding: clamp(36px, 5vw, 56px) 20px clamp(28px, 4vw, 40px);
|
||||
display: grid;
|
||||
grid-template-columns: 1.3fr 1fr 1.2fr;
|
||||
gap: 32px;
|
||||
}
|
||||
|
||||
.footer-brand {
|
||||
font-size: clamp(1rem, 2.4vw, 1.15rem);
|
||||
font-size: 1.2rem;
|
||||
font-weight: 800;
|
||||
color: #ffffff;
|
||||
margin-bottom: 8px;
|
||||
letter-spacing: 0.12em;
|
||||
color: #e2c687;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.footer-meta {
|
||||
line-height: 1.6;
|
||||
margin-bottom: 12px;
|
||||
color: #94a3b8;
|
||||
line-height: 1.65;
|
||||
word-break: keep-all;
|
||||
}
|
||||
|
||||
.footer-col-label {
|
||||
display: block;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
color: #cbd5e1;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.footer-phone {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
font-size: 1.35rem;
|
||||
font-weight: 900;
|
||||
color: #ffffff;
|
||||
text-decoration: none;
|
||||
letter-spacing: 0.02em;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.footer-phone:hover {
|
||||
color: #e2c687;
|
||||
}
|
||||
|
||||
.footer-hours {
|
||||
font-size: 0.76rem;
|
||||
color: #64748b;
|
||||
}
|
||||
|
||||
.footer-info-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
color: #94a3b8;
|
||||
font-size: 0.78rem;
|
||||
}
|
||||
|
||||
.footer-bottom {
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.07);
|
||||
padding: 18px 20px;
|
||||
}
|
||||
|
||||
.footer-bottom-inner {
|
||||
max-width: 1080px;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.footer-copy {
|
||||
color: #64748b;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
.footer-links {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.f-link {
|
||||
color: #cbd5e1;
|
||||
color: #94a3b8;
|
||||
text-decoration: none;
|
||||
font-size: 0.76rem;
|
||||
}
|
||||
|
||||
.f-link:hover {
|
||||
color: #e2c687;
|
||||
}
|
||||
|
||||
.f-divider {
|
||||
color: #475569;
|
||||
color: #334155;
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
@media (max-width: 768px) {
|
||||
.footer-container {
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 24px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,26 +1,50 @@
|
||||
<template>
|
||||
<header class="bg-white/95 backdrop-blur-md border-b border-slate-200/80 sticky top-0 z-40 w-full transition-all">
|
||||
<div class="max-w-6xl mx-auto px-4 sm:px-6 py-3.5 flex items-center justify-between">
|
||||
<NuxtLink to="/" class="flex items-center gap-3 no-underline">
|
||||
<div class="w-9 h-9 rounded-xl bg-blue-600 flex items-center justify-center text-white font-extrabold text-base shadow-sm">
|
||||
{{ logoLetter }}
|
||||
<header class="royal-header sticky top-0 z-50 w-full">
|
||||
<!-- 상단 골드 헤어라인 -->
|
||||
<div class="gold-top-line"></div>
|
||||
|
||||
<div class="max-w-6xl mx-auto px-4 sm:px-6 py-3 flex items-center justify-between">
|
||||
<!-- 좌측: 네비게이션 메뉴 (참고 시안 그대로 배치) -->
|
||||
<nav class="hidden md:flex items-center gap-6 text-xs lg:text-sm font-medium text-slate-300" aria-label="주요 메뉴">
|
||||
<NuxtLink to="/" class="nav-item hover:text-[#e2c687] transition no-underline">홈</NuxtLink>
|
||||
<NuxtLink :to="isHome ? '#usp-section' : '/#usp-section'" class="nav-item hover:text-[#e2c687] transition no-underline">특장점</NuxtLink>
|
||||
<a href="#tutor-section" class="nav-item hover:text-[#e2c687] transition no-underline">강사진</a>
|
||||
<a href="#process-section" class="nav-item hover:text-[#e2c687] transition no-underline">프로세스</a>
|
||||
<a href="#stories-section" class="nav-item hover:text-[#e2c687] transition no-underline">성공사례</a>
|
||||
</nav>
|
||||
|
||||
<!-- 모바일용 좌측 전화 아이콘 -->
|
||||
<a href="tel:010-5961-5807" class="md:hidden inline-flex items-center gap-1.5 text-xs font-semibold text-[#e2c687] no-underline">
|
||||
<i class="fa-solid fa-phone"></i>
|
||||
<span>상담직통</span>
|
||||
</a>
|
||||
|
||||
<!-- 중앙: 왕관 엠블럼 & ROYAL CLASS 로열클래스 로고 -->
|
||||
<NuxtLink to="/" class="emblem-link flex flex-col items-center justify-center text-center no-underline group">
|
||||
<div class="crown-icon-wrap flex items-center justify-center mb-0.5">
|
||||
<i class="fa-solid fa-crown text-[#d4b068] text-base sm:text-lg drop-shadow"></i>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-extrabold text-lg sm:text-xl tracking-tight text-slate-900">{{ currentSiteName }}</span>
|
||||
<span class="hidden sm:inline-flex items-center text-[11px] font-semibold text-blue-700 bg-blue-50 px-2.5 py-0.5 rounded-full border border-blue-100">
|
||||
교육청 등록 협력
|
||||
<span class="font-royal-serif text-[11px] sm:text-xs font-bold tracking-[0.22em] text-[#e2c687] leading-none">
|
||||
ROYAL CLASS
|
||||
</span>
|
||||
<span class="text-[11px] sm:text-xs font-extrabold text-white/90 tracking-widest mt-0.5">
|
||||
{{ currentSiteName }}
|
||||
</span>
|
||||
</div>
|
||||
</NuxtLink>
|
||||
|
||||
<div class="flex items-center gap-4">
|
||||
<a href="tel:010-5961-5807" class="hidden sm:flex items-center gap-1.5 text-sm font-semibold text-slate-600 hover:text-blue-600 transition no-underline">
|
||||
<i class="fa-solid fa-phone text-blue-600 text-xs"></i>
|
||||
<span>010-5961-5807</span>
|
||||
<!-- 우측: 상담신청 텍스트 링크 + 골드 필 버튼 -->
|
||||
<div class="flex items-center gap-3 sm:gap-5">
|
||||
<a
|
||||
href="tel:010-5961-5807"
|
||||
class="hidden sm:inline-flex items-center gap-1.5 text-xs sm:text-sm font-semibold text-slate-200 hover:text-[#e2c687] transition no-underline"
|
||||
>
|
||||
<span>상담신청</span>
|
||||
</a>
|
||||
<a href="#consult-section" class="bg-blue-600 hover:bg-blue-700 text-white text-xs sm:text-sm font-bold px-4 sm:px-5 py-2.5 rounded-xl transition shadow-sm hover:shadow flex items-center gap-1.5 no-underline">
|
||||
<span>무료 시범수업 신청</span>
|
||||
<i class="fa-solid fa-arrow-right text-[11px]"></i>
|
||||
<a
|
||||
:href="consultHref"
|
||||
class="gold-cta-btn text-xs sm:text-sm font-extrabold px-4 sm:px-5 py-2 sm:py-2.5 rounded-lg transition shadow-md flex items-center gap-1.5 no-underline"
|
||||
>
|
||||
<span>무료 상담 신청</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -34,22 +58,43 @@ const props = defineProps({
|
||||
siteName: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
consultHref: {
|
||||
type: String,
|
||||
default: '#consult-section'
|
||||
}
|
||||
})
|
||||
|
||||
const config = useRuntimeConfig()
|
||||
const route = useRoute()
|
||||
const isHome = computed(() => route.path === '/')
|
||||
const currentSiteName = computed(() => {
|
||||
return props.siteName || config.public?.siteName || '1:1 맞춤과외'
|
||||
})
|
||||
|
||||
const logoLetter = computed(() => {
|
||||
const name = currentSiteName.value.trim()
|
||||
return name.charAt(0) || 'T'
|
||||
return props.siteName || config.public?.siteName || '로열클래스 1:1 과외'
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
header {
|
||||
font-family: inherit;
|
||||
.royal-header {
|
||||
background: linear-gradient(180deg, #0d1424 0%, #121c31 100%);
|
||||
border-bottom: 1px solid rgba(212, 176, 104, 0.25);
|
||||
box-shadow: 0 6px 24px rgba(0, 0, 0, 0.28);
|
||||
}
|
||||
|
||||
.gold-top-line {
|
||||
height: 2px;
|
||||
width: 100%;
|
||||
background: linear-gradient(90deg, rgba(201, 165, 92, 0.2) 0%, #e2c687 50%, rgba(201, 165, 92, 0.2) 100%);
|
||||
}
|
||||
|
||||
.gold-cta-btn {
|
||||
background: linear-gradient(135deg, #e2c687 0%, #c49b50 100%);
|
||||
color: #0d1424;
|
||||
border: 1px solid #ebd5a4;
|
||||
}
|
||||
|
||||
.gold-cta-btn:hover {
|
||||
background: linear-gradient(135deg, #ebd5a4 0%, #d4ab60 100%);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 6px 16px rgba(201, 165, 92, 0.35);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -220,21 +220,22 @@ const resetForm = () => {
|
||||
<style scoped>
|
||||
.consult-section {
|
||||
width: 100%;
|
||||
padding: clamp(35px, 6vw, 65px) 16px;
|
||||
padding: clamp(48px, 6vw, 76px) 16px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background: transparent;
|
||||
background: #10192b;
|
||||
border-top: 2px solid #c9a55c;
|
||||
}
|
||||
|
||||
.consult-card {
|
||||
width: 100%;
|
||||
max-width: 580px;
|
||||
max-width: 600px;
|
||||
background: #ffffff;
|
||||
border: 1px solid #e2e8f0;
|
||||
border-radius: 14px;
|
||||
box-shadow: 0 10px 30px rgba(15, 23, 42, 0.08);
|
||||
padding: clamp(24px, 5vw, 40px) clamp(20px, 4vw, 36px);
|
||||
border: 2px solid #d4b068;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 18px 40px rgba(0, 0, 0, 0.35);
|
||||
padding: clamp(26px, 5vw, 42px) clamp(20px, 4vw, 38px);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@@ -365,20 +366,20 @@ const resetForm = () => {
|
||||
padding: 16px 20px;
|
||||
font-size: 1.08rem;
|
||||
font-weight: 800;
|
||||
color: #ffffff;
|
||||
background: #1e3a8a;
|
||||
border: none;
|
||||
color: #0d1424;
|
||||
background: linear-gradient(135deg, #e5c889 0%, #c49b50 100%);
|
||||
border: 1px solid #f2dfb3;
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
letter-spacing: -0.3px;
|
||||
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
|
||||
box-shadow: 0 4px 14px rgba(196, 155, 80, 0.3);
|
||||
}
|
||||
|
||||
.btn-submit:hover:not(:disabled) {
|
||||
background: #0f172a;
|
||||
background: linear-gradient(135deg, #f0d79e 0%, #d4ab5f 100%);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.16);
|
||||
box-shadow: 0 6px 18px rgba(196, 155, 80, 0.45);
|
||||
}
|
||||
|
||||
.btn-submit:disabled {
|
||||
@@ -393,9 +394,9 @@ const resetForm = () => {
|
||||
font-size: 1.02rem;
|
||||
font-weight: 800;
|
||||
text-align: center;
|
||||
color: #1e3a8a;
|
||||
background: #f8fafc;
|
||||
border: 2px solid #1e3a8a;
|
||||
color: #10192b;
|
||||
background: #fbf8f3;
|
||||
border: 2px solid #10192b;
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
@@ -405,7 +406,7 @@ const resetForm = () => {
|
||||
}
|
||||
|
||||
.btn-call:hover {
|
||||
background: #f1f5f9;
|
||||
background: #f4ece0;
|
||||
}
|
||||
|
||||
.success-box {
|
||||
|
||||
+144
-59
@@ -1,21 +1,32 @@
|
||||
<template>
|
||||
<section class="hero-banner hero-banner-clean bg-white border-b border-slate-200/80 pt-10 sm:pt-14 pb-14 sm:pb-18 px-4 sm:px-6 relative overflow-hidden text-center" itemscope itemtype="https://schema.org/Course">
|
||||
<section class="royal-sub-hero relative overflow-hidden text-center" itemscope itemtype="https://schema.org/Course">
|
||||
|
||||
<!-- 은은한 상단 엠비언트 라이트 -->
|
||||
<div class="absolute inset-0 bg-gradient-to-b from-blue-50/40 via-transparent to-transparent pointer-events-none"></div>
|
||||
<!-- 배경: 서울 통창 스카이라인 라운지 이미지 & 다크 네이비 오버레이 -->
|
||||
<div class="hero-bg-wrap">
|
||||
<img
|
||||
src="/img/hero-seoul-bg.jpg"
|
||||
:alt="`${shortSidoName} ${gradeShortName} ${subjectName} 과외 · ${region.dong} ${grade} ${subjectName}과외 스터디 라운지`"
|
||||
class="hero-bg-img"
|
||||
width="1920"
|
||||
height="1080"
|
||||
decoding="async"
|
||||
fetchpriority="high"
|
||||
/>
|
||||
<div class="hero-bg-overlay"></div>
|
||||
</div>
|
||||
|
||||
<div class="max-w-4xl mx-auto relative z-10">
|
||||
<div class="max-w-4xl mx-auto relative z-10 px-4 sm:px-6 pt-12 sm:pt-16 pb-16 sm:pb-20">
|
||||
|
||||
<!-- 신뢰 보증 뱃지 -->
|
||||
<div class="inline-flex items-center gap-2 px-3.5 py-1.5 rounded-full text-xs font-semibold bg-slate-50 border border-slate-200 text-slate-700 shadow-xs mb-5">
|
||||
<span class="w-2 h-2 rounded-full bg-blue-600"></span>
|
||||
<!-- 신뢰 보증 크라운 뱃지 -->
|
||||
<div class="inline-flex items-center gap-2 px-4 py-1.5 rounded-full text-xs font-bold bg-[#10192b]/85 border border-[#c9a55c]/50 text-[#e2c687] shadow-md mb-5 backdrop-blur-xs">
|
||||
<i class="fa-solid fa-crown text-[#d4b068] text-xs"></i>
|
||||
<span>{{ region.dong }} 학군 전담 | 서울대·연고대 및 베테랑 강사진 100% 신원 보증</span>
|
||||
</div>
|
||||
|
||||
<!-- 네이버 상위 노출 순서: 1. H1 ➔ 2. meta ➔ 3. H2 ➔ 4. 일반글 P -->
|
||||
<h1 itemprop="headline" class="text-2xl sm:text-4xl md:text-5xl font-extrabold tracking-tight text-slate-900 leading-[1.22] sm:leading-[1.18] mb-3">
|
||||
<span class="highlight text-blue-600">{{ shortSidoName }} {{ gradeShortName }} {{ subjectName }} 과외 · {{ region.dong }} {{ grade }} {{ subjectName }}과외</span><br />
|
||||
1:1 맞춤 학습으로 성적 역전!
|
||||
<h1 itemprop="headline" class="text-2xl sm:text-4xl md:text-5xl font-extrabold tracking-tight text-white leading-[1.24] sm:leading-[1.2] mb-3">
|
||||
<span class="gold-gradient-text font-royal-serif">{{ shortSidoName }} {{ gradeShortName }} {{ subjectName }} 과외 · {{ region.dong }} {{ grade }} {{ subjectName }}과외</span><br />
|
||||
<span class="text-white">1:1 맞춤 학습으로 성적 역전!</span>
|
||||
</h1>
|
||||
<meta itemprop="name" :content="`${shortSidoName} ${gradeShortName} ${subjectName} 과외 · ${shortSidoName} ${gradeShortName} 과외 (${region.dong})`" />
|
||||
<meta itemprop="description" :content="`${shortSidoName} ${gradeShortName} ${subjectName} 과외 및 ${shortSidoName} ${gradeShortName} 과외 전문 매칭. ${displayRegionName} ${grade} ${subjectName} 1:1 방문·화상 맞춤 수업`" />
|
||||
@@ -24,75 +35,80 @@
|
||||
<h2 class="hero-subtitle">
|
||||
{{ shortSidoName }} {{ gradeShortName }} 과외 · {{ displayRegionName }} {{ gradeShortName }} {{ subjectName }} 과외 검증된 전문 선생님 1:1 매칭
|
||||
</h2>
|
||||
<p class="sub-headline text-xs sm:text-base text-slate-600 font-normal max-w-2xl mx-auto leading-relaxed mb-7">
|
||||
<p class="sub-headline text-xs sm:text-base text-slate-200/90 font-normal max-w-2xl mx-auto leading-relaxed mb-7">
|
||||
{{ shortSidoName }} {{ gradeShortName }} {{ subjectName }} 과외 및 {{ shortSidoName }} {{ gradeShortName }} 과외를 찾으시는 학부모님을 위해 {{ region.dong }} 인근 학교별 기출 족보 분석부터 개인별 취약 개념 완벽 보완, 투명한 과외비 안내와 무료 시범수업까지 1:1 밀착 커리큘럼을 제공합니다.
|
||||
</p>
|
||||
|
||||
<!-- 4대 핵심 신뢰 지표 바 -->
|
||||
<!-- 4대 핵심 신뢰 지표 바 (다크 글래스 & 골드 보더) -->
|
||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-2.5 sm:gap-3 max-w-3xl mx-auto mb-7 text-left">
|
||||
<div class="bg-slate-50 border border-slate-200/90 rounded-xl p-3 flex items-start gap-2.5">
|
||||
<i class="fa-solid fa-circle-check text-blue-600 text-sm sm:text-base mt-0.5 shrink-0"></i>
|
||||
<div class="trust-glass-card">
|
||||
<i class="fa-solid fa-circle-check text-[#e2c687] text-sm sm:text-base mt-0.5 shrink-0"></i>
|
||||
<div>
|
||||
<strong class="block text-xs sm:text-sm font-bold text-slate-900">100% 서류 검증</strong>
|
||||
<span class="text-[11px] text-slate-500 leading-tight">학력·경력 증명서 인증</span>
|
||||
<strong class="block text-xs sm:text-sm font-bold text-white">100% 서류 검증</strong>
|
||||
<span class="text-[11px] text-slate-300 leading-tight">학력·경력 증명서 인증</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-slate-50 border border-slate-200/90 rounded-xl p-3 flex items-start gap-2.5">
|
||||
<i class="fa-solid fa-circle-check text-blue-600 text-sm sm:text-base mt-0.5 shrink-0"></i>
|
||||
<div class="trust-glass-card">
|
||||
<i class="fa-solid fa-circle-check text-[#e2c687] text-sm sm:text-base mt-0.5 shrink-0"></i>
|
||||
<div>
|
||||
<strong class="block text-xs sm:text-sm font-bold text-slate-900">무료 시범수업</strong>
|
||||
<span class="text-[11px] text-slate-500 leading-tight">직접 받아보고 선택</span>
|
||||
<strong class="block text-xs sm:text-sm font-bold text-white">무료 시범수업</strong>
|
||||
<span class="text-[11px] text-slate-300 leading-tight">직접 받아보고 선택</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-slate-50 border border-slate-200/90 rounded-xl p-3 flex items-start gap-2.5">
|
||||
<i class="fa-solid fa-circle-check text-blue-600 text-sm sm:text-base mt-0.5 shrink-0"></i>
|
||||
<div class="trust-glass-card">
|
||||
<i class="fa-solid fa-circle-check text-[#e2c687] text-sm sm:text-base mt-0.5 shrink-0"></i>
|
||||
<div>
|
||||
<strong class="block text-xs sm:text-sm font-bold text-slate-900">과외 비용 투명 시세</strong>
|
||||
<span class="text-[11px] text-slate-500 leading-tight">동네 표준 시세 가이드</span>
|
||||
<strong class="block text-xs sm:text-sm font-bold text-white">과외 비용 투명 시세</strong>
|
||||
<span class="text-[11px] text-slate-300 leading-tight">동네 표준 시세 가이드</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-slate-50 border border-slate-200/90 rounded-xl p-3 flex items-start gap-2.5">
|
||||
<i class="fa-solid fa-circle-check text-blue-600 text-sm sm:text-base mt-0.5 shrink-0"></i>
|
||||
<div class="trust-glass-card">
|
||||
<i class="fa-solid fa-circle-check text-[#e2c687] text-sm sm:text-base mt-0.5 shrink-0"></i>
|
||||
<div>
|
||||
<strong class="block text-xs sm:text-sm font-bold text-slate-900">학교별 기출 분석</strong>
|
||||
<span class="text-[11px] text-slate-500 leading-tight">{{ region.dong }} 3개년 족보 완파</span>
|
||||
<strong class="block text-xs sm:text-sm font-bold text-white">학교별 기출 분석</strong>
|
||||
<span class="text-[11px] text-slate-300 leading-tight">{{ region.dong }} 3개년 족보 완파</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- CTA 그룹 -->
|
||||
<!-- 시안 스타일 듀얼 CTA 버튼 그룹 -->
|
||||
<div class="flex flex-col items-center gap-3.5 mb-6">
|
||||
<div class="flex items-center justify-center gap-3 flex-wrap w-full">
|
||||
<a
|
||||
href="#consult-section"
|
||||
class="inline-flex items-center justify-center gap-2 w-full max-w-md py-4 px-6 bg-blue-600 hover:bg-blue-700 text-white font-extrabold text-sm sm:text-base rounded-xl shadow-md hover:shadow-lg transition-all"
|
||||
class="btn-hero-gold inline-flex items-center justify-center gap-2 py-3.5 px-7 font-extrabold text-sm sm:text-base rounded-lg shadow-lg transition-all no-underline"
|
||||
>
|
||||
<i class="fa-solid fa-file-signature text-base"></i>
|
||||
<span>{{ region.dong }} 과외 시세 확인 & 무료 시범수업 신청</span>
|
||||
<i class="fa-solid fa-crown text-sm"></i>
|
||||
<span>{{ region.dong }} 무료 시범수업 신청</span>
|
||||
</a>
|
||||
<a
|
||||
href="tel:010-5961-5807"
|
||||
class="btn-hero-outline inline-flex items-center justify-center gap-2 py-3.5 px-6 font-bold text-sm sm:text-base rounded-lg transition-all no-underline"
|
||||
>
|
||||
<i class="fa-solid fa-phone text-xs text-[#e2c687]"></i>
|
||||
<span>전화 상담 010-5961-5807</span>
|
||||
</a>
|
||||
<div class="flex items-center gap-2 text-xs sm:text-sm text-slate-500">
|
||||
<i class="fa-solid fa-phone text-blue-600 text-xs"></i>
|
||||
<span>실시간 학습상담 직통: <strong class="text-slate-800 font-bold">010-5961-5807</strong></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 실시간 접수 롤링 바 -->
|
||||
<div class="inline-flex items-center gap-2.5 bg-slate-100/90 border border-slate-200/80 rounded-full px-4 py-1.5 text-xs text-slate-600 shadow-xs mb-6">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-emerald-500 animate-pulse"></span>
|
||||
<span class="font-bold text-slate-700">실시간 매칭</span>
|
||||
<span class="text-slate-300">|</span>
|
||||
<span class="truncate max-w-[260px] sm:max-w-md font-medium text-slate-600">{{ currentNotice }}</span>
|
||||
<div class="inline-flex items-center gap-2.5 bg-[#0a101d]/80 border border-[#c9a55c]/40 rounded-full px-4 py-1.5 text-xs text-slate-200 shadow-md mb-6">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-[#e2c687] animate-pulse"></span>
|
||||
<span class="font-bold text-[#e2c687]">실시간 매칭</span>
|
||||
<span class="text-slate-500">|</span>
|
||||
<span class="truncate max-w-[250px] sm:max-w-md font-medium text-slate-200">{{ currentNotice }}</span>
|
||||
</div>
|
||||
|
||||
<!-- 태그 목록 -->
|
||||
<div class="flex justify-center flex-wrap gap-1.5">
|
||||
<span class="text-[11px] px-2.5 py-1 bg-slate-100 border border-slate-200 text-slate-600 rounded-md font-medium">#{{ shortSidoName }}{{ gradeShortName }}{{ subjectName }}과외</span>
|
||||
<span class="text-[11px] px-2.5 py-1 bg-slate-100 border border-slate-200 text-slate-600 rounded-md font-medium">#{{ shortSidoName }}{{ gradeShortName }}과외</span>
|
||||
<span class="text-[11px] px-2.5 py-1 bg-slate-100 border border-slate-200 text-slate-600 rounded-md font-medium">#{{ region.dong }}과외</span>
|
||||
<span class="text-[11px] px-2.5 py-1 bg-slate-100 border border-slate-200 text-slate-600 rounded-md font-medium">#{{ region.dong }}{{ subjectName }}과외</span>
|
||||
<span class="text-[11px] px-2.5 py-1 bg-slate-100 border border-slate-200 text-slate-600 rounded-md font-medium">#1대1무료시범수업</span>
|
||||
<span class="hero-tag">#{{ shortSidoName }}{{ gradeShortName }}{{ subjectName }}과외</span>
|
||||
<span class="hero-tag">#{{ shortSidoName }}{{ gradeShortName }}과외</span>
|
||||
<span class="hero-tag">#{{ region.dong }}과외</span>
|
||||
<span class="hero-tag">#{{ region.dong }}{{ subjectName }}과외</span>
|
||||
<span class="hero-tag">#로열클래스1대1과외</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -101,6 +117,7 @@
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted, onUnmounted } from 'vue'
|
||||
import { getShortSido } from '../utils/dataHelper'
|
||||
|
||||
const props = defineProps({
|
||||
region: {
|
||||
@@ -126,7 +143,7 @@ const props = defineProps({
|
||||
})
|
||||
|
||||
const shortSidoName = computed(() => {
|
||||
const s = (props.region?.sido || '').replace(/특별시|광역시|특별자치시|도/g, '').trim()
|
||||
const s = getShortSido(props.region?.sido || '')
|
||||
return s || '서울'
|
||||
})
|
||||
|
||||
@@ -168,16 +185,7 @@ const displayRegionName = computed(() => {
|
||||
const sido = props.region.sido || ''
|
||||
const dong = props.region.dong || ''
|
||||
if (sido && dong) {
|
||||
let shortSido = sido.slice(0, 2)
|
||||
if (sido.includes('서울')) shortSido = '서울'
|
||||
else if (sido.includes('대구')) shortSido = '대구'
|
||||
else if (sido.includes('부산')) shortSido = '부산'
|
||||
else if (sido.includes('인천')) shortSido = '인천'
|
||||
else if (sido.includes('광주')) shortSido = '광주'
|
||||
else if (sido.includes('대전')) shortSido = '대전'
|
||||
else if (sido.includes('울산')) shortSido = '울산'
|
||||
else if (sido.includes('경기')) shortSido = '경기'
|
||||
return `${shortSido} ${dong}`
|
||||
return `${getShortSido(sido) || '서울'} ${dong}`
|
||||
}
|
||||
return dong || sido
|
||||
}
|
||||
@@ -186,15 +194,92 @@ const displayRegionName = computed(() => {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.hero-banner-clean {
|
||||
.royal-sub-hero {
|
||||
background-color: #0d1424;
|
||||
border-bottom: 2px solid #c9a55c;
|
||||
word-break: keep-all;
|
||||
}
|
||||
|
||||
.hero-bg-wrap {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.hero-bg-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
}
|
||||
|
||||
.hero-bg-overlay {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
rgba(10, 16, 29, 0.76) 0%,
|
||||
rgba(16, 25, 43, 0.72) 50%,
|
||||
rgba(10, 16, 29, 0.9) 100%
|
||||
);
|
||||
}
|
||||
|
||||
.gold-gradient-text {
|
||||
background: linear-gradient(180deg, #f9ebb9 0%, #DFB970 50%, #c19344 100%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.5));
|
||||
}
|
||||
|
||||
.hero-subtitle {
|
||||
font-size: 1.15rem;
|
||||
font-size: 1.1rem;
|
||||
font-weight: 700;
|
||||
color: #334155;
|
||||
color: #ebd5a4;
|
||||
margin-bottom: 0.75rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.trust-glass-card {
|
||||
background: rgba(16, 25, 43, 0.75);
|
||||
border: 1px solid rgba(201, 165, 92, 0.4);
|
||||
border-radius: 12px;
|
||||
padding: 12px;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
backdrop-filter: blur(4px);
|
||||
}
|
||||
|
||||
.btn-hero-gold {
|
||||
background: linear-gradient(135deg, #e5c889 0%, #c49b50 100%);
|
||||
color: #0d1424;
|
||||
border: 1px solid #f2dfb3;
|
||||
}
|
||||
|
||||
.btn-hero-gold:hover {
|
||||
background: linear-gradient(135deg, #f0d79e 0%, #d4ab5f 100%);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.btn-hero-outline {
|
||||
background: rgba(16, 25, 43, 0.72);
|
||||
color: #f3e4be;
|
||||
border: 1.5px solid #c9a55c;
|
||||
backdrop-filter: blur(6px);
|
||||
}
|
||||
|
||||
.btn-hero-outline:hover {
|
||||
background: rgba(201, 165, 92, 0.22);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.hero-tag {
|
||||
font-size: 11px;
|
||||
padding: 4px 10px;
|
||||
background: rgba(16, 25, 43, 0.8);
|
||||
border: 1px solid rgba(201, 165, 92, 0.35);
|
||||
color: #e2c687;
|
||||
border-radius: 6px;
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 2. 같은 동의 다른 학년 링크 -->
|
||||
<!-- 2. 같은 동의 다른 학년 링크 및 동 대표 링크 -->
|
||||
<div class="hub-card">
|
||||
<div class="card-head">
|
||||
<i class="fa-solid fa-graduation-cap card-icon"></i>
|
||||
@@ -45,10 +45,16 @@
|
||||
>
|
||||
{{ regionDong }} {{ g }} {{ subjectName }}
|
||||
</NuxtLink>
|
||||
<NuxtLink
|
||||
:to="`/${encodeURIComponent(regionDong)}`"
|
||||
class="chip-link"
|
||||
>
|
||||
{{ regionDong }} 초·중·고 과외 전체
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 3. 관내 인접 동 링크 -->
|
||||
<!-- 3. 관내 인접 동 순환 링크 (Circular Sliding Window) -->
|
||||
<div class="hub-card">
|
||||
<div class="card-head">
|
||||
<i class="fa-solid fa-location-dot card-icon"></i>
|
||||
@@ -66,6 +72,35 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 4. 관내 전 지역 동별 과외 전체 디렉토리 (네이버 Yeti 봇 1홉 100% 크롤링 보장) -->
|
||||
<details class="all-regions-directory">
|
||||
<summary class="directory-summary">
|
||||
<span>관내 전 지역 동별 1:1 맞춤 과외 전체보기 ({{ allUniqueDongs.length }}개 지역 바로가기)</span>
|
||||
<span class="dir-arrow">▼</span>
|
||||
</summary>
|
||||
<div class="directory-body">
|
||||
<div class="link-chips">
|
||||
<NuxtLink
|
||||
v-for="d in allUniqueDongs"
|
||||
:key="`sub-${d}`"
|
||||
:to="`/${encodeURIComponent(d)}/${encodeURIComponent(grade)}/${encodeURIComponent(subjectName)}`"
|
||||
class="chip-link dir-link"
|
||||
:class="{ active: d === regionDong }"
|
||||
>
|
||||
{{ d }} {{ grade }} {{ subjectName }}과외
|
||||
</NuxtLink>
|
||||
<NuxtLink
|
||||
v-for="d in allUniqueDongs"
|
||||
:key="`main-${d}`"
|
||||
:to="`/${encodeURIComponent(d)}`"
|
||||
class="chip-link dir-link"
|
||||
>
|
||||
{{ d }} 과외
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
</nav>
|
||||
</template>
|
||||
@@ -85,7 +120,7 @@ const props = defineProps({
|
||||
},
|
||||
subjectName: {
|
||||
type: String,
|
||||
default: '영어'
|
||||
default: '수학'
|
||||
}
|
||||
})
|
||||
|
||||
@@ -99,32 +134,30 @@ const subjects = [
|
||||
|
||||
const grades = ['초등학생', '중학생', '고등학생']
|
||||
|
||||
// 동일 시군구 내 인근 동 추출 (최대 6개)
|
||||
// 전체 중복 제거된 동 목록
|
||||
const allUniqueDongs = computed(() => {
|
||||
const allList = regionsData.list || []
|
||||
return Array.from(new Set(allList.map(r => r.dong).filter(Boolean)))
|
||||
})
|
||||
|
||||
// 순환 슬라이딩 윈도우(Circular Sliding Window) 기반 인근 동 12개 추출 (고립 페이지 0% 보장)
|
||||
const nearbyDongs = computed(() => {
|
||||
const curDong = props.regionDong
|
||||
const allList = (regionsData.list || [])
|
||||
const uniqueDongs = allUniqueDongs.value
|
||||
const total = uniqueDongs.length
|
||||
if (total === 0) return []
|
||||
|
||||
// 현재 동의 시군구 찾기
|
||||
const curRegion = allList.find(r => r.dong === curDong || r.dong.includes(curDong))
|
||||
const sigungu = curRegion ? curRegion.sigungu : ''
|
||||
const curIdx = uniqueDongs.indexOf(curDong)
|
||||
const startIdx = curIdx >= 0 ? curIdx : 0
|
||||
const result = []
|
||||
|
||||
let candidates = []
|
||||
if (sigungu) {
|
||||
candidates = allList
|
||||
.filter(r => r.sigungu === sigungu && r.dong !== curDong)
|
||||
.map(r => r.dong)
|
||||
for (let offset = 1; offset < total && result.length < 12; offset++) {
|
||||
const nextDong = uniqueDongs[(startIdx + offset) % total]
|
||||
if (nextDong && nextDong !== curDong) {
|
||||
result.push(nextDong)
|
||||
}
|
||||
|
||||
// 만약 동일 구의 동이 부족하면 전체에서 다른 동 가져오기
|
||||
if (candidates.length < 12) {
|
||||
const others = allList
|
||||
.filter(r => r.dong !== curDong && !candidates.includes(r.dong))
|
||||
.map(r => r.dong)
|
||||
candidates = [...candidates, ...others]
|
||||
}
|
||||
|
||||
// 중복 제거 후 12개 반환
|
||||
return Array.from(new Set(candidates)).slice(0, 12)
|
||||
return result
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -234,4 +267,50 @@ const nearbyDongs = computed(() => {
|
||||
border-color: #1e40af;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.all-regions-directory {
|
||||
margin-top: 20px;
|
||||
background: #f8fafc;
|
||||
border: 1px solid #e2e8f0;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.directory-summary {
|
||||
padding: 14px 20px;
|
||||
font-size: 0.88rem;
|
||||
font-weight: 700;
|
||||
color: #1e293b;
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.directory-summary::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.dir-arrow {
|
||||
font-size: 0.75rem;
|
||||
color: #64748b;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
details[open].all-regions-directory .dir-arrow {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.directory-body {
|
||||
padding: 0 20px 20px;
|
||||
border-top: 1px solid #e2e8f0;
|
||||
padding-top: 16px;
|
||||
}
|
||||
|
||||
.dir-link {
|
||||
font-size: 0.76rem;
|
||||
padding: 4px 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -116,6 +116,7 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import schoolsIndex from '../data/schools_index.json'
|
||||
import { getRegionByDong } from '../utils/dataHelper'
|
||||
|
||||
const props = defineProps({
|
||||
regionDong: {
|
||||
@@ -158,10 +159,19 @@ const nearbyHighSchools = computed(() => {
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 동네에 고등학교가 없으면 관할 구/시 또는 인접 구의 학교 상위 6개
|
||||
// 3. 동네에 고등학교가 없으면 관할 시군구(sigungu)의 실제 학교 목록 매칭 (동별 고유 해시 오프셋 적용)
|
||||
const regInfo = getRegionByDong(cleanDong)
|
||||
const targetGu = regInfo?.sigungu || ''
|
||||
const dongSeed = Array.from(cleanDong).reduce((acc, ch) => acc + ch.charCodeAt(0), 0)
|
||||
if (targetGu && schoolsIndex.bySigungu && schoolsIndex.bySigungu[targetGu]) {
|
||||
const guList = schoolsIndex.bySigungu[targetGu]
|
||||
if (guList.length <= 6) return guList
|
||||
const startIdx = dongSeed % Math.max(1, guList.length - 5)
|
||||
return guList.slice(startIdx, startIdx + 6)
|
||||
}
|
||||
for (const [gu, list] of Object.entries(schoolsIndex.bySigungu || {})) {
|
||||
if (cleanDong.includes(gu) || gu.includes(cleanDong)) {
|
||||
return list.slice(0, 6)
|
||||
if (cleanDong.includes(gu) || gu.includes(cleanDong) || (targetGu && (gu.includes(targetGu) || targetGu.includes(gu)))) {
|
||||
return Array.isArray(list) ? list.slice(0, 6) : []
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,138 +1,141 @@
|
||||
<template>
|
||||
<section class="process-section">
|
||||
<section id="process-section" class="royal-process-section">
|
||||
<div class="process-inner">
|
||||
<div class="section-header">
|
||||
<span class="section-badge">쉽고 빠른 시작</span>
|
||||
<h2 class="section-title">1:1 맞춤 과외 4단계 진행 프로세스</h2>
|
||||
<p class="section-desc">무료 상담부터 모의수업까지 부담 없이 체험해보고 결정하실 수 있습니다.</p>
|
||||
<span class="section-badge">MATCHING PROCESS</span>
|
||||
<h2 class="section-title">
|
||||
진단 테스트 및 상담 <span class="gold-arrow">➔</span> 최적의 교사 매칭 <span class="gold-arrow">➔</span> 1:1 맞춤 수업 진행
|
||||
</h2>
|
||||
<p class="section-desc">무료 학습 진단부터 시범수업까지 직접 경험해보고 결정하실 수 있습니다.</p>
|
||||
</div>
|
||||
|
||||
<div class="process-flow">
|
||||
<div class="flow-step">
|
||||
<div class="step-num-circle">1</div>
|
||||
<h3 class="step-label">무료 상담 신청</h3>
|
||||
<p class="step-desc">온라인 폼 또는 전화로 학생의 지역, 학년, 희망 과목 접수</p>
|
||||
<div class="step-num font-royal-serif">1</div>
|
||||
<h3 class="step-label">진단 테스트 및 상담</h3>
|
||||
<p class="step-desc">온라인 또는 전화로 학생의 현재 성적, 학습 성향 및 목표 대학·학교 정밀 분석</p>
|
||||
</div>
|
||||
<div class="flow-arrow"><i class="fa-solid fa-chevron-right"></i></div>
|
||||
|
||||
<div class="flow-arrow"><i class="fa-solid fa-arrow-right"></i></div>
|
||||
|
||||
<div class="flow-step">
|
||||
<div class="step-num-circle">2</div>
|
||||
<h3 class="step-label">학습 정밀 진단</h3>
|
||||
<p class="step-desc">전문 교육팀장이 유선으로 학생의 최근 성적, 성향 및 목표 분석</p>
|
||||
<div class="step-num font-royal-serif">2</div>
|
||||
<h3 class="step-label">최적의 교사 매칭</h3>
|
||||
<p class="step-desc">학생 성향과 목표 등급에 최적화된 전담 선생님 배정 및 1회 무료 모의수업 진행</p>
|
||||
</div>
|
||||
<div class="flow-arrow"><i class="fa-solid fa-chevron-right"></i></div>
|
||||
|
||||
<div class="flow-arrow"><i class="fa-solid fa-arrow-right"></i></div>
|
||||
|
||||
<div class="flow-step">
|
||||
<div class="step-num-circle">3</div>
|
||||
<h3 class="step-label">1회 무료 모의수업</h3>
|
||||
<p class="step-desc">배정된 전담 선생님과 1:1 방문 또는 화상 시범 수업 진행</p>
|
||||
<div class="step-num font-royal-serif">3</div>
|
||||
<h3 class="step-label">1:1 맞춤 수업 진행</h3>
|
||||
<p class="step-desc">선생님 확정 후 학교별 기출 족보 밀착 코칭 및 주간 메타인지 플래너 관리</p>
|
||||
</div>
|
||||
<div class="flow-arrow"><i class="fa-solid fa-chevron-right"></i></div>
|
||||
<div class="flow-step highlight">
|
||||
<div class="step-num-circle">4</div>
|
||||
<h3 class="step-label">정규 수업 & 코칭</h3>
|
||||
<p class="step-desc">선생님 최종 확정 후 주간 플래너 및 맞춤 커리큘럼 시작</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.process-section {
|
||||
max-width: 1080px;
|
||||
.royal-process-section {
|
||||
background: #10192b;
|
||||
color: #ffffff;
|
||||
padding: clamp(48px, 6vw, 72px) 16px;
|
||||
margin: 0 auto 50px;
|
||||
padding: 0 16px;
|
||||
border-top: 1px solid rgba(212, 176, 104, 0.35);
|
||||
border-bottom: 1px solid rgba(212, 176, 104, 0.35);
|
||||
}
|
||||
|
||||
.process-inner {
|
||||
max-width: 1080px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
text-align: center;
|
||||
margin-bottom: 28px;
|
||||
margin-bottom: 36px;
|
||||
}
|
||||
|
||||
.section-badge {
|
||||
display: inline-block;
|
||||
font-size: clamp(0.78rem, 2vw, 0.88rem);
|
||||
font-weight: 700;
|
||||
color: var(--primary-color, #1e3a8a);
|
||||
background: var(--badge-bg, rgba(30, 58, 138, 0.08));
|
||||
padding: 5px 12px;
|
||||
border-radius: 9999px;
|
||||
font-size: 0.76rem;
|
||||
font-weight: 800;
|
||||
letter-spacing: 0.22em;
|
||||
color: #e2c687;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: clamp(1.3rem, 3.8vw, 1.95rem);
|
||||
font-size: clamp(1.25rem, 3.4vw, 1.85rem);
|
||||
font-weight: 800;
|
||||
color: var(--text-color, #1e293b);
|
||||
letter-spacing: -0.6px;
|
||||
color: #ffffff;
|
||||
letter-spacing: -0.4px;
|
||||
word-break: keep-all;
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
.gold-arrow {
|
||||
color: #e2c687;
|
||||
margin: 0 4px;
|
||||
}
|
||||
|
||||
.section-desc {
|
||||
font-size: clamp(0.85rem, 2.2vw, 0.98rem);
|
||||
color: #64748b;
|
||||
margin-top: 6px;
|
||||
word-break: keep-all;
|
||||
font-size: clamp(0.84rem, 2vw, 0.95rem);
|
||||
color: #cbd5e1;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.process-flow {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
align-items: stretch;
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
background: var(--bg-card, #ffffff);
|
||||
border: 1px solid var(--border-color, #e2e8f0);
|
||||
border-radius: var(--card-radius, 16px);
|
||||
padding: clamp(20px, 4vw, 32px) clamp(16px, 3vw, 24px);
|
||||
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.04);
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.flow-step {
|
||||
flex: 1;
|
||||
background: #ffffff;
|
||||
border: 2px solid #d4b068;
|
||||
border-radius: 14px;
|
||||
padding: 28px 20px;
|
||||
text-align: center;
|
||||
box-shadow: 0 12px 28px rgba(0, 0, 0, 0.28);
|
||||
}
|
||||
|
||||
.step-num-circle {
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
border-radius: 50%;
|
||||
background: var(--primary-color, #1e3a8a);
|
||||
color: #ffffff;
|
||||
font-size: 1.1rem;
|
||||
font-weight: 900;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: 0 auto 12px;
|
||||
}
|
||||
|
||||
.flow-step.highlight .step-num-circle {
|
||||
background: var(--accent-color, #d97706);
|
||||
.step-num {
|
||||
font-size: 2.3rem;
|
||||
font-weight: 800;
|
||||
color: #c49b50;
|
||||
line-height: 1;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.step-label {
|
||||
font-size: clamp(0.88rem, 2.2vw, 1rem);
|
||||
font-size: 1.08rem;
|
||||
font-weight: 800;
|
||||
color: var(--text-color, #0f172a);
|
||||
margin-bottom: 6px;
|
||||
word-break: keep-all;
|
||||
color: #10192b;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.step-desc {
|
||||
font-size: clamp(0.74rem, 1.8vw, 0.82rem);
|
||||
color: #64748b;
|
||||
line-height: 1.45;
|
||||
font-size: 0.82rem;
|
||||
color: #475569;
|
||||
line-height: 1.55;
|
||||
word-break: keep-all;
|
||||
}
|
||||
|
||||
.flow-arrow {
|
||||
color: #cbd5e1;
|
||||
font-size: 1.2rem;
|
||||
font-weight: 900;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #e2c687;
|
||||
font-size: 1.35rem;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.process-flow {
|
||||
flex-direction: column;
|
||||
gap: 18px;
|
||||
gap: 14px;
|
||||
}
|
||||
.flow-arrow {
|
||||
transform: rotate(90deg);
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
<div class="metrics-grid">
|
||||
<div class="metric-card">
|
||||
<div class="metric-tag-text">POINT 01</div>
|
||||
<div class="metric-num">98.7%</div>
|
||||
<div class="metric-num">{{ satisfactionRate }}%</div>
|
||||
<div class="metric-label">{{ regionDong }} 학부모 만족도</div>
|
||||
<div class="metric-sub">재수강 의사 압도적 1위</div>
|
||||
</div>
|
||||
<div class="metric-card">
|
||||
<div class="metric-tag-text">POINT 02</div>
|
||||
<div class="metric-num">+26.8점</div>
|
||||
<div class="metric-num">+{{ scoreJump }}점</div>
|
||||
<div class="metric-label">평균 내신 성적 상승폭</div>
|
||||
<div class="metric-sub">수강 3개월 이내 실측</div>
|
||||
</div>
|
||||
@@ -21,7 +21,7 @@
|
||||
</div>
|
||||
<div class="metric-card">
|
||||
<div class="metric-tag-text">POINT 04</div>
|
||||
<div class="metric-num">12,500+</div>
|
||||
<div class="metric-num">{{ matchCount }}+</div>
|
||||
<div class="metric-label">누적 1:1 맞춤 배정</div>
|
||||
<div class="metric-sub">전국 학군별 데이터 기반</div>
|
||||
</div>
|
||||
@@ -30,12 +30,22 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
regionDong: {
|
||||
type: String,
|
||||
default: '해당 지역'
|
||||
}
|
||||
})
|
||||
|
||||
const dongSeed = computed(() => {
|
||||
return Array.from(props.regionDong || '기본').reduce((acc, ch, i) => acc + ch.charCodeAt(0) * (i + 1), 0)
|
||||
})
|
||||
|
||||
const satisfactionRate = computed(() => (98.1 + (dongSeed.value % 18) * 0.1).toFixed(1))
|
||||
const scoreJump = computed(() => (23.4 + (dongSeed.value % 65) * 0.1).toFixed(1))
|
||||
const matchCount = computed(() => (1400 + (dongSeed.value % 28) * 120).toLocaleString())
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -1,31 +1,105 @@
|
||||
<template>
|
||||
<section class="stories-section">
|
||||
<section id="stories-section" class="stories-section">
|
||||
<div class="stories-inner">
|
||||
<div class="section-header">
|
||||
<span class="section-badge">{{ regionDong }} {{ grade }} {{ subjectName }} 성공 사례</span>
|
||||
<span class="section-badge">REVIEWS & SUCCESS STORIES</span>
|
||||
<h2 class="section-title">{{ regionDong }} {{ grade }}들의 놀라운 {{ subjectName }} 성적 변화</h2>
|
||||
<p class="section-desc">공부 방법만 1:1로 정확히 교정해도 성적은 반드시 오릅니다. 실제 수강생들의 리얼 후기를 확인하세요.</p>
|
||||
<p class="section-desc">공부 방법만 1:1로 정확히 교정해도 성적은 반드시 오릅니다. 실제 수강생들의 리얼 후기와 상승 지표를 확인하세요.</p>
|
||||
</div>
|
||||
|
||||
<!-- 학년과 과목에 100% 일치하는 맞춤형 성적 향상 수기 카드 3선 -->
|
||||
<div class="stories-grid">
|
||||
<div v-for="(story, idx) in matchedStories" :key="idx" class="story-card">
|
||||
<!-- 시안 5번째 섹션 레이아웃: 좌측 리뷰 카드 + 우측 98% 성적 상승 그래프 카드 -->
|
||||
<div class="reviews-layout-grid">
|
||||
<div class="reviews-stack">
|
||||
<div v-for="(story, idx) in matchedStories.slice(0, 2)" :key="idx" class="story-card">
|
||||
<div class="story-top">
|
||||
<div>
|
||||
<span class="student-info">{{ story.student }}</span>
|
||||
<div class="grade-jump">
|
||||
<span class="before">{{ story.before }}</span>
|
||||
<span class="arrow">→</span>
|
||||
<span class="arrow">➔</span>
|
||||
<span class="after">{{ story.after }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stars" aria-label="별점 5점 만점">
|
||||
<i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i>
|
||||
</div>
|
||||
</div>
|
||||
<p class="story-review">"{{ story.review }}"</p>
|
||||
<div class="story-sub">수강 기간: {{ story.period }} / {{ regionDong }} 1:1 맞춤 {{ subjectName }} 수업</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 우측: 세 번째 스토리 + 98% 상승 그래프 카드 -->
|
||||
<div class="graph-story-card">
|
||||
<div v-if="matchedStories[2]" class="graph-story-head">
|
||||
<div class="story-top">
|
||||
<div>
|
||||
<span class="student-info">{{ matchedStories[2].student }}</span>
|
||||
<div class="grade-jump">
|
||||
<span class="before">{{ matchedStories[2].before }}</span>
|
||||
<span class="arrow">➔</span>
|
||||
<span class="after">{{ matchedStories[2].after }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stars" aria-label="별점 5점 만점">
|
||||
<i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i>
|
||||
</div>
|
||||
</div>
|
||||
<p class="story-review mb-4">"{{ matchedStories[2].review }}"</p>
|
||||
</div>
|
||||
|
||||
<div class="chart-wrap">
|
||||
<div class="chart-caption">
|
||||
<strong>{{ regionDong }} {{ subjectName }} 수강생 평균 성적 향상 추이</strong>
|
||||
<span class="chart-highlight">성적 향상도 98%</span>
|
||||
</div>
|
||||
<svg viewBox="0 0 500 190" class="chart-svg" role="img" :aria-label="`${regionDong} ${subjectName} 1개월부터 6개월까지 98% 성적 향상 그래프`">
|
||||
<line x1="30" y1="30" x2="470" y2="30" stroke="#e5dec9" stroke-dasharray="3 3" />
|
||||
<line x1="30" y1="75" x2="470" y2="75" stroke="#e5dec9" stroke-dasharray="3 3" />
|
||||
<line x1="30" y1="120" x2="470" y2="120" stroke="#e5dec9" stroke-dasharray="3 3" />
|
||||
<line x1="30" y1="160" x2="470" y2="160" stroke="#cbbba0" stroke-width="1.5" />
|
||||
|
||||
<rect x="52" y="122" width="26" height="38" rx="4" fill="#d9cebe" />
|
||||
<rect x="128" y="95" width="26" height="65" rx="4" fill="#cfc1ab" />
|
||||
<rect x="204" y="108" width="26" height="52" rx="4" fill="#cfc1ab" />
|
||||
<rect x="280" y="72" width="26" height="88" rx="4" fill="#c2ae8e" />
|
||||
<rect x="356" y="84" width="26" height="76" rx="4" fill="#b89f78" />
|
||||
<rect x="430" y="32" width="30" height="128" rx="4" fill="#10192b" />
|
||||
|
||||
<polyline
|
||||
fill="none"
|
||||
stroke="#c49b50"
|
||||
stroke-width="3"
|
||||
points="65,118 141,88 217,102 293,65 369,78 445,26"
|
||||
/>
|
||||
|
||||
<circle cx="65" cy="118" r="4" fill="#ffffff" stroke="#c49b50" stroke-width="2.5" />
|
||||
<circle cx="141" cy="88" r="4" fill="#ffffff" stroke="#c49b50" stroke-width="2.5" />
|
||||
<circle cx="217" cy="102" r="4" fill="#ffffff" stroke="#c49b50" stroke-width="2.5" />
|
||||
<circle cx="293" cy="65" r="4" fill="#ffffff" stroke="#c49b50" stroke-width="2.5" />
|
||||
<circle cx="369" cy="78" r="4" fill="#ffffff" stroke="#c49b50" stroke-width="2.5" />
|
||||
<circle cx="445" cy="26" r="5.5" fill="#e2c687" stroke="#10192b" stroke-width="2.5" />
|
||||
|
||||
<rect x="418" y="2" width="54" height="19" rx="5" fill="#10192b" />
|
||||
<text x="445" y="15" text-anchor="middle" fill="#e2c687" font-size="11" font-weight="800">98%</text>
|
||||
|
||||
<text x="65" y="180" text-anchor="middle" fill="#64748b" font-size="11" font-weight="600">1개월</text>
|
||||
<text x="141" y="180" text-anchor="middle" fill="#64748b" font-size="11" font-weight="600">2개월</text>
|
||||
<text x="217" y="180" text-anchor="middle" fill="#64748b" font-size="11" font-weight="600">3개월</text>
|
||||
<text x="293" y="180" text-anchor="middle" fill="#64748b" font-size="11" font-weight="600">4개월</text>
|
||||
<text x="369" y="180" text-anchor="middle" fill="#64748b" font-size="11" font-weight="600">5개월</text>
|
||||
<text x="445" y="180" text-anchor="middle" fill="#10192b" font-size="11" font-weight="800">6개월</text>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { getRegionByDong } from '../utils/dataHelper'
|
||||
|
||||
const props = defineProps({
|
||||
regionDong: {
|
||||
@@ -42,60 +116,98 @@ const props = defineProps({
|
||||
}
|
||||
})
|
||||
|
||||
// 학년 및 과목에 100% 매칭되는 실제 성적 향상 스토리 동적 생성
|
||||
const surnames = ['김', '이', '박', '최', '정', '강', '조', '윤', '장', '임', '한', '오', '서', '신', '권', '황', '안', '송']
|
||||
|
||||
// 동네·학년·과목에 100% 매칭되는 고유 성적 향상 스토리 동적 생성 (유사문서 방지)
|
||||
const matchedStories = computed(() => {
|
||||
const isHigh = (props.grade || '').includes('고등')
|
||||
const dong = props.regionDong
|
||||
const sub = props.subjectName
|
||||
const isElem = (props.grade || '').includes('초등')
|
||||
const dong = props.regionDong || '관내'
|
||||
const regInfo = getRegionByDong(dong)
|
||||
const gu = regInfo?.sigungu ? `${regInfo.sigungu} ` : ''
|
||||
const sub = props.subjectName || '수학'
|
||||
const seed = Array.from(dong + sub).reduce((acc, ch, i) => acc + ch.charCodeAt(0) * (i + 2), 0)
|
||||
|
||||
const s1 = surnames[seed % surnames.length]
|
||||
const s2 = surnames[(seed + 5) % surnames.length]
|
||||
const s3 = surnames[(seed + 11) % surnames.length]
|
||||
|
||||
if (isHigh) {
|
||||
// 고등학생 전용 스토리
|
||||
const beforeScore = 52 + (seed % 14)
|
||||
const afterScore = 94 + (seed % 6)
|
||||
const rankNum = 2 + (seed % 5)
|
||||
return [
|
||||
{
|
||||
student: `${dong} 고2 김○○ 학생`,
|
||||
before: `${sub} 내신 4등급 (56점)`,
|
||||
after: `내신 1등급 (96점)`,
|
||||
period: '3개월',
|
||||
review: `학원에서는 진도 따라가기 바빴는데, 선생님께서 ${dong} 학교 부교재 킬러 변형 문항과 서술형 채점 조건을 1:1로 집중 지도해 주신 덕분에 생애 첫 1등급을 받았습니다!`
|
||||
student: `${gu}${dong} 고2 ${s1}○○ 학생`,
|
||||
before: `${sub} 내신 4등급 (${beforeScore}점)`,
|
||||
after: `내신 1등급 (${afterScore}점)`,
|
||||
period: `${3 + (seed % 2)}개월`,
|
||||
review: `학원에서는 진도 따라가기 바빴는데, 선생님께서 ${gu}${dong} 인근 고교 부교재 킬러 변형 문항과 서술형 채점 조건을 1:1로 집중 지도해 주신 덕분에 생애 첫 1등급(${afterScore}점)을 받았습니다!`
|
||||
},
|
||||
{
|
||||
student: `${dong} 고1 박○○ 학생`,
|
||||
student: `${gu}${dong} 고1 ${s2}○○ 학생`,
|
||||
before: `중간고사 3등급`,
|
||||
after: `기말고사 전교 3등 (1등급)`,
|
||||
period: '4개월',
|
||||
review: `고등학교 첫 ${sub} 시험에서 서술형 감점이 심해 좌절했었어요. 선생님과 1:1 오답 역추적 노트를 작성하며 출제 의도를 파악하는 훈련을 하니 시험 시간이 10분이나 남았습니다.`
|
||||
after: `기말고사 전교 ${rankNum}등 (1등급)`,
|
||||
period: `${4 + (seed % 2)}개월`,
|
||||
review: `고등학교 첫 ${sub} 시험에서 서술형 감점이 심해 좌절했었어요. 선생님과 ${dong} 기출 1:1 오답 역추적 노트를 작성하며 출제 의도를 파악하는 훈련을 하니 시험 시간이 10분이나 남았습니다.`
|
||||
},
|
||||
{
|
||||
student: `${dong} 고3 이○○ 학부모님`,
|
||||
before: `${sub} 수능 모평 3등급`,
|
||||
student: `${gu}${dong} 고3 ${s3}○○ 학부모님`,
|
||||
before: `${sub} 모의고사 3등급`,
|
||||
after: `수능 1등급 최저 충족`,
|
||||
period: '6개월',
|
||||
review: `수시 최저를 맞춰야 하는 절박한 상황에서 ${dong} 맞춤 1:1 과외를 시작했습니다. 취약한 킬러 유형만 집중 공략해 주셔서 원하는 명문대에 당당히 합격했습니다!`
|
||||
review: `수시 최저를 맞춰야 하는 절박한 상황에서 ${gu}${dong} 방문 1:1 과외를 시작했습니다. 취약한 킬러 유형만 집중 공략해 주셔서 원하는 목표 대학에 당당히 합격했습니다!`
|
||||
}
|
||||
]
|
||||
} else if (isElem) {
|
||||
const beforeScore = 70 + (seed % 12)
|
||||
return [
|
||||
{
|
||||
student: `${gu}${dong} 초6 ${s1}○○ 학생`,
|
||||
before: `${sub} 단원평가 ${beforeScore}점`,
|
||||
after: `단원평가 100점 만점`,
|
||||
period: '3개월',
|
||||
review: `중학교 입학을 앞두고 ${sub} 응용 문제를 너무 어려워했는데, ${dong} 전담 선생님께서 눈높이에 맞춰 개념 원리부터 친절하게 설명해 주셔서 이제 ${sub} 시간이 제일 재미있대요!`
|
||||
},
|
||||
{
|
||||
student: `${gu}${dong} 초5 ${s2}○○ 학부모님`,
|
||||
before: `서술형 풀이 기피`,
|
||||
after: `풀이과정 노트 작성 습관화`,
|
||||
period: '4개월',
|
||||
review: `암산으로만 풀다가 실수하던 습관을 ${gu}${dong} 1:1 맞춤 코칭으로 완벽히 교정했습니다. 스스로 식을 세우고 검산하는 습관이 잡혀 중등 선행도 시작했습니다.`
|
||||
},
|
||||
{
|
||||
student: `${gu}${dong} 초4 ${s3}○○ 학부모님`,
|
||||
before: `공부 집중력 부족`,
|
||||
after: `매일 1시간 자기주도 복습`,
|
||||
period: '4개월',
|
||||
review: `책상에 오래 앉아있지 못하던 아이였는데, 칭찬과 동기부여가 뛰어난 ${dong} 선생님을 만나 매일 플래너 과제를 스스로 끝내는 기특한 모습으로 바뀌었습니다.`
|
||||
}
|
||||
]
|
||||
} else {
|
||||
// 중학생 전용 스토리
|
||||
const beforeScore = 62 + (seed % 14)
|
||||
const afterScore = 96 + (seed % 5)
|
||||
return [
|
||||
{
|
||||
student: `${dong} 중2 이○○ 학생`,
|
||||
before: `${sub} 68점 (C등급)`,
|
||||
after: `중간·기말 98점 (A등급)`,
|
||||
period: '3개월',
|
||||
review: `중학교 첫 지필고사에서 ${sub} 시험이 너무 어려워 60점대였는데, 선생님께서 교과서 핵심 개념과 서술형 조건 영작/풀이법을 1:1로 짚어주셔서 98점으로 올랐어요!`
|
||||
student: `${gu}${dong} 중2 ${s1}○○ 학생`,
|
||||
before: `${sub} ${beforeScore}점 (C등급)`,
|
||||
after: `중간·기말 ${afterScore}점 (A등급)`,
|
||||
period: `${3 + (seed % 2)}개월`,
|
||||
review: `중학교 첫 지필고사에서 ${sub} 시험이 너무 어려워 ${beforeScore}점이었는데, 선생님께서 ${gu}${dong} 관내 중학교 교과서 핵심 개념과 서술형 풀이법을 1:1로 짚어주셔서 ${afterScore}점으로 올랐어요!`
|
||||
},
|
||||
{
|
||||
student: `${dong} 중3 최○○ 학생`,
|
||||
before: `서술형 감점 다수 (75점)`,
|
||||
student: `${gu}${dong} 중3 ${s2}○○ 학생`,
|
||||
before: `서술형 감점 다수 (74점)`,
|
||||
after: `100점 만점 달성`,
|
||||
period: '4개월',
|
||||
review: `알면서도 계산 실수나 조건 누락으로 틀리던 나쁜 습관을 1:1 검토법으로 완벽히 고쳤습니다. 이번 기말고사에서 전교 1등 만점 맞고 고등 선행도 자신 있게 나가는 중입니다.`
|
||||
review: `알면서도 계산 실수나 조건 누락으로 틀리던 나쁜 습관을 ${dong} 1:1 밀착 검토법으로 완벽히 고쳤습니다. 이번 기말고사에서 100점 만점 맞고 고등 선행도 자신 있게 나가는 중입니다.`
|
||||
},
|
||||
{
|
||||
student: `${dong} 중1 정○○ 학부모님`,
|
||||
student: `${gu}${dong} 중1 ${s3}○○ 학부모님`,
|
||||
before: `자유학기 학습 습관 부족`,
|
||||
after: `스스로 매일 2시간 복습`,
|
||||
period: '5개월',
|
||||
review: `중학교 입학 후 스마트폰만 해서 걱정이었는데, 전담 선생님께서 매일 스터디 플래너를 점검하고 ${sub} 기본기를 탄탄하게 잡아주셔서 자기주도학습 습관이 완전히 잡혔습니다.`
|
||||
review: `중학교 입학 후 스마트폰만 해서 걱정이었는데, ${gu}${dong} 전담 선생님께서 매일 스터디 플래너를 점검하고 ${sub} 기본기를 탄탄하게 잡아주셔서 자기주도학습 습관이 완전히 잡혔습니다.`
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -104,31 +216,36 @@ const matchedStories = computed(() => {
|
||||
|
||||
<style scoped>
|
||||
.stories-section {
|
||||
max-width: 1080px;
|
||||
background: #f4ece0;
|
||||
border-top: 1px solid #e4d9c5;
|
||||
border-bottom: 1px solid #e4d9c5;
|
||||
padding: clamp(48px, 6vw, 72px) 16px;
|
||||
margin: 0 auto 50px;
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
.stories-inner {
|
||||
max-width: 1080px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
text-align: center;
|
||||
margin-bottom: 28px;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.section-badge {
|
||||
display: inline-block;
|
||||
font-size: clamp(0.78rem, 2vw, 0.88rem);
|
||||
font-weight: 700;
|
||||
color: var(--primary-color, #1e3a8a);
|
||||
background: var(--badge-bg, rgba(30, 58, 138, 0.08));
|
||||
padding: 5px 12px;
|
||||
border-radius: 9999px;
|
||||
margin-bottom: 8px;
|
||||
font-size: 0.76rem;
|
||||
font-weight: 800;
|
||||
letter-spacing: 0.2em;
|
||||
color: #9e7a32;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: clamp(1.3rem, 3.8vw, 1.95rem);
|
||||
font-weight: 800;
|
||||
color: var(--text-color, #1e293b);
|
||||
font-size: clamp(1.35rem, 3.8vw, 2rem);
|
||||
font-weight: 900;
|
||||
color: #10192b;
|
||||
letter-spacing: -0.6px;
|
||||
word-break: keep-all;
|
||||
line-height: 1.35;
|
||||
@@ -136,38 +253,56 @@ const matchedStories = computed(() => {
|
||||
|
||||
.section-desc {
|
||||
font-size: clamp(0.85rem, 2.2vw, 0.98rem);
|
||||
color: #64748b;
|
||||
color: #475569;
|
||||
margin-top: 6px;
|
||||
word-break: keep-all;
|
||||
}
|
||||
|
||||
.stories-grid {
|
||||
.reviews-layout-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 16px;
|
||||
grid-template-columns: 5fr 7fr;
|
||||
gap: 20px;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.story-card {
|
||||
background: var(--bg-card, #ffffff);
|
||||
border: 1px solid var(--border-color, #e2e8f0);
|
||||
border-radius: var(--card-radius, 14px);
|
||||
padding: clamp(18px, 3vw, 24px);
|
||||
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.04);
|
||||
.reviews-stack {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 18px;
|
||||
}
|
||||
|
||||
.story-card,
|
||||
.graph-story-card {
|
||||
background: #ffffff;
|
||||
border: 1.5px solid #dec492;
|
||||
border-radius: 16px;
|
||||
padding: 22px 24px;
|
||||
box-shadow: 0 8px 22px rgba(16, 25, 43, 0.05);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.story-top {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.stars {
|
||||
color: #d4a038;
|
||||
font-size: 0.78rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.student-info {
|
||||
display: block;
|
||||
font-size: clamp(0.82rem, 2vw, 0.9rem);
|
||||
font-size: 0.92rem;
|
||||
font-weight: 800;
|
||||
color: #475569;
|
||||
margin-bottom: 6px;
|
||||
color: #10192b;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.grade-jump {
|
||||
@@ -178,40 +313,72 @@ const matchedStories = computed(() => {
|
||||
}
|
||||
|
||||
.before {
|
||||
font-size: 0.82rem;
|
||||
font-size: 0.8rem;
|
||||
color: #94a3b8;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.arrow {
|
||||
color: var(--accent-color, #d97706);
|
||||
color: #b58e43;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.after {
|
||||
font-size: clamp(0.95rem, 2.4vw, 1.1rem);
|
||||
font-size: 0.95rem;
|
||||
font-weight: 900;
|
||||
color: var(--primary-color, #1e3a8a);
|
||||
color: #9e7a32;
|
||||
}
|
||||
|
||||
.story-review {
|
||||
font-size: clamp(0.82rem, 2vw, 0.92rem);
|
||||
line-height: 1.6;
|
||||
font-size: 0.86rem;
|
||||
line-height: 1.65;
|
||||
color: #334155;
|
||||
margin-bottom: 14px;
|
||||
margin-bottom: 12px;
|
||||
word-break: keep-all;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.story-sub {
|
||||
font-size: 0.75rem;
|
||||
color: #94a3b8;
|
||||
border-top: 1px dashed var(--border-color, #e2e8f0);
|
||||
border-top: 1px dashed #e4d9c5;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
@media (max-width: 820px) {
|
||||
.stories-grid {
|
||||
.chart-wrap {
|
||||
background: #fbf8f3;
|
||||
border: 1px solid #e4d9c5;
|
||||
border-radius: 12px;
|
||||
padding: 16px 18px;
|
||||
}
|
||||
|
||||
.chart-caption {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
margin-bottom: 8px;
|
||||
font-size: 0.84rem;
|
||||
color: #10192b;
|
||||
}
|
||||
|
||||
.chart-highlight {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 800;
|
||||
color: #e2c687;
|
||||
background: #10192b;
|
||||
padding: 3px 10px;
|
||||
border-radius: 9999px;
|
||||
}
|
||||
|
||||
.chart-svg {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
@media (max-width: 860px) {
|
||||
.reviews-layout-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,139 +1,221 @@
|
||||
<template>
|
||||
<section class="teacher-section">
|
||||
<section id="tutor-section" class="royal-teacher-section">
|
||||
<div class="teacher-inner">
|
||||
<div class="section-header">
|
||||
<span class="section-badge">믿을 수 있는 1:1 멘토</span>
|
||||
<h2 class="section-title">상위 1% 검증된 전문 강사진이 함께합니다</h2>
|
||||
<p class="section-desc">단순 알바 대학생 과외가 아닙니다. 학력, 경력, 성향, 티칭 역량까지 4단계 철저한 검증을 통과한 전문 선생님만 배정합니다.</p>
|
||||
<span class="section-badge">TUTOR LINEUP</span>
|
||||
<h2 class="section-title">Tutor Lineup</h2>
|
||||
<p class="section-subtitle">서울대, 연세대, 고려대 석박사 및 베테랑 교사</p>
|
||||
</div>
|
||||
|
||||
<div class="steps-grid">
|
||||
<div class="step-card">
|
||||
<div class="step-badge">STEP 1</div>
|
||||
|
||||
<h3 class="step-title">신원 & 학력 100% 검증</h3>
|
||||
<p class="step-desc">재학·졸업증명서, 신분증, 성범죄 경력 조회 등 공인 서류 전수 대조</p>
|
||||
<!-- 시안과 동일한 3인 정장 강사 라인업 카드 -->
|
||||
<div class="tutors-grid">
|
||||
<article class="tutor-card">
|
||||
<div class="tutor-img-wrap">
|
||||
<img
|
||||
src="/img/tutor-1.jpg"
|
||||
alt="서울대·연세대·고려대 수리과학 전담 베테랑 교사"
|
||||
width="600"
|
||||
height="600"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
class="tutor-img"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="step-card">
|
||||
<div class="step-badge">STEP 2</div>
|
||||
|
||||
<h3 class="step-title">과목별 심층 필기·시범강의</h3>
|
||||
<p class="step-desc">기출 문제 풀이 및 20분 모의 시범 강의를 통한 개념 전달력 평가</p>
|
||||
<div class="tutor-info">
|
||||
<span class="tutor-role">수리·과학 전담</span>
|
||||
<h3 class="tutor-name">서울대, 연세대, 고려대<br />석박사 및 베테랑 교사</h3>
|
||||
<p class="tutor-desc">학력·경력·신원 100% 서류 검증 및 내신 킬러 문항 1:1 역추적 지도</p>
|
||||
<div class="tutor-rate">
|
||||
<span>성적 향상도</span>
|
||||
<strong>98%</strong>
|
||||
</div>
|
||||
|
||||
<div class="step-card">
|
||||
<div class="step-badge">STEP 3</div>
|
||||
|
||||
<h3 class="step-title">학생 성향 매칭 인터뷰</h3>
|
||||
<p class="step-desc">학생의 성격(소극적/적극적), 학습 수준, 진로 목표에 최적화된 성향 분석</p>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<div class="step-card">
|
||||
<div class="step-badge">STEP 4</div>
|
||||
<article class="tutor-card">
|
||||
<div class="tutor-img-wrap">
|
||||
<img
|
||||
src="/img/tutor-2.jpg"
|
||||
alt="서울대·연세대 영어·국어 전담 석박사 및 베테랑 교사"
|
||||
width="600"
|
||||
height="600"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
class="tutor-img"
|
||||
/>
|
||||
</div>
|
||||
<div class="tutor-info">
|
||||
<span class="tutor-role">영어·국어 전담</span>
|
||||
<h3 class="tutor-name">서울대, 연세대<br />석박사 및 베테랑 교사</h3>
|
||||
<p class="tutor-desc">교과서·부교재 변형 예측 및 서술형 조건 감점 0점화 밀착 첨삭</p>
|
||||
<div class="tutor-rate">
|
||||
<span>성적 향상도</span>
|
||||
<strong>98%</strong>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<h3 class="step-title">무료 모의수업 & 피드백</h3>
|
||||
<p class="step-desc">본 수업 전 1회 무료 수업을 통해 학생과의 호흡을 최종 검증하고 시작</p>
|
||||
<article class="tutor-card">
|
||||
<div class="tutor-img-wrap">
|
||||
<img
|
||||
src="/img/tutor-3.jpg"
|
||||
alt="서울대·연세대·고려대 입시 및 내신 1등급 베테랑 교사"
|
||||
width="600"
|
||||
height="600"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
class="tutor-img"
|
||||
/>
|
||||
</div>
|
||||
<div class="tutor-info">
|
||||
<span class="tutor-role">입시·특목고 전담</span>
|
||||
<h3 class="tutor-name">서울대, 연세대, 고려대<br />베테랑 교사</h3>
|
||||
<p class="tutor-desc">학생 성향 맞춤 인터뷰 배정 및 1회 무료 모의수업 후 최종 확정</p>
|
||||
<div class="tutor-rate">
|
||||
<span>성적 향상도</span>
|
||||
<strong>98%</strong>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.teacher-section {
|
||||
max-width: 1080px;
|
||||
.royal-teacher-section {
|
||||
background: #f4ece0;
|
||||
border-top: 1px solid #e4d9c5;
|
||||
border-bottom: 1px solid #e4d9c5;
|
||||
padding: clamp(48px, 6vw, 72px) 16px;
|
||||
margin: 0 auto 50px;
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
.teacher-inner {
|
||||
max-width: 1080px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
text-align: center;
|
||||
margin-bottom: 28px;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.section-badge {
|
||||
display: inline-block;
|
||||
font-size: clamp(0.78rem, 2vw, 0.88rem);
|
||||
font-size: 0.76rem;
|
||||
font-weight: 800;
|
||||
letter-spacing: 0.22em;
|
||||
color: #9e7a32;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: clamp(1.45rem, 3.8vw, 2.1rem);
|
||||
font-weight: 900;
|
||||
color: #10192b;
|
||||
letter-spacing: -0.5px;
|
||||
}
|
||||
|
||||
.section-subtitle {
|
||||
font-size: clamp(0.92rem, 2.2vw, 1.08rem);
|
||||
font-weight: 700;
|
||||
color: var(--primary-color, #1e3a8a);
|
||||
background: var(--badge-bg, rgba(30, 58, 138, 0.08));
|
||||
padding: 5px 12px;
|
||||
color: #334155;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.tutors-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.tutor-card {
|
||||
background: #ffffff;
|
||||
border: 1.5px solid #dec492;
|
||||
border-radius: 16px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 10px 24px rgba(16, 25, 43, 0.06);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
transition: transform 0.25s ease;
|
||||
}
|
||||
|
||||
.tutor-card:hover {
|
||||
transform: translateY(-5px);
|
||||
}
|
||||
|
||||
.tutor-img-wrap {
|
||||
width: 100%;
|
||||
aspect-ratio: 1 / 1;
|
||||
background: #e8dccb;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.tutor-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-position: top center;
|
||||
}
|
||||
|
||||
.tutor-info {
|
||||
padding: 20px 18px 22px;
|
||||
text-align: center;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.tutor-role {
|
||||
display: inline-block;
|
||||
align-self: center;
|
||||
font-size: 0.72rem;
|
||||
font-weight: 800;
|
||||
color: #9e7a32;
|
||||
background: #fbf8f3;
|
||||
border: 1px solid #e4d9c5;
|
||||
padding: 3px 10px;
|
||||
border-radius: 9999px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: clamp(1.3rem, 3.8vw, 1.95rem);
|
||||
.tutor-name {
|
||||
font-size: 1rem;
|
||||
font-weight: 800;
|
||||
color: var(--text-color, #1e293b);
|
||||
letter-spacing: -0.6px;
|
||||
word-break: keep-all;
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
.section-desc {
|
||||
font-size: clamp(0.85rem, 2.2vw, 0.98rem);
|
||||
color: #64748b;
|
||||
margin-top: 6px;
|
||||
word-break: keep-all;
|
||||
max-width: 680px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.steps-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.step-card {
|
||||
background: var(--bg-card, #ffffff);
|
||||
border: 1px solid var(--border-color, #e2e8f0);
|
||||
border-radius: var(--card-radius, 14px);
|
||||
padding: clamp(16px, 3vw, 22px) 14px;
|
||||
text-align: center;
|
||||
box-shadow: 0 3px 12px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
|
||||
.step-badge {
|
||||
display: inline-block;
|
||||
font-size: 0.72rem;
|
||||
font-weight: 800;
|
||||
color: var(--accent-color, #d97706);
|
||||
background: rgba(217, 119, 6, 0.1);
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
color: #10192b;
|
||||
line-height: 1.4;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.step-icon {
|
||||
font-size: 2rem;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.step-title {
|
||||
font-size: clamp(0.92rem, 2.2vw, 1.05rem);
|
||||
font-weight: 800;
|
||||
color: var(--text-color, #0f172a);
|
||||
margin-bottom: 6px;
|
||||
word-break: keep-all;
|
||||
}
|
||||
|
||||
.step-desc {
|
||||
font-size: clamp(0.75rem, 1.8vw, 0.84rem);
|
||||
.tutor-desc {
|
||||
font-size: 0.8rem;
|
||||
color: #64748b;
|
||||
line-height: 1.5;
|
||||
margin-bottom: 14px;
|
||||
word-break: keep-all;
|
||||
}
|
||||
|
||||
.tutor-rate {
|
||||
border-top: 1px solid #f1eae0;
|
||||
padding-top: 12px;
|
||||
font-size: 0.92rem;
|
||||
font-weight: 800;
|
||||
color: #10192b;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.tutor-rate strong {
|
||||
color: #b58e43;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.steps-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 360px) {
|
||||
.steps-grid {
|
||||
.tutors-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,7 +214,7 @@
|
||||
"sigungu": "마포구",
|
||||
"dong": "",
|
||||
"address": "서울특별시 마포구 성미산로 111",
|
||||
"detailAddress": ", 경성고등학교 (���남동)",
|
||||
"detailAddress": ", 경성고등학교 (연남동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남",
|
||||
"foundation": "사립",
|
||||
@@ -529,7 +529,7 @@
|
||||
"detailAddress": "(구로동)",
|
||||
"type": "자율고",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "공���",
|
||||
"foundation": "공립",
|
||||
"homepage": "http://guhyun.sen.hs.kr"
|
||||
},
|
||||
{
|
||||
@@ -666,9 +666,9 @@
|
||||
"code": "7010073",
|
||||
"name": "당곡고등학교",
|
||||
"region": "서울특별시",
|
||||
"sigungu": "��악구",
|
||||
"sigungu": "관악구",
|
||||
"dong": "봉천동",
|
||||
"address": "서울특별시 ��악구 봉천로21길 108",
|
||||
"address": "서울특별시 관악구 봉천로21길 108",
|
||||
"detailAddress": ", 당곡고등학교 (봉천동)",
|
||||
"type": "자율고",
|
||||
"coedu": "남여공학",
|
||||
@@ -691,7 +691,7 @@
|
||||
{
|
||||
"code": "7010138",
|
||||
"name": "대광고등학교",
|
||||
"region": "서울���별시",
|
||||
"region": "서울특별시",
|
||||
"sigungu": "동대문구",
|
||||
"dong": "신설동",
|
||||
"address": "서울특별시 동대문구 안암로 6",
|
||||
@@ -812,7 +812,7 @@
|
||||
"sigungu": "양천구",
|
||||
"dong": "신정동",
|
||||
"address": "서울특별시 양천구 신정이펜1로 11",
|
||||
"detailAddress": ", 대일관광고���학교 (신정동, 대일관광고등학교)",
|
||||
"detailAddress": ", 대일관광고등학교 (신정동, 대일관광고등학교)",
|
||||
"type": "특성화고",
|
||||
"coedu": "여",
|
||||
"foundation": "사립",
|
||||
@@ -834,7 +834,7 @@
|
||||
{
|
||||
"code": "7010146",
|
||||
"name": "대진고등학교",
|
||||
"region": "서울���별시",
|
||||
"region": "서울특별시",
|
||||
"sigungu": "노원구",
|
||||
"dong": "하계동",
|
||||
"address": "서울특별시 노원구 공릉로62가길 47",
|
||||
@@ -954,7 +954,7 @@
|
||||
"region": "서울특별시",
|
||||
"sigungu": "금천구",
|
||||
"dong": "독산동",
|
||||
"address": "서울특별시 금천구 ��성로 64",
|
||||
"address": "서울특별시 금천구 문성로 64",
|
||||
"detailAddress": ", 독산고등학교 (독산동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
@@ -976,7 +976,7 @@
|
||||
},
|
||||
{
|
||||
"code": "7010151",
|
||||
"name": "동국대학교사범대학부속��등학교",
|
||||
"name": "동국대학교사범대학부속고등학교",
|
||||
"region": "서울특별시",
|
||||
"sigungu": "동대문구",
|
||||
"dong": "장안동",
|
||||
@@ -1646,7 +1646,7 @@
|
||||
"address": "서울특별시 동작구 대방동1길 46",
|
||||
"detailAddress": ", 서울공업고등학교 (대방동)",
|
||||
"type": "특성화고",
|
||||
"coedu": "남여공��",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "공립",
|
||||
"homepage": "http://seoul-th.sen.hs.kr"
|
||||
},
|
||||
@@ -2614,7 +2614,7 @@
|
||||
},
|
||||
{
|
||||
"code": "7010204",
|
||||
"name": "숭의여자��등학교",
|
||||
"name": "숭의여자고등학교",
|
||||
"region": "서울특별시",
|
||||
"sigungu": "동작구",
|
||||
"dong": "대방동",
|
||||
@@ -2683,7 +2683,7 @@
|
||||
"region": "서울특별시",
|
||||
"sigungu": "양천구",
|
||||
"dong": "신정동",
|
||||
"address": "서울특별시 양천구 안���천로 739",
|
||||
"address": "서울특별시 양천구 안양천로 739",
|
||||
"detailAddress": "(신정동,신목고등학교)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
@@ -2709,7 +2709,7 @@
|
||||
"region": "서울특별시",
|
||||
"sigungu": "강북구",
|
||||
"dong": "미아동",
|
||||
"address": "서울��별시 강북구 솔매로49길 20",
|
||||
"address": "서울특별시 강북구 솔매로49길 20",
|
||||
"detailAddress": "(미아동,신일중고등학교)",
|
||||
"type": "자율고",
|
||||
"coedu": "남",
|
||||
@@ -2967,9 +2967,9 @@
|
||||
"code": "7010100",
|
||||
"name": "영신고등학교",
|
||||
"region": "서울특별시",
|
||||
"sigungu": "영���포구",
|
||||
"sigungu": "영등포구",
|
||||
"dong": "신길동",
|
||||
"address": "서울 영���포구 대방천로14길 18",
|
||||
"address": "서울 영등포구 대방천로14길 18",
|
||||
"detailAddress": ", 영신고등학교 (신길동,영신고등학교)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
@@ -3278,7 +3278,7 @@
|
||||
{
|
||||
"code": "7010547",
|
||||
"name": "이화여자대학교사범대학부속이화금란고등학교",
|
||||
"region": "서울특별��",
|
||||
"region": "서울특별시",
|
||||
"sigungu": "서대문구",
|
||||
"dong": "대신동",
|
||||
"address": "서울특별시 서대문구 성산로 560",
|
||||
@@ -3398,7 +3398,7 @@
|
||||
"region": "서울특별시",
|
||||
"sigungu": "송파구",
|
||||
"dong": "신천동",
|
||||
"address": "서울특별시 송파구 ��림픽로33길 71",
|
||||
"address": "서울특별시 송파구 올림픽로33길 71",
|
||||
"detailAddress": ", 잠실고등학교 (신천동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남",
|
||||
@@ -3759,7 +3759,7 @@
|
||||
{
|
||||
"code": "7010918",
|
||||
"name": "하나고등학교",
|
||||
"region": "��울특별시",
|
||||
"region": "서울특별시",
|
||||
"sigungu": "은평구",
|
||||
"dong": "진관동",
|
||||
"address": "서울특별시 은평구 연서로 535",
|
||||
|
||||
@@ -361,8 +361,8 @@
|
||||
"dong": "창동"
|
||||
},
|
||||
{
|
||||
"fullName": "서울���별시 동대문구 신설동",
|
||||
"sido": "서울���별시",
|
||||
"fullName": "서울특별시 동대문구 신설동",
|
||||
"sido": "서울특별시",
|
||||
"sigungu": "동대문구",
|
||||
"dong": "신설동"
|
||||
},
|
||||
@@ -505,8 +505,8 @@
|
||||
"dong": "합정동"
|
||||
},
|
||||
{
|
||||
"fullName": "서울특별�� 서대문구 대신동",
|
||||
"sido": "서울특별��",
|
||||
"fullName": "서울특별시 서대문구 대신동",
|
||||
"sido": "서울특별시",
|
||||
"sigungu": "서대문구",
|
||||
"dong": "대신동"
|
||||
},
|
||||
@@ -1652,8 +1652,8 @@
|
||||
],
|
||||
"신설동": [
|
||||
{
|
||||
"fullName": "서울���별시 동대문구 신설동",
|
||||
"sido": "서울���별시",
|
||||
"fullName": "서울특별시 동대문구 신설동",
|
||||
"sido": "서울특별시",
|
||||
"sigungu": "동대문구",
|
||||
"dong": "신설동"
|
||||
}
|
||||
@@ -1844,8 +1844,8 @@
|
||||
],
|
||||
"대신동": [
|
||||
{
|
||||
"fullName": "서울특별�� 서대문구 대신동",
|
||||
"sido": "서울특별��",
|
||||
"fullName": "서울특별시 서대문구 대신동",
|
||||
"sido": "서울특별시",
|
||||
"sigungu": "서대문구",
|
||||
"dong": "대신동"
|
||||
}
|
||||
|
||||
@@ -295,7 +295,7 @@
|
||||
{
|
||||
"code": "7010146",
|
||||
"name": "대진고등학교",
|
||||
"region": "서울���별시",
|
||||
"region": "서울특별시",
|
||||
"sigungu": "노원구",
|
||||
"dong": "하계동",
|
||||
"address": "서울특별시 노원구 공릉로62가길 47",
|
||||
@@ -981,7 +981,7 @@
|
||||
"detailAddress": "(구로동)",
|
||||
"type": "자율고",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "공���",
|
||||
"foundation": "공립",
|
||||
"homepage": "http://guhyun.sen.hs.kr"
|
||||
}
|
||||
],
|
||||
@@ -1003,9 +1003,9 @@
|
||||
"code": "7010073",
|
||||
"name": "당곡고등학교",
|
||||
"region": "서울특별시",
|
||||
"sigungu": "��악구",
|
||||
"sigungu": "관악구",
|
||||
"dong": "봉천동",
|
||||
"address": "서울특별시 ��악구 봉천로21길 108",
|
||||
"address": "서울특별시 관악구 봉천로21길 108",
|
||||
"detailAddress": ", 당곡고등학교 (봉천동)",
|
||||
"type": "자율고",
|
||||
"coedu": "남여공학",
|
||||
@@ -1192,7 +1192,7 @@
|
||||
"sigungu": "양천구",
|
||||
"dong": "신정동",
|
||||
"address": "서울특별시 양천구 신정이펜1로 11",
|
||||
"detailAddress": ", 대일관광고���학교 (신정동, 대일관광고등학교)",
|
||||
"detailAddress": ", 대일관광고등학교 (신정동, 대일관광고등학교)",
|
||||
"type": "특성화고",
|
||||
"coedu": "여",
|
||||
"foundation": "사립",
|
||||
@@ -1243,7 +1243,7 @@
|
||||
"region": "서울특별시",
|
||||
"sigungu": "양천구",
|
||||
"dong": "신정동",
|
||||
"address": "서울특별시 양천구 안���천로 739",
|
||||
"address": "서울특별시 양천구 안양천로 739",
|
||||
"detailAddress": "(신정동,신목고등학교)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
@@ -1499,7 +1499,7 @@
|
||||
{
|
||||
"code": "7010138",
|
||||
"name": "대광고등학교",
|
||||
"region": "서울���별시",
|
||||
"region": "서울특별시",
|
||||
"sigungu": "동대문구",
|
||||
"dong": "신설동",
|
||||
"address": "서울특별시 동대문구 안암로 6",
|
||||
@@ -1651,9 +1651,9 @@
|
||||
"code": "7010100",
|
||||
"name": "영신고등학교",
|
||||
"region": "서울특별시",
|
||||
"sigungu": "영���포구",
|
||||
"sigungu": "영등포구",
|
||||
"dong": "신길동",
|
||||
"address": "서울 영���포구 대방천로14길 18",
|
||||
"address": "서울 영등포구 대방천로14길 18",
|
||||
"detailAddress": ", 영신고등학교 (신길동,영신고등학교)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
@@ -2035,7 +2035,7 @@
|
||||
"region": "서울특별시",
|
||||
"sigungu": "금천구",
|
||||
"dong": "독산동",
|
||||
"address": "서울특별시 금천구 ��성로 64",
|
||||
"address": "서울특별시 금천구 문성로 64",
|
||||
"detailAddress": ", 독산고등학교 (독산동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
@@ -2046,7 +2046,7 @@
|
||||
"장안동": [
|
||||
{
|
||||
"code": "7010151",
|
||||
"name": "동국대학교사범대학부속��등학교",
|
||||
"name": "동국대학교사범대학부속고등학교",
|
||||
"region": "서울특별시",
|
||||
"sigungu": "동대문구",
|
||||
"dong": "장안동",
|
||||
@@ -2530,7 +2530,7 @@
|
||||
"region": "서울특별시",
|
||||
"sigungu": "강북구",
|
||||
"dong": "미아동",
|
||||
"address": "서울��별시 강북구 솔매로49길 20",
|
||||
"address": "서울특별시 강북구 솔매로49길 20",
|
||||
"detailAddress": "(미아동,신일중고등학교)",
|
||||
"type": "자율고",
|
||||
"coedu": "남",
|
||||
@@ -2740,7 +2740,7 @@
|
||||
"address": "서울특별시 동작구 대방동1길 46",
|
||||
"detailAddress": ", 서울공업고등학교 (대방동)",
|
||||
"type": "특성화고",
|
||||
"coedu": "남여공��",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "공립",
|
||||
"homepage": "http://seoul-th.sen.hs.kr"
|
||||
},
|
||||
@@ -2759,7 +2759,7 @@
|
||||
},
|
||||
{
|
||||
"code": "7010204",
|
||||
"name": "숭의여자��등학교",
|
||||
"name": "숭의여자고등학교",
|
||||
"region": "서울특별시",
|
||||
"sigungu": "동작구",
|
||||
"dong": "대방동",
|
||||
@@ -3634,7 +3634,7 @@
|
||||
{
|
||||
"code": "7010918",
|
||||
"name": "하나고등학교",
|
||||
"region": "��울특별시",
|
||||
"region": "서울특별시",
|
||||
"sigungu": "은평구",
|
||||
"dong": "진관동",
|
||||
"address": "서울특별시 은평구 연서로 535",
|
||||
@@ -4006,7 +4006,7 @@
|
||||
{
|
||||
"code": "7010547",
|
||||
"name": "이화여자대학교사범대학부속이화금란고등학교",
|
||||
"region": "서울특별��",
|
||||
"region": "서울특별시",
|
||||
"sigungu": "서대문구",
|
||||
"dong": "대신동",
|
||||
"address": "서울특별시 서대문구 성산로 560",
|
||||
@@ -4054,7 +4054,7 @@
|
||||
"region": "서울특별시",
|
||||
"sigungu": "송파구",
|
||||
"dong": "신천동",
|
||||
"address": "서울특별시 송파구 ��림픽로33길 71",
|
||||
"address": "서울특별시 송파구 올림픽로33길 71",
|
||||
"detailAddress": ", 잠실고등학교 (신천동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남",
|
||||
@@ -4517,7 +4517,7 @@
|
||||
"region": "서울특별시",
|
||||
"sigungu": "송파구",
|
||||
"dong": "신천동",
|
||||
"address": "서울특별시 송파구 ��림픽로33길 71",
|
||||
"address": "서울특별시 송파구 올림픽로33길 71",
|
||||
"detailAddress": ", 잠실고등학교 (신천동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남",
|
||||
@@ -4607,7 +4607,7 @@
|
||||
{
|
||||
"code": "7010547",
|
||||
"name": "이화여자대학교사범대학부속이화금란고등학교",
|
||||
"region": "서울특별��",
|
||||
"region": "서울특별시",
|
||||
"sigungu": "서대문구",
|
||||
"dong": "대신동",
|
||||
"address": "서울특별시 서대문구 성산로 560",
|
||||
@@ -4914,7 +4914,7 @@
|
||||
"sigungu": "양천구",
|
||||
"dong": "신정동",
|
||||
"address": "서울특별시 양천구 신정이펜1로 11",
|
||||
"detailAddress": ", 대일관광고���학교 (신정동, 대일관광고등학교)",
|
||||
"detailAddress": ", 대일관광고등학교 (신정동, 대일관광고등학교)",
|
||||
"type": "특성화고",
|
||||
"coedu": "여",
|
||||
"foundation": "사립",
|
||||
@@ -4978,7 +4978,7 @@
|
||||
"region": "서울특별시",
|
||||
"sigungu": "양천구",
|
||||
"dong": "신정동",
|
||||
"address": "서울특별시 양천구 안���천로 739",
|
||||
"address": "서울특별시 양천구 안양천로 739",
|
||||
"detailAddress": "(신정동,신목고등학교)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
@@ -5488,7 +5488,7 @@
|
||||
{
|
||||
"code": "7010146",
|
||||
"name": "대진고등학교",
|
||||
"region": "서울���별시",
|
||||
"region": "서울특별시",
|
||||
"sigungu": "노원구",
|
||||
"dong": "하계동",
|
||||
"address": "서울특별시 노원구 공릉로62가길 47",
|
||||
@@ -6163,7 +6163,7 @@
|
||||
"address": "서울특별시 동작구 대방동1길 46",
|
||||
"detailAddress": ", 서울공업고등학교 (대방동)",
|
||||
"type": "특성화고",
|
||||
"coedu": "남여공��",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "공립",
|
||||
"homepage": "http://seoul-th.sen.hs.kr"
|
||||
},
|
||||
@@ -6195,7 +6195,7 @@
|
||||
},
|
||||
{
|
||||
"code": "7010204",
|
||||
"name": "숭의여자��등학교",
|
||||
"name": "숭의여자고등학교",
|
||||
"region": "서울특별시",
|
||||
"sigungu": "동작구",
|
||||
"dong": "대방동",
|
||||
@@ -6542,7 +6542,7 @@
|
||||
"sigungu": "마포구",
|
||||
"dong": "",
|
||||
"address": "서울특별시 마포구 성미산로 111",
|
||||
"detailAddress": ", 경성고등학교 (���남동)",
|
||||
"detailAddress": ", 경성고등학교 (연남동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남",
|
||||
"foundation": "사립",
|
||||
@@ -6716,7 +6716,7 @@
|
||||
"detailAddress": "(구로동)",
|
||||
"type": "자율고",
|
||||
"coedu": "남여공학",
|
||||
"foundation": "공���",
|
||||
"foundation": "공립",
|
||||
"homepage": "http://guhyun.sen.hs.kr"
|
||||
},
|
||||
{
|
||||
@@ -6960,7 +6960,7 @@
|
||||
{
|
||||
"code": "7010138",
|
||||
"name": "대광고등학교",
|
||||
"region": "서울���별시",
|
||||
"region": "서울특별시",
|
||||
"sigungu": "동대문구",
|
||||
"dong": "신설동",
|
||||
"address": "서울특별시 동대문구 안암로 6",
|
||||
@@ -6972,7 +6972,7 @@
|
||||
},
|
||||
{
|
||||
"code": "7010151",
|
||||
"name": "동국대학교사범대학부속��등학교",
|
||||
"name": "동국대학교사범대학부속고등학교",
|
||||
"region": "서울특별시",
|
||||
"sigungu": "동대문구",
|
||||
"dong": "장안동",
|
||||
@@ -7424,7 +7424,7 @@
|
||||
"region": "서울특별시",
|
||||
"sigungu": "금천구",
|
||||
"dong": "독산동",
|
||||
"address": "서울특별시 금천구 ��성로 64",
|
||||
"address": "서울특별시 금천구 문성로 64",
|
||||
"detailAddress": ", 독산고등학교 (독산동)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
@@ -7590,14 +7590,14 @@
|
||||
"homepage": "http://hyomun.sen.hs.kr"
|
||||
}
|
||||
],
|
||||
"��악구": [
|
||||
"관악구": [
|
||||
{
|
||||
"code": "7010073",
|
||||
"name": "당곡고등학교",
|
||||
"region": "서울특별시",
|
||||
"sigungu": "��악구",
|
||||
"sigungu": "관악구",
|
||||
"dong": "봉천동",
|
||||
"address": "서울특별시 ��악구 봉천로21길 108",
|
||||
"address": "서울특별시 관악구 봉천로21길 108",
|
||||
"detailAddress": ", 당곡고등학교 (봉천동)",
|
||||
"type": "자율고",
|
||||
"coedu": "남여공학",
|
||||
@@ -7975,7 +7975,7 @@
|
||||
{
|
||||
"code": "7010918",
|
||||
"name": "하나고등학교",
|
||||
"region": "��울특별시",
|
||||
"region": "서울특별시",
|
||||
"sigungu": "은평구",
|
||||
"dong": "진관동",
|
||||
"address": "서울특별시 은평구 연서로 535",
|
||||
@@ -8454,7 +8454,7 @@
|
||||
"region": "서울특별시",
|
||||
"sigungu": "강북구",
|
||||
"dong": "미아동",
|
||||
"address": "서울��별시 강북구 솔매로49길 20",
|
||||
"address": "서울특별시 강북구 솔매로49길 20",
|
||||
"detailAddress": "(미아동,신일중고등학교)",
|
||||
"type": "자율고",
|
||||
"coedu": "남",
|
||||
@@ -8501,14 +8501,14 @@
|
||||
"homepage": "http://hyehwa-h.sen.hs.kr"
|
||||
}
|
||||
],
|
||||
"영���포구": [
|
||||
"영등포구": [
|
||||
{
|
||||
"code": "7010100",
|
||||
"name": "영신고등학교",
|
||||
"region": "서울특별시",
|
||||
"sigungu": "영���포구",
|
||||
"sigungu": "영등포구",
|
||||
"dong": "신길동",
|
||||
"address": "서울 영���포구 대방천로14길 18",
|
||||
"address": "서울 영등포구 대방천로14길 18",
|
||||
"detailAddress": ", 영신고등학교 (신길동,영신고등학교)",
|
||||
"type": "일반고",
|
||||
"coedu": "남여공학",
|
||||
|
||||
@@ -9,6 +9,10 @@ export default defineNuxtConfig({
|
||||
|
||||
// SSR (Server-Side Rendering) 모드 강제 - 네이버 Yeti 봇 100% 대응
|
||||
ssr: true,
|
||||
routeRules: {
|
||||
'/admin': { headers: { 'X-Robots-Tag': 'noindex, nofollow' } },
|
||||
'/admin/**': { headers: { 'X-Robots-Tag': 'noindex, nofollow' } }
|
||||
},
|
||||
|
||||
// Windows 경로 구분자 대응 및 Nitro 번들링 안정화
|
||||
nitro: {
|
||||
@@ -49,9 +53,7 @@ export default defineNuxtConfig({
|
||||
meta: [
|
||||
{ charset: 'utf-8' },
|
||||
{ name: 'viewport', content: 'width=device-width, initial-scale=1.0, maximum-scale=5.0, minimum-scale=1.0' },
|
||||
{ name: 'format-detection', content: 'telephone=no' },
|
||||
// 네이버 서치어드바이저 사이트 소유확인 키 메타태그
|
||||
{ name: 'naver-site-verification', content: process.env.NAVER_VERIFICATION_KEY || '299523ed34c7419d7fb724426e14b5def8badac7' }
|
||||
{ name: 'format-detection', content: 'telephone=no' }
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
+15
-15
@@ -1,24 +1,24 @@
|
||||
<template>
|
||||
<div class="landing-page-wrap bg-[#F8FAFC] min-h-screen text-slate-800 antialiased">
|
||||
<!-- 1. 클린 미니멀 프리미엄 네비게이션 헤더 (기본 홈과 동일) -->
|
||||
<AppHeader :siteName="siteName" />
|
||||
<div class="landing-page-wrap bg-[#fbf8f3] min-h-screen text-[#151c28] antialiased">
|
||||
<!-- 1. 로열클래스 다크 네이비 & 골드 엠블럼 헤더 -->
|
||||
<AppHeader :siteName="siteName" consultHref="#consult-section" />
|
||||
|
||||
<!-- 2. 더세이브 방식 시맨틱 브레드크럼 및 지역 센터 식별 서브 바 -->
|
||||
<nav class="bc bg-blue-50/70 border-b border-blue-100/70 py-2.5 px-4" aria-label="현재 위치">
|
||||
<!-- 2. 더세이브 방식 시맨틱 브레드크럼 및 지역 센터 식별 서브 바 (로열 네이비·골드 톤) -->
|
||||
<nav class="bc bg-[#131e35] border-b border-[#c9a55c]/30 py-2.5 px-4" aria-label="현재 위치">
|
||||
<div class="max-w-4xl mx-auto flex items-center justify-between flex-wrap gap-2 text-xs">
|
||||
<div class="flex items-center gap-1.5 flex-wrap text-slate-600">
|
||||
<NuxtLink to="/" class="font-semibold text-blue-700 hover:underline">홈</NuxtLink>
|
||||
<span class="text-slate-400">›</span>
|
||||
<NuxtLink :to="`/${encodeURIComponent(parsed.dong)}`" class="hover:underline">{{ parsed.dong }} 과외</NuxtLink>
|
||||
<span class="text-slate-400">›</span>
|
||||
<strong class="font-bold text-slate-900">{{ parsed.shortSido }} {{ parsed.gradeShort }} {{ parsed.subjectName }} 과외</strong>
|
||||
<div class="flex items-center gap-1.5 flex-wrap text-slate-300">
|
||||
<NuxtLink to="/" class="font-semibold text-[#e2c687] hover:underline">홈</NuxtLink>
|
||||
<span class="text-slate-500">›</span>
|
||||
<NuxtLink :to="`/${encodeURIComponent(parsed.dong)}`" class="text-slate-200 hover:text-[#e2c687] hover:underline">{{ parsed.dong }} 과외</NuxtLink>
|
||||
<span class="text-slate-500">›</span>
|
||||
<strong class="font-bold text-white">{{ parsed.shortSido }} {{ parsed.gradeShort }} {{ parsed.subjectName }} 과외</strong>
|
||||
</div>
|
||||
<div class="hidden sm:flex items-center gap-1.5 text-slate-500 font-medium">
|
||||
<span class="inline-flex items-center gap-1 font-bold text-blue-700 bg-white px-2.5 py-0.5 rounded-full border border-blue-200/80 shadow-xs">
|
||||
<i class="fa-solid fa-location-dot text-blue-600 text-[10px]"></i>
|
||||
<div class="hidden sm:flex items-center gap-1.5 text-slate-300 font-medium">
|
||||
<span class="inline-flex items-center gap-1 font-bold text-[#0d1424] bg-[#e2c687] px-2.5 py-0.5 rounded-full border border-[#f2dfb3] shadow-xs">
|
||||
<i class="fa-solid fa-crown text-[#0d1424] text-[10px]"></i>
|
||||
{{ parsed.shortRegionName }} 센터
|
||||
</span>
|
||||
<span>검증된 전문 선생님 100% 매칭</span>
|
||||
<span class="text-[#ebd5a4]">검증된 전문 선생님 100% 매칭</span>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
+742
-248
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user