Qwen3-Coder+高德MCP打造情侣十一假期四日游武汉攻略
🌟 Hello,我是摘星! 🌈 在彩虹般绚烂的技术栈中,我是那个永不停歇的色彩收集者。 🦋 每一个优化都是我培育的花朵,每一个特性都是我放飞的蝴蝶。 🔬 每一次代码审查都是我的显微镜观察,每一次重构都是我的化学实验。 🎵 在编程的交响乐中,我既是指挥家也是演奏者。让我们一起,在技术的音乐厅里,奏响属于程序员的华美乐章。摘要
作为一名常年奔波于代码世界的技术人,我深知十一长假对于程序员们的珍贵。尤其是那些想要与心爱的人共度美好时光的技术宅们,如何在有限的假期里规划出一场完美的情侣游,成为了一个既浪漫又技术的挑战。今天,我要与大家分享一个令人兴奋的技术实践项目——利用Qwen3-Coder的强大编程能力,结合高德地图MCP(Model Context Protocol)的地理信息服务,为情侣们量身定制了一套武汉四日游的智能攻略系统。这不仅仅是一次简单的旅游规划,更是一次AI技术在生活场景中的深度应用探索。
在这个项目中,我们充分发挥了Qwen3-Coder在代码生成、逻辑推理和数据处理方面的优势,通过与高德MCP的深度集成,实现了从景点推荐、路线规划、美食发现到住宿选择的全方位智能化服务。我们不仅考虑了传统的距离优化和时间安排,更融入了情侣出行的特殊需求:浪漫指数评估、拍照打卡点推荐、私密空间筛选等个性化功能。
通过这套系统,我们可以根据情侣的兴趣偏好、体力状况、预算范围等多维度参数,动态生成最适合的行程方案。系统还具备实时调整能力,能够根据天气变化、景点客流量、交通状况等实时信息,自动优化行程安排,确保每一刻都能获得最佳的游览体验。
效果演示
地图导航行程规划
天气预报
技术实现
Qwen3-Coder
**Qwen3-Coder-Plus(强大的“大脑”):**这是理解任务、生成方案的智能核心,经过海量数据训练,能洞察复杂任务。**Qwen-Code CLI 工具(易用的“驾驶舱”):**这是一个安装简单的命令行工具,让你能轻松与“大脑”对话,指挥它完成任务。无论你是开发者想提升效率,还是办公人员想自动化处理文档、表格,它都能帮上忙。
由于Qwen-Code CLI是运行在命令行的工具,且逻辑处理和计算均在Qwen3-Coder的云端模型推理计算完成,所以**对于设备性能基本没有要求,**当前主流桌面电脑均可以运行。
高德MCP
在AI时代,随着AI技术的迅猛发展,各种出行助手应用如雨后春笋,受限于大模型的数据孤岛、能力边界限制,始终未能发挥其在应用层面落地价值。 MCP的出现统一了大模型与外部数据、工具间的通讯协议。而在出行服务领域,数据的时效性、工具的便捷性尤为重要,高德MCP Server旨在为大模型在出行领域的应用落地高效赋能。2025年3月,高德地图MCP首发,为开发者提供了基于位置服务、地点信息搜索、路径规划、天气查询等12大核心高鲜度数据,让用户在出行规划、位置信息检索场景下轻松获取即时信息。
2025年5月,高德地图MCP全新升级,通过高德MCP Server 与高德地图APP无缝打通,用户可将大模型产出的攻略与高德地图APP无缝衔接。实现一键生成专属地图,将攻略中的点位、描述、行程规划等个性化信息自动导入到高德地图APP,生成一张独属于用户的私有地图,实际出行中可实现由攻略到一键导航、打车、 订票的丝滑体验。
开发指南
配置Qwen3-Coder
获取阿里云API-KEY
访问并登录阿里云百炼大模型服务平台:[https://bailian.console.aliyun.com/?tab=app#/api-key](https://bailian.console.aliyun.com/?tab=app#/api-key),创建API-KEY安装Node.js
**Node.js 版本****:**必须安装 **Node.js 20 或更高版本**,安装流程如下:➡️**** Windows:推荐官网下载
访问 Node.js 官方网站的下载页面,选择平台为 Windows 并选择下载并安装(推荐 LTS 版本)
安装验证:安装完成后,打开命令提示符(CMD)并运行以下命令,以确认 Node.js 和 npm(Node.js 包管理器)已成功安装。
node -v
npm -v
安装Qwen3-Coder CLI
```bash npm install -g @qwen-code/qwen-code ```安装完成后,通过以下命令验证安装是否成功:
qwen --version
设置项目级系统变量
在项目根目录下创建一个名为 .env 的文件,是管理Qwen项目运行的最好方法。这可以避免污染全局环境,并方便团队成员共享配置(只需共享 .env.example 文件)。在 Qwen 的根目录创建 .env 或文件(或使用vi .env命令),并填入以下内容:
OPENAI_API_KEY="YOUR_API_KEY_HERE"
OPENAI_BASE_URL="YOUR_REGIONAL_BASE_URL"
OPENAI_MODEL="qwen3-coder-plus"
启动Qwen3-Coder
配置高德MCP
访问高德地图开发平台
访问高德开发平台:[https://lbs.amap.com/api](https://lbs.amap.com/api)查看高德MCP Servers文档lbs.amap.com/api/mcp-ser…
参考高德官方给出的示例进行MCP的配置
创建高德API KEY
登录高德开发者平台控制台[https://console.amap.com/dev/index](https://console.amap.com/dev/index)进入应用管理console.amap.com/dev/key/app
创建API KEY
配置高德MCP
直接复制下方的json,导入到Qwen3-Coder中{
"mcpServers": {
"amap-maps-streamableHTTP": {
"url": "https://mcp.amap.com/mcp?key=您的密钥"
}
}
}
Qwen3-Coder交互开发
我们准备好下方的提示词,并投喂给Qwen3-Coder请为武汉4天情侣旅行制作一个现代化旅游攻略网页应用。需要调用高德地图MCP,实现以下功能:1、行程规划:根据十一假期时间安排最优游览路线,时间安排、景点推荐、美食攻略,结合实时天气数据调整行程建议,每日行程独立卡片展示,支持点击切换浏览,景点信息以精美卡片形式呈现,包含MCP中返回的真实图片和详细介绍;。2、交互式地图展示:在高德app上展示地图,并且集成到H5网页中。3、展示天气数据响应式卡片式界面设计,采用现代美学风格,要求界面色彩丰富,交互流畅,具有优雅的UI\UX。
开始执行
一步步根据提示等待执行完毕之后打开HTML查看结果:
武汉作为历史文化名城,拥有众多特色景点。我们的推荐系统针对不同类型的情侣提供个性化建议:
| 情侣类型 | 推荐景点类别 | 权重分配 | 特色标签 |
|---|---|---|---|
| 文艺浪漫型 | 黄鹤楼、武汉大学、东湖樱园 | 文化40% + 浪漫30% | 🎨文艺范、💕浪漫值MAX |
| 活力探索型 | 木兰天池、欢乐谷、江滩公园 | 活动35% + 探索30% | 🏃♂️活力四射、🌟新鲜体验 |
| 休闲度假型 | 汉口租界、昙华林、东湖绿道 | 舒适40% + 休闲30% | 🛋️舒适惬意、⏰慢节奏 |
| 网红打卡型 | 江汉路步行街、光谷步行街 | 拍照40% + 热度30% | 📸拍照圣地、🔥网红必去 |
| 美食享乐型 | 户部巷、武汉天地、楚河汉街 | 美食40% + 品质30% | 🍜美食天堂、👨🍳地道风味 |
源码
HTML<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>武汉4天情侣旅行攻略</title>
<link rel="stylesheet" href="styles.css">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
<script type="text/javascript" src="https://webapi.amap.com/maps?v=2.0&key="></script>
</head>
<body>
<div class="app-container">
<!-- 头部导航 -->
<header class="header">
<div class="header-content">
<div class="logo">
<i class="fas fa-heart"></i>
<span>武汉情侣游</span>
</div>
<nav class="nav-menu">
<a href="#itinerary" class="nav-item active" data-section="itinerary">
<i class="fas fa-route"></i>
行程规划
</a>
<a href="#map" class="nav-item" data-section="map">
<i class="fas fa-map-marked-alt"></i>
地图导览
</a>
<a href="#weather" class="nav-item" data-section="weather">
<i class="fas fa-cloud-sun"></i>
天气预报
</a>
</nav>
</div>
</header>
<!-- 主要内容区域 -->
<main class="main-content">
<!-- 行程规划部分 -->
<section id="itinerary" class="section active">
<div class="section-header">
<h2>4天浪漫行程规划</h2>
<p>精心安排的武汉情侣之旅,每一天都充满惊喜</p>
</div>
<div class="day-tabs">
<button class="day-tab active" data-day="1">第一天</button>
<button class="day-tab" data-day="2">第二天</button>
<button class="day-tab" data-day="3">第三天</button>
<button class="day-tab" data-day="4">第四天</button>
</div>
<div class="day-content">
<!-- 第一天 -->
<div class="day-plan active" data-day="1">
<div class="day-header">
<h3>第一天 - 历史文化之旅</h3>
<span class="day-date">8月28日</span>
</div>
<div class="attractions-grid">
<div class="attraction-card">
<div class="card-image">
<img src="http://store.is.autonavi.com/showpic/38284e14a64f92703a452a900e4667c6" alt="黄鹤楼">
<div class="card-badge">必游</div>
</div>
<div class="card-content">
<h4>黄鹤楼</h4>
<p class="location"><i class="fas fa-map-marker-alt"></i> 蛇山西山坡特1号(地铁司门口黄鹤楼站A出口步行500m)</p>
<p class="description">江南三大名楼之一,登楼远眺长江美景,感受千年文化底蕴</p>
<div class="card-meta">
<span class="time"><i class="fas fa-clock"></i> 2-3小时</span>
<span class="price"><i class="fas fa-ticket-alt"></i> ¥70</span>
</div>
</div>
</div>
<div class="attraction-card">
<div class="card-image">
<img src="http://store.is.autonavi.com/showpic/2b8b08296bcb347f1f1683f0daa54f49" alt="户部巷">
<div class="card-badge">美食</div>
</div>
<div class="card-content">
<h4>户部巷</h4>
<p class="location"><i class="fas fa-map-marker-alt"></i> 司门口中华路街道解放路459号</p>
<p class="description">武汉小吃第一巷,热干面、豆皮、糊汤粉等地道美食</p>
<div class="card-meta">
<span class="time"><i class="fas fa-clock"></i> 1-2小时</span>
<span class="price"><i class="fas fa-utensils"></i> ¥50-80</span>
</div>
</div>
</div>
<div class="attraction-card">
<div class="card-image">
<img src="https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=400" alt="长江大桥">
<div class="card-badge">夜景</div>
</div>
<div class="card-content">
<h4>武汉长江大桥</h4>
<p class="location"><i class="fas fa-map-marker-alt"></i> 武昌区临江大道</p>
<p class="description">万里长江第一桥,夜晚灯光璀璨,是情侣拍照的绝佳地点</p>
<div class="card-meta">
<span class="time"><i class="fas fa-clock"></i> 1小时</span>
<span class="price"><i class="fas fa-camera"></i> 免费</span>
</div>
</div>
</div>
</div>
</div>
<!-- 第二天 -->
<div class="day-plan" data-day="2">
<div class="day-header">
<h3>第二天 - 自然风光之旅</h3>
<span class="day-date">8月29日</span>
</div>
<div class="attractions-grid">
<div class="attraction-card">
<div class="card-image">
<img src="http://store.is.autonavi.com/showpic/78f1a01143257890d61346845947eb28" alt="东湖">
<div class="card-badge">自然</div>
</div>
<div class="card-content">
<h4>东湖生态旅游风景区</h4>
<p class="location"><i class="fas fa-map-marker-alt"></i> 沿湖大道16号</p>
<p class="description">中国最大的城中湖,湖光山色,适合情侣漫步游船</p>
<div class="card-meta">
<span class="time"><i class="fas fa-clock"></i> 4-5小时</span>
<span class="price"><i class="fas fa-ticket-alt"></i> ¥30</span>
</div>
</div>
</div>
<div class="attraction-card">
<div class="card-image">
<img src="http://aos-cdn-image.amap.com/sns/ugccomment/618096f0-4bab-4818-b529-2fcfedc7db27.jpg" alt="武汉大学">
<div class="card-badge">文化</div>
</div>
<div class="card-content">
<h4>武汉大学</h4>
<p class="location"><i class="fas fa-map-marker-alt"></i> 珞珈山街道八一路299号</p>
<p class="description">中国最美大学之一,古典建筑与现代气息完美融合</p>
<div class="card-meta">
<span class="time"><i class="fas fa-clock"></i> 2-3小时</span>
<span class="price"><i class="fas fa-graduation-cap"></i> 免费</span>
</div>
</div>
</div>
<div class="attraction-card">
<div class="card-image">
<img src="https://images.unsplash.com/photo-1555396273-367ea4eb4db5?w=400" alt="樱花园">
<div class="card-badge">浪漫</div>
</div>
<div class="card-content">
<h4>樱花园</h4>
<p class="location"><i class="fas fa-map-marker-alt"></i> 武汉大学内</p>
<p class="description">虽非樱花季,但园内景色依然优美,适合情侣拍照留念</p>
<div class="card-meta">
<span class="time"><i class="fas fa-clock"></i> 1小时</span>
<span class="price"><i class="fas fa-heart"></i> 免费</span>
</div>
</div>
</div>
</div>
</div>
<!-- 第三天 -->
<div class="day-plan" data-day="3">
<div class="day-header">
<h3>第三天 - 现代都市之旅</h3>
<span class="day-date">8月30日</span>
</div>
<div class="attractions-grid">
<div class="attraction-card">
<div class="card-image">
<img src="https://images.unsplash.com/photo-1449824913935-59a10b8d2000?w=400" alt="江汉路步行街">
<div class="card-badge">购物</div>
</div>
<div class="card-content">
<h4>江汉路步行街</h4>
<p class="location"><i class="fas fa-map-marker-alt"></i> 江汉区江汉路</p>
<p class="description">武汉最繁华的商业街,购物美食一应俱全</p>
<div class="card-meta">
<span class="time"><i class="fas fa-clock"></i> 3-4小时</span>
<span class="price"><i class="fas fa-shopping-bag"></i> 自定</span>
</div>
</div>
</div>
<div class="attraction-card">
<div class="card-image">
<img src="https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=400" alt="汉口江滩">
<div class="card-badge">休闲</div>
</div>
<div class="card-content">
<h4>汉口江滩</h4>
<p class="location"><i class="fas fa-map-marker-alt"></i> 江岸区沿江大道</p>
<p class="description">长江边的城市阳台,夜晚灯光秀美轮美奂</p>
<div class="card-meta">
<span class="time"><i class="fas fa-clock"></i> 2小时</span>
<span class="price"><i class="fas fa-moon"></i> 免费</span>
</div>
</div>
</div>
<div class="attraction-card">
<div class="card-image">
<img src="https://images.unsplash.com/photo-1517248135467-4c7edcad34c4?w=400" alt="光谷步行街">
<div class="card-badge">夜生活</div>
</div>
<div class="card-content">
<h4>光谷步行街</h4>
<p class="location"><i class="fas fa-map-marker-alt"></i> 洪山区珞瑜路</p>
<p class="description">年轻人的聚集地,酒吧、咖啡厅、电影院应有尽有</p>
<div class="card-meta">
<span class="time"><i class="fas fa-clock"></i> 3小时</span>
<span class="price"><i class="fas fa-cocktail"></i> ¥100-200</span>
</div>
</div>
</div>
</div>
</div>
<!-- 第四天 -->
<div class="day-plan" data-day="4">
<div class="day-header">
<h3>第四天 - 文艺休闲之旅</h3>
<span class="day-date">8月31日</span>
</div>
<div class="attractions-grid">
<div class="attraction-card">
<div class="card-image">
<img src="https://images.unsplash.com/photo-1481277542470-605612bd2d61?w=400" alt="湖北省博物馆">
<div class="card-badge">文化</div>
</div>
<div class="card-content">
<h4>湖北省博物馆</h4>
<p class="location"><i class="fas fa-map-marker-alt"></i> 武昌区东湖路156号</p>
<p class="description">荆楚文化的宝库,编钟演奏不容错过</p>
<div class="card-meta">
<span class="time"><i class="fas fa-clock"></i> 2-3小时</span>
<span class="price"><i class="fas fa-university"></i> 免费</span>
</div>
</div>
</div>
<div class="attraction-card">
<div class="card-image">
<img src="https://images.unsplash.com/photo-1441986300917-64674bd600d8?w=400" alt="昙华林">
<div class="card-badge">文艺</div>
</div>
<div class="card-content">
<h4>昙华林</h4>
<p class="location"><i class="fas fa-map-marker-alt"></i> 武昌区昙华林</p>
<p class="description">武汉的文艺街区,咖啡馆、书店、手工艺品店林立</p>
<div class="card-meta">
<span class="time"><i class="fas fa-clock"></i> 2小时</span>
<span class="price"><i class="fas fa-coffee"></i> ¥50-100</span>
</div>
</div>
</div>
<div class="attraction-card">
<div class="card-image">
<img src="https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=400" alt="归元寺">
<div class="card-badge">祈福</div>
</div>
<div class="card-content">
<h4>归元寺</h4>
<p class="location"><i class="fas fa-map-marker-alt"></i> 汉阳区翠微路20号</p>
<p class="description">武汉著名古刹,为爱情祈福的好去处</p>
<div class="card-meta">
<span class="time"><i class="fas fa-clock"></i> 1-2小时</span>
<span class="price"><i class="fas fa-pray"></i> ¥10</span>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- 地图导览部分 -->
<section id="map" class="section">
<div class="section-header">
<h2>交互式地图导览</h2>
<p>查看景点位置,规划最佳路线</p>
</div>
<div class="map-container">
<div id="amap-container"></div>
<div class="map-controls">
<button class="map-btn" onclick="showAllAttractions()">
<i class="fas fa-map-marked-alt"></i>
显示所有景点
</button>
<button class="map-btn" onclick="planRoute()">
<i class="fas fa-route"></i>
规划路线
</button>
<button class="map-btn" onclick="findNearby()">
<i class="fas fa-search-location"></i>
附近推荐
</button>
</div>
</div>
</section>
<!-- 天气预报部分 -->
<section id="weather" class="section">
<div class="section-header">
<h2>武汉天气预报</h2>
<p>实时天气信息,助您合理安排行程</p>
</div>
<div class="weather-container">
<div class="current-weather">
<div class="weather-main">
<div class="weather-icon">
<i class="fas fa-sun"></i>
</div>
<div class="weather-info">
<h3 id="current-temp">38°C</h3>
<p id="weather-desc">晴朗</p>
<p id="weather-location">武汉市</p>
</div>
</div>
<div class="weather-details">
<div class="detail-item">
<i class="fas fa-eye"></i>
<span>能见度</span>
<span id="visibility">10km</span>
</div>
<div class="detail-item">
<i class="fas fa-tint"></i>
<span>湿度</span>
<span id="humidity">65%</span>
</div>
<div class="detail-item">
<i class="fas fa-wind"></i>
<span>风速</span>
<span id="wind-speed">北风1-3级</span>
</div>
</div>
</div>
<div class="weather-forecast">
<h4>4天预报</h4>
<div class="forecast-grid">
<div class="forecast-item">
<div class="forecast-date">8/28</div>
<div class="forecast-icon"><i class="fas fa-sun"></i></div>
<div class="forecast-temp">38°/27°</div>
<div class="forecast-desc">晴</div>
</div>
<div class="forecast-item">
<div class="forecast-date">8/29</div>
<div class="forecast-icon"><i class="fas fa-sun"></i></div>
<div class="forecast-temp">37°/26°</div>
<div class="forecast-desc">晴</div>
</div>
<div class="forecast-item">
<div class="forecast-date">8/30</div>
<div class="forecast-icon"><i class="fas fa-cloud-rain"></i></div>
<div class="forecast-temp">34°/25°</div>
<div class="forecast-desc">小雨</div>
</div>
<div class="forecast-item">
<div class="forecast-date">8/31</div>
<div class="forecast-icon"><i class="fas fa-cloud-rain"></i></div>
<div class="forecast-temp">31°/25°</div>
<div class="forecast-desc">中雨</div>
</div>
</div>
</div>
<div class="weather-tips">
<h4>出行建议</h4>
<div class="tips-grid">
<div class="tip-item">
<i class="fas fa-tshirt"></i>
<div>
<h5>穿衣指数</h5>
<p>高温天气,建议穿轻薄透气衣物,注意防晒</p>
</div>
</div>
<div class="tip-item">
<i class="fas fa-umbrella"></i>
<div>
<h5>雨具提醒</h5>
<p>后两天有雨,记得携带雨具</p>
</div>
</div>
<div class="tip-item">
<i class="fas fa-camera"></i>
<div>
<h5>拍照指数</h5>
<p>前两天晴朗,光线充足,适合拍照</p>
</div>
</div>
</div>
</div>
</div>
</section>
</main>
<!-- 浮动操作按钮 -->
<div class="fab-container">
<button class="fab" onclick="scrollToTop()">
<i class="fas fa-arrow-up"></i>
</button>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
CSS
/* 全局样式 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
line-height: 1.6;
color: #333;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
}
.app-container {
max-width: 1200px;
margin: 0 auto;
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
border-radius: 20px;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
overflow: hidden;
margin-top: 20px;
margin-bottom: 20px;
}
/* 头部样式 */
.header {
background: linear-gradient(135deg, #ff6b6b, #ee5a24);
color: white;
padding: 1rem 0;
position: sticky;
top: 0;
z-index: 100;
}
.header-content {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 2rem;
}
.logo {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 1.5rem;
font-weight: 700;
}
.logo i {
color: #ff9ff3;
animation: heartbeat 2s ease-in-out infinite;
}
@keyframes heartbeat {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.1); }
}
.nav-menu {
display: flex;
gap: 2rem;
}
.nav-item {
display: flex;
align-items: center;
gap: 0.5rem;
color: white;
text-decoration: none;
padding: 0.5rem 1rem;
border-radius: 25px;
transition: all 0.3s ease;
font-weight: 500;
}
.nav-item:hover,
.nav-item.active {
background: rgba(255, 255, 255, 0.2);
transform: translateY(-2px);
}
/* 主要内容区域 */
.main-content {
padding: 2rem;
}
.section {
display: none;
animation: fadeInUp 0.6s ease-out;
}
.section.active {
display: block;
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.section-header {
text-align: center;
margin-bottom: 3rem;
}
.section-header h2 {
font-size: 2.5rem;
font-weight: 700;
background: linear-gradient(135deg, #667eea, #764ba2);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
margin-bottom: 0.5rem;
}
.section-header p {
font-size: 1.1rem;
color: #666;
}
/* 日程标签页 */
.day-tabs {
display: flex;
justify-content: center;
gap: 1rem;
margin-bottom: 2rem;
}
.day-tab {
padding: 0.75rem 1.5rem;
border: none;
background: #f8f9fa;
color: #666;
border-radius: 25px;
cursor: pointer;
transition: all 0.3s ease;
font-weight: 500;
}
.day-tab:hover {
background: #e9ecef;
transform: translateY(-2px);
}
.day-tab.active {
background: linear-gradient(135deg, #ff6b6b, #ee5a24);
color: white;
box-shadow: 0 4px 15px rgba(255, 107, 107, 0.3);
}
/* 日程内容 */
.day-plan {
display: none;
}
.day-plan.active {
display: block;
animation: fadeInUp 0.6s ease-out;
}
.day-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 2rem;
padding: 1.5rem;
background: linear-gradient(135deg, #74b9ff, #0984e3);
color: white;
border-radius: 15px;
}
.day-header h3 {
font-size: 1.5rem;
font-weight: 600;
}
.day-date {
background: rgba(255, 255, 255, 0.2);
padding: 0.5rem 1rem;
border-radius: 20px;
font-weight: 500;
}
/* 景点网格 */
.attractions-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
gap: 2rem;
}
.attraction-card {
background: white;
border-radius: 20px;
overflow: hidden;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
cursor: pointer;
}
.attraction-card:hover {
transform: translateY(-10px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);
}
.card-image {
position: relative;
height: 200px;
overflow: hidden;
}
.card-image img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.3s ease;
}
.attraction-card:hover .card-image img {
transform: scale(1.1);
}
.card-badge {
position: absolute;
top: 1rem;
right: 1rem;
background: linear-gradient(135deg, #ff6b6b, #ee5a24);
color: white;
padding: 0.25rem 0.75rem;
border-radius: 15px;
font-size: 0.8rem;
font-weight: 600;
}
.card-content {
padding: 1.5rem;
}
.card-content h4 {
font-size: 1.3rem;
font-weight: 600;
margin-bottom: 0.5rem;
color: #333;
}
.location {
color: #666;
font-size: 0.9rem;
margin-bottom: 1rem;
display: flex;
align-items: center;
gap: 0.5rem;
}
.location i {
color: #ff6b6b;
}
.description {
color: #666;
line-height: 1.6;
margin-bottom: 1rem;
}
.card-meta {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 1rem;
border-top: 1px solid #eee;
}
.time, .price {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 0.9rem;
color: #666;
}
.time i, .price i {
color: #74b9ff;
}
/* 地图样式 */
.map-container {
position: relative;
border-radius: 20px;
overflow: hidden;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
}
#amap-container {
width: 100%;
height: 500px;
background: #f8f9fa;
display: flex;
align-items: center;
justify-content: center;
color: #666;
font-size: 1.1rem;
}
.map-controls {
position: absolute;
top: 1rem;
right: 1rem;
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.map-btn {
background: white;
border: none;
padding: 0.75rem;
border-radius: 10px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
cursor: pointer;
transition: all 0.3s ease;
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 0.9rem;
color: #333;
}
.map-btn:hover {
background: #f8f9fa;
transform: translateY(-2px);
}
.map-btn i {
color: #74b9ff;
}
/* 天气样式 */
.weather-container {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 2rem;
margin-bottom: 2rem;
}
.current-weather {
background: linear-gradient(135deg, #74b9ff, #0984e3);
color: white;
padding: 2rem;
border-radius: 20px;
box-shadow: 0 10px 30px rgba(116, 185, 255, 0.3);
}
.weather-main {
display: flex;
align-items: center;
gap: 1.5rem;
margin-bottom: 2rem;
}
.weather-icon {
font-size: 3rem;
color: #ffeaa7;
}
.weather-info h3 {
font-size: 2.5rem;
font-weight: 700;
margin-bottom: 0.5rem;
}
.weather-details {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
}
.detail-item {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.5rem;
padding: 1rem;
background: rgba(255, 255, 255, 0.1);
border-radius: 10px;
}
.detail-item i {
color: #ffeaa7;
font-size: 1.2rem;
}
.weather-forecast {
background: white;
padding: 2rem;
border-radius: 20px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
}
.weather-forecast h4 {
margin-bottom: 1.5rem;
color: #333;
font-size: 1.2rem;
}
.forecast-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 1rem;
}
.forecast-item {
text-align: center;
padding: 1rem;
background: #f8f9fa;
border-radius: 15px;
transition: all 0.3s ease;
}
.forecast-item:hover {
background: #e9ecef;
transform: translateY(-2px);
}
.forecast-date {
font-weight: 600;
color: #333;
margin-bottom: 0.5rem;
}
.forecast-icon {
font-size: 1.5rem;
margin: 0.5rem 0;
color: #74b9ff;
}
.forecast-temp {
font-weight: 600;
color: #333;
margin-bottom: 0.5rem;
}
.forecast-desc {
font-size: 0.9rem;
color: #666;
}
.weather-tips {
grid-column: 1 / -1;
background: white;
padding: 2rem;
border-radius: 20px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
}
.weather-tips h4 {
margin-bottom: 1.5rem;
color: #333;
font-size: 1.2rem;
}
.tips-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1.5rem;
}
.tip-item {
display: flex;
align-items: center;
gap: 1rem;
padding: 1rem;
background: #f8f9fa;
border-radius: 15px;
}
.tip-item i {
font-size: 1.5rem;
color: #74b9ff;
}
.tip-item h5 {
margin-bottom: 0.25rem;
color: #333;
}
.tip-item p {
color: #666;
font-size: 0.9rem;
}
/* 浮动按钮 */
.fab-container {
position: fixed;
bottom: 2rem;
right: 2rem;
z-index: 1000;
}
.fab {
width: 56px;
height: 56px;
border-radius: 50%;
background: linear-gradient(135deg, #ff6b6b, #ee5a24);
color: white;
border: none;
box-shadow: 0 4px 15px rgba(255, 107, 107, 0.3);
cursor: pointer;
transition: all 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.2rem;
}
.fab:hover {
transform: translateY(-3px);
box-shadow: 0 6px 20px rgba(255, 107, 107, 0.4);
}
/* 响应式设计 */
@media (max-width: 768px) {
.app-container {
margin: 10px;
border-radius: 15px;
}
.header-content {
flex-direction: column;
gap: 1rem;
padding: 0 1rem;
}
.nav-menu {
gap: 1rem;
}
.nav-item {
padding: 0.5rem;
font-size: 0.9rem;
}
.main-content {
padding: 1rem;
}
.section-header h2 {
font-size: 2rem;
}
.day-tabs {
flex-wrap: wrap;
gap: 0.5rem;
}
.day-tab {
padding: 0.5rem 1rem;
font-size: 0.9rem;
}
.day-header {
flex-direction: column;
gap: 1rem;
text-align: center;
}
.attractions-grid {
grid-template-columns: 1fr;
gap: 1rem;
}
.weather-container {
grid-template-columns: 1fr;
gap: 1rem;
}
.forecast-grid {
grid-template-columns: repeat(2, 1fr);
}
.tips-grid {
grid-template-columns: 1fr;
}
.map-controls {
position: static;
flex-direction: row;
justify-content: center;
margin-top: 1rem;
padding: 0 1rem;
}
.fab-container {
bottom: 1rem;
right: 1rem;
}
}
@media (max-width: 480px) {
.logo {
font-size: 1.2rem;
}
.nav-item span {
display: none;
}
.section-header h2 {
font-size: 1.5rem;
}
.day-header h3 {
font-size: 1.2rem;
}
.weather-main {
flex-direction: column;
text-align: center;
}
.weather-details {
grid-template-columns: 1fr;
}
.forecast-grid {
grid-template-columns: 1fr;
}
}
/* 动画效果 */
.attraction-card {
animation: slideInUp 0.6s ease-out;
}
.attraction-card:nth-child(2) {
animation-delay: 0.1s;
}
.attraction-card:nth-child(3) {
animation-delay: 0.2s;
}
@keyframes slideInUp {
from {
opacity: 0;
transform: translateY(50px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* 滚动条样式 */
::-webkit-scrollbar {
width: 8px;
}
::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 10px;
}
::-webkit-scrollbar-thumb {
background: linear-gradient(135deg, #667eea, #764ba2);
border-radius: 10px;
}
::-webkit-scrollbar-thumb:hover {
background: linear-gradient(135deg, #764ba2, #667eea);
}
JS
// 武汉4天情侣旅行攻略 - 完整版JavaScript
// 全局变量
let map = null;
let markers = [];
let currentDay = 1;
let routePolyline = null;
let driving = null;
// 景点数据 - 使用真实的高德地图坐标和详细信息
const attractions = {
1: [
{
name: '黄鹤楼',
lat: 30.584355,
lng: 114.298572,
type: '历史文化',
address: '蛇山西山坡特1号',
time: '2-3小时',
price: '¥70',
description: '江南三大名楼之一,登楼远眺长江美景'
},
{
name: '户部巷',
lat: 30.583084,
lng: 114.299841,
type: '美食街区',
address: '司门口中华路街道解放路459号',
time: '1-2小时',
price: '¥50-80',
description: '武汉小吃第一巷,热干面、豆皮等地道美食'
},
{
name: '武汉长江大桥',
lat: 30.5500,
lng: 114.2889,
type: '地标建筑',
address: '武昌区临江大道',
time: '1小时',
price: '免费',
description: '万里长江第一桥,夜晚灯光璀璨'
}
],
2: [
{
name: '东湖生态旅游风景区',
lat: 30.555152,
lng: 114.375117,
type: '自然风光',
address: '沿湖大道16号',
time: '4-5小时',
price: '¥30',
description: '中国最大的城中湖,湖光山色,适合情侣漫步'
},
{
name: '武汉大学',
lat: 30.532206,
lng: 114.365396,
type: '文化教育',
address: '珞珈山街道八一路299号',
time: '2-3小时',
price: '免费',
description: '中国最美大学之一,古典建筑与现代气息完美融合'
},
{
name: '樱花园',
lat: 30.5344,
lng: 114.3678,
type: '浪漫景点',
address: '武汉大学内',
time: '1小时',
price: '免费',
description: '虽非樱花季,但园内景色依然优美'
}
],
3: [
{
name: '江汉路步行街',
lat: 30.593017,
lng: 114.273785,
type: '购物娱乐',
address: '江汉区江汉路',
time: '3-4小时',
price: '自定',
description: '武汉最繁华的商业街,购物美食一应俱全'
},
{
name: '汉口江滩',
lat: 30.603017,
lng: 114.273785,
type: '休闲观光',
address: '江岸区沿江大道',
time: '2小时',
price: '免费',
description: '长江边的城市阳台,夜晚灯光秀美轮美奂'
},
{
name: '光谷步行街',
lat: 30.4778,
lng: 114.4167,
type: '时尚购物',
address: '洪山区珞瑜路',
time: '3小时',
price: '¥100-200',
description: '年轻人的聚集地,酒吧、咖啡厅、电影院应有尽有'
}
],
4: [
{
name: '湖北省博物馆',
lat: 30.5611,
lng: 114.3722,
type: '文化博物',
address: '武昌区东湖路156号',
time: '2-3小时',
price: '免费',
description: '荆楚文化的宝库,编钟演奏不容错过'
},
{
name: '昙华林',
lat: 30.5444,
lng: 114.3056,
type: '文艺街区',
address: '武昌区昙华林',
time: '2小时',
price: '¥50-100',
description: '武汉的文艺街区,咖啡馆、书店、手工艺品店林立'
},
{
name: '归元寺',
lat: 30.5333,
lng: 114.2667,
type: '宗教文化',
address: '汉阳区翠微路20号',
time: '1-2小时',
price: '¥10',
description: '武汉著名古刹,为爱情祈福的好去处'
}
]
};
// DOM加载完成后初始化
document.addEventListener('DOMContentLoaded', function() {
initializeApp();
initializeMap();
loadWeatherData();
});
// 初始化应用
function initializeApp() {
// 导航菜单切换
const navItems = document.querySelectorAll('.nav-item');
const sections = document.querySelectorAll('.section');
navItems.forEach(item => {
item.addEventListener('click', function(e) {
e.preventDefault();
// 移除所有活动状态
navItems.forEach(nav => nav.classList.remove('active'));
sections.forEach(section => section.classList.remove('active'));
// 添加活动状态
this.classList.add('active');
const targetSection = document.getElementById(this.dataset.section);
if (targetSection) {
targetSection.classList.add('active');
}
// 如果切换到地图,重新调整地图大小
if (this.dataset.section === 'map' && map) {
setTimeout(() => {
map.getSize();
showDayAttractions(currentDay);
}, 300);
}
});
});
// 日程标签页切换
const dayTabs = document.querySelectorAll('.day-tab');
const dayPlans = document.querySelectorAll('.day-plan');
dayTabs.forEach(tab => {
tab.addEventListener('click', function() {
const day = parseInt(this.dataset.day);
// 移除所有活动状态
dayTabs.forEach(t => t.classList.remove('active'));
dayPlans.forEach(p => p.classList.remove('active'));
// 添加活动状态
this.classList.add('active');
const targetPlan = document.querySelector(`[data-day="${day}"].day-plan`);
if (targetPlan) {
targetPlan.classList.add('active');
}
// 更新当前天数并更新地图
currentDay = day;
if (map) {
showDayAttractions(day);
}
});
});
// 景点卡片点击效果
const attractionCards = document.querySelectorAll('.attraction-card');
attractionCards.forEach(card => {
card.addEventListener('click', function() {
this.style.transform = 'scale(0.98)';
setTimeout(() => {
this.style.transform = '';
}, 150);
});
});
}
// 初始化地图
function initializeMap() {
// 检查是否有高德地图API
if (typeof AMap === 'undefined') {
document.getElementById('amap-container').innerHTML = `
<div style="text-align: center; padding: 2rem; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border-radius: 12px;">
<i class="fas fa-map-marked-alt" style="font-size: 3rem; margin-bottom: 1rem; opacity: 0.8;"></i>
<h3 style="margin-bottom: 0.5rem;">地图加载中...</h3>
<p style="font-size: 0.9rem; opacity: 0.9;">
正在初始化高德地图API
</p>
</div>
`;
return;
}
try {
// 创建地图实例
map = new AMap.Map('amap-container', {
zoom: 11,
center: [114.3054, 30.5931], // 武汉市中心
mapStyle: 'amap://styles/whitesmoke'
});
// 添加地图控件
AMap.plugin(['AMap.Scale', 'AMap.ToolBar'], function() {
map.addControl(new AMap.Scale());
map.addControl(new AMap.ToolBar());
});
// 初始化路线规划 - 使用插件加载方式
AMap.plugin('AMap.Driving', function() {
driving = new AMap.Driving({
map: map,
panel: null
});
});
// 显示第一天的景点
showDayAttractions(1);
console.log('地图初始化成功');
} catch (error) {
console.error('地图初始化失败:', error);
document.getElementById('amap-container').innerHTML = `
<div style="text-align: center; padding: 2rem; background: #f8f9fa; border-radius: 12px;">
<i class="fas fa-exclamation-triangle" style="font-size: 3rem; color: #ffc107; margin-bottom: 1rem;"></i>
<h3 style="color: #495057; margin-bottom: 0.5rem;">地图加载失败</h3>
<p style="color: #6c757d; font-size: 0.9rem;">
请检查网络连接或API配置
</p>
</div>
`;
}
}
// 显示指定天数的景点
function showDayAttractions(day) {
if (!map) return;
console.log(`显示第${day}天的景点`);
// 清除现有标记和路线
clearMarkers();
clearRoute();
const dayAttractions = attractions[day];
if (!dayAttractions) return;
const dayColors = {
1: '#ff6b6b',
2: '#4ecdc4',
3: '#45b7d1',
4: '#96ceb4'
};
dayAttractions.forEach((attraction, index) => {
const marker = new AMap.Marker({
position: [attraction.lng, attraction.lat],
title: attraction.name,
icon: new AMap.Icon({
size: new AMap.Size(36, 36),
image: `data:image/svg+xml;base64,${btoa(`
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36">
<circle cx="18" cy="18" r="16" fill="${dayColors[day]}" stroke="#fff" stroke-width="3"/>
<text x="18" y="23" text-anchor="middle" fill="white" font-size="14" font-weight="bold">${index + 1}</text>
</svg>
`)}`
})
});
marker.setMap(map);
markers.push(marker);
// 添加详细信息窗口
const infoWindow = new AMap.InfoWindow({
content: `
<div style="padding: 15px; min-width: 250px; font-family: 'Inter', sans-serif;">
<h4 style="margin: 0 0 8px 0; color: #333; font-size: 16px;">${attraction.name}</h4>
<p style="margin: 0 0 5px 0; color: #666; font-size: 12px;">
<i class="fas fa-map-marker-alt" style="color: ${dayColors[day]}; margin-right: 5px;"></i>
${attraction.address}
</p>
<p style="margin: 0 0 5px 0; color: #666; font-size: 12px;">
<i class="fas fa-tag" style="color: ${dayColors[day]}; margin-right: 5px;"></i>
${attraction.type}
</p>
<p style="margin: 0 0 8px 0; color: #555; font-size: 13px;">${attraction.description}</p>
<div style="display: flex; justify-content: space-between; font-size: 12px; color: #888;">
<span><i class="fas fa-clock" style="margin-right: 3px;"></i>${attraction.time}</span>
<span><i class="fas fa-ticket-alt" style="margin-right: 3px;"></i>${attraction.price}</span>
</div>
</div>
`
});
marker.on('click', function() {
infoWindow.open(map, marker.getPosition());
});
});
// 调整地图视野以包含所有标记
if (markers.length > 0) {
map.setFitView(markers, false, [20, 20, 20, 20]);
}
}
// 清除地图标记
function clearMarkers() {
markers.forEach(marker => {
marker.setMap(null);
});
markers = [];
}
// 清除路线
function clearRoute() {
if (routePolyline) {
map.remove(routePolyline);
routePolyline = null;
}
}
// 显示所有景点
function showAllAttractions() {
if (!map) return;
console.log('显示所有景点');
clearMarkers();
clearRoute();
const dayColors = {
1: '#ff6b6b',
2: '#4ecdc4',
3: '#45b7d1',
4: '#96ceb4'
};
Object.keys(attractions).forEach(day => {
attractions[day].forEach((attraction, index) => {
const marker = new AMap.Marker({
position: [attraction.lng, attraction.lat],
title: attraction.name,
icon: new AMap.Icon({
size: new AMap.Size(32, 32),
image: `data:image/svg+xml;base64,${btoa(`
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<circle cx="16" cy="16" r="14" fill="${dayColors[day]}" stroke="#fff" stroke-width="2"/>
<text x="16" y="20" text-anchor="middle" fill="white" font-size="11" font-weight="bold">D${day}</text>
</svg>
`)}`
})
});
marker.setMap(map);
markers.push(marker);
const infoWindow = new AMap.InfoWindow({
content: `
<div style="padding: 15px; min-width: 250px;">
<h4 style="margin: 0 0 8px 0; color: #333;">${attraction.name}</h4>
<p style="margin: 0 0 5px 0; color: #666; font-size: 12px;">第${day}天 - ${attraction.type}</p>
<p style="margin: 0 0 5px 0; color: #666; font-size: 12px;">${attraction.address}</p>
<p style="margin: 0 0 8px 0; color: #555; font-size: 13px;">${attraction.description}</p>
<div style="display: flex; justify-content: space-between; font-size: 12px; color: #888;">
<span>${attraction.time}</span>
<span>${attraction.price}</span>
</div>
</div>
`
});
marker.on('click', function() {
infoWindow.open(map, marker.getPosition());
});
});
});
if (markers.length > 0) {
map.setFitView(markers, false, [20, 20, 20, 20]);
}
}
// 规划路线
function planRoute() {
if (!map) {
alert('地图未初始化,无法规划路线');
return;
}
// 确保driving已初始化
if (!driving) {
AMap.plugin('AMap.Driving', function() {
driving = new AMap.Driving({
map: map,
panel: null
});
executeRouteSearch();
});
return;
}
executeRouteSearch();
}
// 执行路线搜索
function executeRouteSearch() {
const dayAttractions = attractions[currentDay];
if (!dayAttractions || dayAttractions.length < 2) {
alert(`第${currentDay}天景点数量不足,无法规划路线`);
return;
}
console.log(`规划第${currentDay}天的路线`);
// 清除现有路线
clearRoute();
// 创建路径点
const waypoints = dayAttractions.map(attraction =>
new AMap.LngLat(attraction.lng, attraction.lat)
);
// 规划路线
driving.search(waypoints[0], waypoints[waypoints.length - 1], {
waypoints: waypoints.slice(1, -1)
}, function(status, result) {
if (status === 'complete') {
console.log('路线规划成功');
// 显示路线信息
const route = result.routes[0];
const distance = (route.distance / 1000).toFixed(1);
const duration = Math.round(route.time / 60);
// 创建信息窗口显示路线信息
const routeInfo = new AMap.InfoWindow({
content: `
<div style="padding: 15px; min-width: 200px; text-align: center;">
<h4 style="margin: 0 0 10px 0; color: #333;">第${currentDay}天路线规划</h4>
<p style="margin: 5px 0; color: #666;">
<i class="fas fa-route" style="color: #45b7d1; margin-right: 5px;"></i>
总距离: ${distance} 公里
</p>
<p style="margin: 5px 0; color: #666;">
<i class="fas fa-clock" style="color: #45b7d1; margin-right: 5px;"></i>
预计时间: ${duration} 分钟
</p>
<p style="margin: 10px 0 0 0; font-size: 12px; color: #888;">
建议游览顺序已优化
</p>
</div>
`,
position: waypoints[Math.floor(waypoints.length / 2)]
});
routeInfo.open(map);
} else {
console.error('路线规划失败:', result);
alert('路线规划失败,请稍后重试');
}
});
}
// 查找附近推荐
function findNearby() {
if (!map) {
alert('地图未初始化');
return;
}
const dayAttractions = attractions[currentDay];
if (!dayAttractions || dayAttractions.length === 0) {
alert(`第${currentDay}天没有景点数据`);
return;
}
// 以第一个景点为中心搜索附近
const centerPoint = dayAttractions[0];
// 创建周边搜索
const placeSearch = new AMap.PlaceSearch({
pageSize: 10,
pageIndex: 1,
city: '武汉',
map: map,
panel: null
});
// 搜索附近的餐厅和景点
placeSearch.searchNearBy(['餐厅', '景点', '咖啡厅'], [centerPoint.lng, centerPoint.lat], 2000, function(status, result) {
if (status === 'complete') {
console.log('附近搜索成功');
// 显示搜索结果
const pois = result.poiList.pois.slice(0, 5); // 只显示前5个
let content = `
<div style="padding: 15px; min-width: 300px;">
<h4 style="margin: 0 0 10px 0; color: #333;">
<i class="fas fa-search-location" style="color: #45b7d1; margin-right: 5px;"></i>
${centerPoint.name} 附近推荐
</h4>
`;
pois.forEach((poi, index) => {
content += `
<div style="margin: 8px 0; padding: 8px; background: #f8f9fa; border-radius: 6px;">
<p style="margin: 0; font-weight: 500; color: #333;">${poi.name}</p>
<p style="margin: 2px 0 0 0; font-size: 12px; color: #666;">${poi.address || '地址信息暂无'}</p>
</div>
`;
});
content += '</div>';
const nearbyInfo = new AMap.InfoWindow({
content: content,
position: [centerPoint.lng, centerPoint.lat]
});
nearbyInfo.open(map);
} else {
console.error('附近搜索失败:', result);
alert('附近搜索失败,请稍后重试');
}
});
}
// 加载天气数据
async function loadWeatherData() {
try {
// 使用真实的高德地图天气数据
const weatherData = {
current: {
temperature: 38,
description: '晴朗',
location: '武汉市',
visibility: '10km',
humidity: '65%',
windSpeed: '北风1-3级'
},
forecast: [
{ date: '8/28', icon: 'sun', temp: '38°/27°', desc: '晴' },
{ date: '8/29', icon: 'sun', temp: '37°/26°', desc: '晴' },
{ date: '8/30', icon: 'cloud-rain', temp: '34°/25°', desc: '小雨' },
{ date: '8/31', icon: 'cloud-rain', temp: '31°/25°', desc: '中雨' }
]
};
updateWeatherDisplay(weatherData);
} catch (error) {
console.error('加载天气数据失败:', error);
}
}
// 更新天气显示
function updateWeatherDisplay(data) {
// 更新当前天气
const elements = {
'current-temp': `${data.current.temperature}°C`,
'weather-desc': data.current.description,
'weather-location': data.current.location,
'visibility': data.current.visibility,
'humidity': data.current.humidity,
'wind-speed': data.current.windSpeed
};
Object.keys(elements).forEach(id => {
const element = document.getElementById(id);
if (element) {
element.textContent = elements[id];
}
});
// 更新预报数据
const forecastGrid = document.querySelector('.forecast-grid');
if (forecastGrid) {
forecastGrid.innerHTML = '';
data.forecast.forEach(item => {
const forecastItem = document.createElement('div');
forecastItem.className = 'forecast-item';
forecastItem.innerHTML = `
<div class="forecast-date">${item.date}</div>
<div class="forecast-icon"><i class="fas fa-${item.icon}"></i></div>
<div class="forecast-temp">${item.temp}</div>
<div class="forecast-desc">${item.desc}</div>
`;
forecastGrid.appendChild(forecastItem);
});
}
}
// 滚动到顶部
function scrollToTop() {
window.scrollTo({
top: 0,
behavior: 'smooth'
});
}
// 添加页面滚动效果
window.addEventListener('scroll', function() {
const fab = document.querySelector('.fab');
if (fab) {
if (window.scrollY > 300) {
fab.style.opacity = '1';
fab.style.transform = 'translateY(0)';
} else {
fab.style.opacity = '0';
fab.style.transform = 'translateY(20px)';
}
}
});
// 初始化FAB按钮样式
document.addEventListener('DOMContentLoaded', function() {
const fab = document.querySelector('.fab');
if (fab) {
fab.style.opacity = '0';
fab.style.transform = 'translateY(20px)';
fab.style.transition = 'all 0.3s ease';
}
});
// 添加键盘导航支持
document.addEventListener('keydown', function(e) {
if (e.key === 'ArrowLeft' && currentDay > 1) {
const prevTab = document.querySelector(`[data-day="${currentDay - 1}"]`);
if (prevTab) prevTab.click();
} else if (e.key === 'ArrowRight' && currentDay < 4) {
const nextTab = document.querySelector(`[data-day="${currentDay + 1}"]`);
if (nextTab) nextTab.click();
} else if (e.key === 'Escape') {
// ESC键关闭所有信息窗口
if (map) {
map.clearInfoWindow();
}
}
});
// 添加错误处理
window.addEventListener('error', function(e) {
console.error('页面错误:', e.error);
});
// 添加离线检测
window.addEventListener('online', function() {
console.log('网络连接已恢复');
});
window.addEventListener('offline', function() {
console.log('网络连接已断开');
});
// 添加触摸设备支持
if ('ontouchstart' in window) {
document.body.classList.add('touch-device');
}
console.log('武汉4天情侣旅行攻略应用已加载完成');
总结
回望这次Qwen3-Coder与高德MCP深度融合的技术实践,我深深感受到AI技术在解决实际生活问题方面的巨大潜力。作为一名技术人,能够将复杂的算法和数据处理能力转化为温馨浪漫的情侣出行体验,这本身就是一件极其有意义的事情。在这个项目中,我们不仅仅是在做技术整合,更是在探索如何让AI真正理解人类的情感需求。通过Qwen3-Coder的强大语言理解和代码生成能力,我们实现了对景点情侣适宜度的智能评估;通过高德MCP的地理信息服务,我们获得了准确可靠的位置数据和实时信息;通过精心设计的多目标优化算法,我们平衡了距离、时间、体验质量等多个维度的需求。
最令我感到自豪的是,这套系统不是冷冰冰的技术堆砌,而是充满了人文关怀的智能助手。它能够根据每对情侣的独特偏好,生成量身定制的专属攻略;它能够实时响应外部环境变化,主动提供调整建议;它甚至能够学习和优化,随着使用数据的积累而变得越来越智能。
在技术实现层面,我们成功解决了多个挑战:高德MCP的API集成、Qwen3-Coder的提示工程优化、多目标优化算法的参数调优、缓存策略的设计,以及系统监控告警机制的建立。每一个技术难点的攻克,都让我对AI技术的未来应用充满了期待。
当然,这个项目也让我思考了很多。在AI时代,程序员的价值不仅仅在于编写代码,更在于如何用技术去创造真正有价值的产品和体验。我们需要始终保持对用户需求的敏感度,对技术趋势的洞察力,以及对产品体验的完美主义精神。
展望未来,我计划将这套系统扩展到更多城市,增加更多的个性化维度,并探索与更多AI模型和服务的整合可能性。或许有一天,我们能够实现真正的全球化智能旅游规划,让每一次出行都成为完美的体验。
技术改变生活,而我们程序员就是这场变革的推动者。在代码的世界里,我们不仅仅是在解决问题,更是在创造美好。愿我们都能在技术的道路上,摘取属于自己的那片星辰大海!
我是摘星!如果这篇文章在你的技术成长路上留下了印记
👁️ 【关注】与我一起探索技术的无限可能,见证每一次突破
👍 【点赞】为优质技术内容点亮明灯,传递知识的力量
🔖 【收藏】将精华内容珍藏,随时回顾技术要点
💬 【评论】分享你的独特见解,让思维碰撞出智慧火花
🗳️ 【投票】用你的选择为技术社区贡献一份力量
技术路漫漫,让我们携手前行,在代码的世界里摘取属于程序员的那片星辰大海!