212 lines
6.8 KiB
JavaScript
212 lines
6.8 KiB
JavaScript
// 예시 텍스트 설정
|
|
function setExample(element) {
|
|
document.getElementById('searchInput').value = element.textContent;
|
|
}
|
|
|
|
// 쿼리 파싱 및 분석
|
|
async function parseQuery() {
|
|
const input = document.getElementById('searchInput').value.trim();
|
|
|
|
if (!input) {
|
|
alert('검색할 내용을 입력해주세요!');
|
|
return;
|
|
}
|
|
|
|
// UI 상태 변경
|
|
document.getElementById('loadingSection').style.display = 'block';
|
|
document.getElementById('resultSection').style.display = 'none';
|
|
document.getElementById('searchBtn').disabled = true;
|
|
|
|
try {
|
|
// /api/search 엔드포인트 호출 (파싱 + 실거래가 조회)
|
|
const response = await fetch('/api/search', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({ text: input })
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error('서버 오류가 발생했습니다.');
|
|
}
|
|
|
|
const data = await response.json();
|
|
displayResults(data);
|
|
|
|
} catch (error) {
|
|
alert('오류: ' + error.message);
|
|
console.error('Error:', error);
|
|
} finally {
|
|
document.getElementById('loadingSection').style.display = 'none';
|
|
document.getElementById('searchBtn').disabled = false;
|
|
}
|
|
}
|
|
|
|
// 결과 표시
|
|
function displayResults(data) {
|
|
const resultContent = document.getElementById('resultContent');
|
|
|
|
let html = '';
|
|
|
|
// 파싱된 정보 요약
|
|
if (data.parsed) {
|
|
html += '<div class="search-summary">';
|
|
html += '<h3>🔍 검색 조건</h3>';
|
|
html += '<div class="summary-items">';
|
|
|
|
if (data.parsed.property_type) {
|
|
html += `<span class="summary-item">${data.parsed.property_type}</span>`;
|
|
}
|
|
if (data.parsed.transaction_type) {
|
|
html += `<span class="summary-item">${data.parsed.transaction_type}</span>`;
|
|
}
|
|
if (data.parsed.location) {
|
|
html += `<span class="summary-item">${data.parsed.location}</span>`;
|
|
}
|
|
if (data.parsed.region_name) {
|
|
html += `<span class="summary-item">${data.parsed.region_name}</span>`;
|
|
}
|
|
|
|
html += '</div>';
|
|
html += '</div>';
|
|
}
|
|
|
|
// 실거래가 목록
|
|
if (data.listings && data.listings.length > 0) {
|
|
html += '<div class="listings-section">';
|
|
html += `<h3>📊 실거래가 정보 (${data.count}건)</h3>`;
|
|
html += '<div class="listings-container">';
|
|
|
|
// 최대 20개만 표시
|
|
const displayCount = Math.min(data.listings.length, 20);
|
|
for (let i = 0; i < displayCount; i++) {
|
|
const item = data.listings[i];
|
|
html += createListingCard(item);
|
|
}
|
|
|
|
if (data.listings.length > 20) {
|
|
html += `<p class="more-info">... 외 ${data.listings.length - 20}건</p>`;
|
|
}
|
|
|
|
html += '</div>';
|
|
html += '</div>';
|
|
} else {
|
|
html += '<div class="no-results">';
|
|
html += '<p>😔 검색 결과가 없습니다.</p>';
|
|
|
|
if (!data.parsed.region_code) {
|
|
html += '<p>지역 정보를 더 구체적으로 입력해주세요.</p>';
|
|
} else {
|
|
html += '<p>다른 조건으로 검색해보세요.</p>';
|
|
}
|
|
html += '</div>';
|
|
}
|
|
|
|
resultContent.innerHTML = html;
|
|
document.getElementById('resultSection').style.display = 'block';
|
|
}
|
|
|
|
// 실거래가 카드 생성
|
|
function createListingCard(item) {
|
|
let html = '<div class="listing-card">';
|
|
|
|
// 제목 (아파트명 또는 주소)
|
|
const title = item['아파트'] || item['법정동'] || '정보 없음';
|
|
html += `<h4>${title}</h4>`;
|
|
|
|
// 거래 정보
|
|
html += '<div class="listing-info">';
|
|
|
|
// 거래금액
|
|
if (item['거래금액']) {
|
|
const price = item['거래금액'].replace(/,/g, '').trim();
|
|
const priceNum = parseInt(price);
|
|
const priceText = priceNum >= 10000 ?
|
|
`${(priceNum / 10000).toFixed(1)}억` :
|
|
`${priceNum.toLocaleString()}만원`;
|
|
html += `<div class="info-item">
|
|
<span class="label">거래금액</span>
|
|
<span class="value price">${priceText}</span>
|
|
</div>`;
|
|
}
|
|
|
|
// 보증금 (전세/월세)
|
|
if (item['보증금액']) {
|
|
const deposit = item['보증금액'].replace(/,/g, '').trim();
|
|
const depositNum = parseInt(deposit);
|
|
const depositText = depositNum >= 10000 ?
|
|
`${(depositNum / 10000).toFixed(1)}억` :
|
|
`${depositNum.toLocaleString()}만원`;
|
|
html += `<div class="info-item">
|
|
<span class="label">보증금</span>
|
|
<span class="value">${depositText}</span>
|
|
</div>`;
|
|
}
|
|
|
|
// 월세
|
|
if (item['월세금액'] && item['월세금액'] !== '0') {
|
|
html += `<div class="info-item">
|
|
<span class="label">월세</span>
|
|
<span class="value">${item['월세금액']}만원</span>
|
|
</div>`;
|
|
}
|
|
|
|
// 면적
|
|
if (item['전용면적']) {
|
|
const area = parseFloat(item['전용면적']);
|
|
const pyeong = (area / 3.3).toFixed(1);
|
|
html += `<div class="info-item">
|
|
<span class="label">면적</span>
|
|
<span class="value">${area}㎡ (${pyeong}평)</span>
|
|
</div>`;
|
|
}
|
|
|
|
// 층
|
|
if (item['층']) {
|
|
html += `<div class="info-item">
|
|
<span class="label">층</span>
|
|
<span class="value">${item['층']}층</span>
|
|
</div>`;
|
|
}
|
|
|
|
// 거래일
|
|
if (item['년'] && item['월'] && item['일']) {
|
|
html += `<div class="info-item">
|
|
<span class="label">거래일</span>
|
|
<span class="value">${item['년']}.${item['월']}.${item['일']}</span>
|
|
</div>`;
|
|
}
|
|
|
|
// 건축년도
|
|
if (item['건축년도']) {
|
|
const age = new Date().getFullYear() - parseInt(item['건축년도']);
|
|
html += `<div class="info-item">
|
|
<span class="label">건축년도</span>
|
|
<span class="value">${item['건축년도']}년 (${age}년)</span>
|
|
</div>`;
|
|
}
|
|
|
|
// 주소
|
|
if (item['법정동'] && item['지번']) {
|
|
html += `<div class="info-item full-width">
|
|
<span class="label">주소</span>
|
|
<span class="value">${item['법정동']} ${item['지번']}</span>
|
|
</div>`;
|
|
}
|
|
|
|
html += '</div>';
|
|
html += '</div>';
|
|
|
|
return html;
|
|
}
|
|
|
|
// Enter 키로 검색
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
document.getElementById('searchInput').addEventListener('keypress', function(e) {
|
|
if (e.key === 'Enter' && !e.shiftKey) {
|
|
e.preventDefault();
|
|
parseQuery();
|
|
}
|
|
});
|
|
}); |