|
<!doctype html> |
|
<html lang="zh-CN"> |
|
<head> |
|
<meta charset="utf-8"> |
|
<meta http-equiv="X-UA-Compatible" content="IE=edge"> |
|
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width"> |
|
<title>美食探索</title> |
|
|
|
<script> |
|
window._AMapSecurityConfig = { |
|
securityJsCode: 'cf71cd668b9003a1144459e461092afb', |
|
} |
|
</script> |
|
<script type="text/javascript" src="https://webapi.amap.com/maps?v=2.0&key=11b1daeff703d83adef3e84cd746ab84&plugin=AMap.CitySearch,AMap.PlaceSearch"></script> |
|
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
|
<style type="text/css"> |
|
* { |
|
margin: 0; |
|
padding: 0; |
|
box-sizing: border-box; |
|
font-family: 'Helvetica Neue', Arial, sans-serif; |
|
} |
|
|
|
body { |
|
height: 100vh; |
|
display: flex; |
|
flex-direction: column; |
|
background-color: #f5f5f5; |
|
} |
|
|
|
.header { |
|
background: linear-gradient(135deg, #ff7e5f, #feb47b); |
|
color: white; |
|
padding: 15px 20px; |
|
display: flex; |
|
justify-content: space-between; |
|
align-items: center; |
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); |
|
z-index: 100; |
|
} |
|
|
|
.header h1 { |
|
font-size: 22px; |
|
font-weight: 600; |
|
} |
|
|
|
.search-container { |
|
background: white; |
|
padding: 15px; |
|
display: flex; |
|
align-items: center; |
|
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05); |
|
} |
|
|
|
.search-bar { |
|
display: flex; |
|
flex: 1; |
|
position: relative; |
|
} |
|
|
|
.search-bar input { |
|
flex: 1; |
|
padding: 12px 15px; |
|
border: 1px solid #e0e0e0; |
|
border-radius: 24px; |
|
font-size: 16px; |
|
outline: none; |
|
transition: border 0.3s; |
|
} |
|
|
|
.search-bar input:focus { |
|
border-color: #ff7e5f; |
|
} |
|
|
|
.search-bar button { |
|
position: absolute; |
|
right: 10px; |
|
top: 50%; |
|
transform: translateY(-50%); |
|
background: none; |
|
border: none; |
|
color: #ff7e5f; |
|
font-size: 18px; |
|
cursor: pointer; |
|
} |
|
|
|
.city-selector { |
|
margin-left: 15px; |
|
display: flex; |
|
align-items: center; |
|
cursor: pointer; |
|
padding: 8px 12px; |
|
border-radius: 20px; |
|
background: #f7f7f7; |
|
transition: background 0.3s; |
|
} |
|
|
|
.city-selector:hover { |
|
background: #f0f0f0; |
|
} |
|
|
|
.main-content { |
|
display: flex; |
|
flex: 1; |
|
overflow: hidden; |
|
} |
|
|
|
#container { |
|
flex: 1; |
|
height: 100%; |
|
} |
|
|
|
#panel { |
|
width: 360px; |
|
background: white; |
|
overflow-y: auto; |
|
box-shadow: -2px 0 10px rgba(0, 0, 0, 0.1); |
|
padding: 0; |
|
transition: transform 0.3s; |
|
} |
|
|
|
.food-categories { |
|
display: flex; |
|
overflow-x: auto; |
|
padding: 15px; |
|
background: white; |
|
margin-bottom: 15px; |
|
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05); |
|
scrollbar-width: none; |
|
} |
|
|
|
.food-categories::-webkit-scrollbar { |
|
display: none; |
|
} |
|
|
|
.category { |
|
flex: 0 0 auto; |
|
margin-right: 15px; |
|
padding: 8px 15px; |
|
background: #f7f7f7; |
|
border-radius: 20px; |
|
cursor: pointer; |
|
transition: all 0.3s; |
|
font-size: 14px; |
|
white-space: nowrap; |
|
} |
|
|
|
.category.active { |
|
background: #ff7e5f; |
|
color: white; |
|
} |
|
|
|
.category:hover:not(.active) { |
|
background: #f0f0f0; |
|
} |
|
|
|
.result-item { |
|
border-bottom: 1px solid #f0f0f0; |
|
padding: 15px; |
|
cursor: pointer; |
|
transition: background 0.3s; |
|
} |
|
|
|
.result-item:hover { |
|
background: #f9f9f9; |
|
} |
|
|
|
.result-item h3 { |
|
font-size: 16px; |
|
margin-bottom: 8px; |
|
color: #333; |
|
} |
|
|
|
.result-item p { |
|
font-size: 14px; |
|
color: #666; |
|
margin-bottom: 8px; |
|
} |
|
|
|
.result-item .rating { |
|
color: #ff7e5f; |
|
margin-bottom: 8px; |
|
} |
|
|
|
.result-item .address { |
|
display: flex; |
|
align-items: center; |
|
font-size: 13px; |
|
color: #999; |
|
} |
|
|
|
.result-item .address i { |
|
margin-right: 5px; |
|
} |
|
|
|
.loading { |
|
position: absolute; |
|
top: 50%; |
|
left: 50%; |
|
transform: translate(-50%, -50%); |
|
display: none; |
|
} |
|
|
|
.loading i { |
|
font-size: 40px; |
|
color: #ff7e5f; |
|
animation: spin 1s infinite linear; |
|
} |
|
|
|
@keyframes spin { |
|
from { transform: rotate(0deg); } |
|
to { transform: rotate(360deg); } |
|
} |
|
|
|
.no-results { |
|
padding: 30px; |
|
text-align: center; |
|
color: #666; |
|
} |
|
|
|
.amap-info-content { |
|
padding: 10px; |
|
border-radius: 8px; |
|
} |
|
|
|
|
|
@media (max-width: 768px) { |
|
.main-content { |
|
flex-direction: column; |
|
} |
|
|
|
#container { |
|
height: 40%; |
|
} |
|
|
|
#panel { |
|
width: 100%; |
|
height: 60%; |
|
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1); |
|
} |
|
|
|
.header h1 { |
|
font-size: 18px; |
|
} |
|
} |
|
</style> |
|
</head> |
|
<body> |
|
<div class="header"> |
|
<h1>美食探索</h1> |
|
<div id="current-city" class="city-selector"> |
|
<i class="fas fa-map-marker-alt"></i> |
|
<span>定位中...</span> |
|
</div> |
|
</div> |
|
|
|
<div class="search-container"> |
|
<div class="search-bar"> |
|
<input type="text" id="keyword" placeholder="搜索美食、餐厅" value="美食"> |
|
<button id="search-btn"><i class="fas fa-search"></i></button> |
|
</div> |
|
</div> |
|
|
|
<div class="food-categories"> |
|
<div class="category active" data-keyword="美食">全部美食</div> |
|
<div class="category" data-keyword="火锅">火锅</div> |
|
<div class="category" data-keyword="烧烤">烧烤</div> |
|
<div class="category" data-keyword="小吃">特色小吃</div> |
|
<div class="category" data-keyword="西餐">西餐</div> |
|
<div class="category" data-keyword="日料">日料</div> |
|
<div class="category" data-keyword="甜点">甜点</div> |
|
<div class="category" data-keyword="咖啡">咖啡</div> |
|
<div class="category" data-keyword="面包">面包</div> |
|
<div class="category" data-keyword="早餐">早餐</div> |
|
</div> |
|
|
|
<div class="main-content"> |
|
<div id="container"></div> |
|
<div id="panel"></div> |
|
</div> |
|
|
|
<div class="loading"> |
|
<i class="fas fa-spinner"></i> |
|
</div> |
|
|
|
<script type="text/javascript"> |
|
|
|
var map = new AMap.Map("container", { |
|
resizeEnable: true, |
|
zoom: 12, |
|
center: [116.397428, 39.90923] |
|
}); |
|
|
|
|
|
var currentCity = { |
|
name: '北京', |
|
adcode: '010' |
|
}; |
|
|
|
|
|
var currentKeyword = '美食'; |
|
|
|
|
|
var placeSearch = null; |
|
|
|
|
|
function updateCityText() { |
|
document.querySelector('#current-city span').textContent = currentCity.name; |
|
} |
|
|
|
|
|
function getCityByIP() { |
|
|
|
var citysearch = new AMap.CitySearch(); |
|
|
|
|
|
citysearch.getLocalCity(function(status, result) { |
|
if (status === 'complete' && result.info === 'OK') { |
|
if (result && result.city && result.bounds) { |
|
currentCity = { |
|
name: result.city, |
|
adcode: result.adcode |
|
}; |
|
|
|
updateCityText(); |
|
|
|
|
|
map.setBounds(result.bounds); |
|
|
|
|
|
initPlaceSearch(); |
|
} |
|
} else { |
|
|
|
updateCityText(); |
|
initPlaceSearch(); |
|
} |
|
}); |
|
} |
|
|
|
|
|
function initPlaceSearch() { |
|
placeSearch = new AMap.PlaceSearch({ |
|
pageSize: 10, |
|
pageIndex: 1, |
|
city: currentCity.adcode, |
|
citylimit: true, |
|
map: map, |
|
autoFitView: true |
|
}); |
|
|
|
|
|
placeSearch.on('complete', function(results) { |
|
document.querySelector('.loading').style.display = 'none'; |
|
if (results.info === 'OK') { |
|
customizeResultList(results.poiList.pois); |
|
} else { |
|
document.getElementById('panel').innerHTML = '<div class="no-results">没有找到相关结果</div>'; |
|
} |
|
}); |
|
|
|
|
|
searchPOI(); |
|
} |
|
|
|
|
|
function searchPOI() { |
|
if (!placeSearch) { |
|
return; |
|
} |
|
|
|
document.querySelector('.loading').style.display = 'block'; |
|
placeSearch.search(currentKeyword, function(status, result) { |
|
document.querySelector('.loading').style.display = 'none'; |
|
if (status === 'error' || status === 'no_data') { |
|
document.getElementById('panel').innerHTML = '<div class="no-results">没有找到相关结果</div>'; |
|
} |
|
}); |
|
} |
|
|
|
|
|
function customizeResultList(pois) { |
|
var panel = document.getElementById('panel'); |
|
panel.innerHTML = ''; |
|
|
|
if (!pois || pois.length === 0) { |
|
panel.innerHTML = '<div class="no-results">没有找到相关结果</div>'; |
|
return; |
|
} |
|
|
|
pois.forEach(function(poi) { |
|
var item = document.createElement('div'); |
|
item.className = 'result-item'; |
|
|
|
|
|
var rating = (Math.random() * 1.0 + 4.0).toFixed(1); |
|
|
|
var price = Math.floor(Math.random() * 180 + 20); |
|
|
|
|
|
var stars = ''; |
|
var fullStars = Math.floor(rating); |
|
var halfStar = rating % 1 >= 0.5; |
|
|
|
for (var i = 0; i < 5; i++) { |
|
if (i < fullStars) { |
|
stars += '<i class="fas fa-star"></i>'; |
|
} else if (halfStar && i === fullStars) { |
|
stars += '<i class="fas fa-star-half-alt"></i>'; |
|
halfStar = false; |
|
} else { |
|
stars += '<i class="far fa-star"></i>'; |
|
} |
|
} |
|
|
|
item.innerHTML = ` |
|
<h3>${poi.name}</h3> |
|
<div class="rating">${stars} ${rating} · 人均 ¥${price}</div> |
|
<p>${poi.type || '特色美食'}</p> |
|
<div class="address"><i class="fas fa-map-marker-alt"></i>${poi.address || poi.location.toString()}</div> |
|
`; |
|
|
|
item.addEventListener('click', function() { |
|
map.setCenter(poi.location); |
|
map.setZoom(15); |
|
}); |
|
|
|
panel.appendChild(item); |
|
}); |
|
} |
|
|
|
|
|
document.getElementById('search-btn').addEventListener('click', function() { |
|
var keyword = document.getElementById('keyword').value.trim(); |
|
if (keyword) { |
|
currentKeyword = keyword; |
|
searchPOI(); |
|
|
|
|
|
document.querySelectorAll('.category').forEach(function(cat) { |
|
cat.classList.remove('active'); |
|
if (cat.dataset.keyword === keyword) { |
|
cat.classList.add('active'); |
|
} |
|
}); |
|
} |
|
}); |
|
|
|
|
|
document.getElementById('keyword').addEventListener('keyup', function(e) { |
|
if (e.key === 'Enter') { |
|
document.getElementById('search-btn').click(); |
|
} |
|
}); |
|
|
|
|
|
document.querySelectorAll('.category').forEach(function(category) { |
|
category.addEventListener('click', function() { |
|
document.querySelectorAll('.category').forEach(function(cat) { |
|
cat.classList.remove('active'); |
|
}); |
|
this.classList.add('active'); |
|
|
|
currentKeyword = this.dataset.keyword; |
|
document.getElementById('keyword').value = currentKeyword; |
|
searchPOI(); |
|
}); |
|
}); |
|
|
|
|
|
document.getElementById('current-city').addEventListener('click', function() { |
|
|
|
alert('城市选择功能将在未来版本添加'); |
|
}); |
|
|
|
|
|
window.onload = function() { |
|
getCityByIP(); |
|
}; |
|
</script> |
|
</body> |
|
</html> |