yangg 3 days ago
parent
commit
79cd2e85d8

+ 127 - 0
MAP_INTEGRATION_SUMMARY.md

@@ -0,0 +1,127 @@
+# 高德地图集成总结
+
+## 已完成的工作
+
+### 1. 创建了 AmapDisplay 组件
+- 位置:`src/components/AmapDisplay/index.vue`
+- 功能:基于高德地图API的Vue3地图组件
+- 特性:
+  - 支持动态显示/隐藏
+  - 可配置地图中心点
+  - 包含地图标记和信息窗体
+  - 响应式设计,支持深色主题
+  - 自动处理地图的创建和销毁
+
+### 2. 在 report.vue 中集成了地图组件
+- 添加了地图相关的响应式状态:
+  ```javascript
+  const mapDisplay = ref(false);
+  const mapCenter = ref({ lng: 121.265276, lat: 31.375566 });
+  ```
+- 在SSE消息处理中添加了地图数据处理:
+  ```javascript
+  case 'final_summary':
+    if (data.map_display) {
+      mapDisplay.value = true;
+      if (data.center) {
+        mapCenter.value = data.center;
+      }
+    }
+    break;
+  ```
+- 在模板中添加了地图组件:
+  ```vue
+  <AmapDisplay 
+    v-if="mapDisplay"
+    :mapDisplay="mapDisplay"
+    :center="mapCenter"
+  />
+  ```
+
+### 3. 配置了高德地图SDK
+- 在 `index.html` 中添加了高德地图SDK引用
+- 提供了配置说明和API密钥占位符
+
+### 4. 创建了详细的使用文档
+- 组件使用说明:`src/components/AmapDisplay/README.md`
+- 包含完整的API文档和使用示例
+
+## 使用方法
+
+### 后端数据格式
+当后端返回的数据包含以下字段时,地图会自动显示:
+
+```json
+{
+  "map_display": true,
+  "center": {
+    "lng": 121.265276,
+    "lat": 31.375566
+  }
+}
+```
+
+### 前端显示逻辑
+1. 当 `map_display` 为 `true` 时,地图组件显示
+2. 地图中心点根据 `center` 字段的 `lng` 和 `lat` 值设置
+3. 地图会自动创建标记点,点击可查看详细信息
+
+## 配置要求
+
+### 1. 高德地图API密钥
+已在 `index.html` 中配置高德地图API密钥:
+```html
+<script src="https://webapi.amap.com/maps?v=2.0&key=c2f5532f8238a3523a9f381cb3e630c8"></script>
+```
+
+### 2. 网络连接
+地图组件需要网络连接才能加载高德地图服务
+
+## 组件特性
+
+- **自动管理**:根据 `mapDisplay` 字段自动显示/隐藏
+- **动态更新**:支持实时更新地图中心点
+- **响应式设计**:适配移动端和桌面端
+- **主题支持**:支持浅色和深色主题
+- **错误处理**:包含完整的错误处理和日志记录
+- **性能优化**:自动销毁和重新初始化,避免内存泄漏
+
+## 测试功能
+
+组件包含一个测试按钮,当地图未加载时显示,可以手动触发地图初始化,方便开发和调试。
+
+## 注意事项
+
+1. **API密钥**:确保使用有效的高德地图API密钥
+2. **坐标系统**:使用WGS84坐标系
+3. **网络依赖**:需要稳定的网络连接
+4. **浏览器兼容性**:支持现代浏览器
+5. **移动端适配**:已针对移动设备进行了优化
+
+## 扩展建议
+
+1. **多标记支持**:可以扩展支持多个位置标记
+2. **路线规划**:可以添加路线规划功能
+3. **地理编码**:可以添加地址搜索和地理编码功能
+4. **离线地图**:可以考虑添加离线地图支持
+5. **自定义样式**:可以添加更多地图样式选项
+
+## 文件结构
+
+```
+src/
+├── components/
+│   └── AmapDisplay/
+│       ├── index.vue          # 地图组件主文件
+│       └── README.md          # 使用说明文档
+├── views/
+│   └── report.vue             # 已集成地图组件
+└── index.html                 # 包含高德地图SDK
+```
+
+## 下一步
+
+1. ✅ 已配置高德地图API密钥
+2. 测试地图组件的显示和交互功能
+3. 根据实际需求调整地图样式和功能
+4. 考虑添加更多地图相关的功能特性

+ 3 - 0
index.html

@@ -6,6 +6,9 @@
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
     <title></title>
+    <!-- 高德地图SDK -->
+    <!-- 高德地图API密钥 -->
+    <script type="text/javascript" src="https://webapi.amap.com/maps?v=2.0&key=c2f5532f8238a3523a9f381cb3e630c8"></script>
   </head>
   <body>
     <div id="app"></div>

BIN
src/assets/map.png


+ 141 - 0
src/components/AmapDisplay/README.md

@@ -0,0 +1,141 @@
+# AmapDisplay 高德地图组件
+
+## 功能特性
+
+- 基础地图显示
+- 位置标记
+- **路线规划与绘制**(新增功能)
+- 深色主题支持
+- 响应式设计
+
+## 路线绘制功能
+
+### 新增的 Props 参数
+
+| 参数名 | 类型 | 默认值 | 说明 |
+|--------|------|--------|------|
+| `startPoint` | Object | `{ lng: 121.265276, lat: 31.375566 }` | 起点坐标 |
+| `endPoint` | Object | `{ lng: 121.275276, lat: 31.385566 }` | 终点坐标 |
+| `routeType` | String | `'driving'` | 路线类型:`driving`(驾车)、`walking`(步行)、`transit`(公交)、`bicycling`(骑行) |
+| `showRoute` | Boolean | `false` | 是否显示路线 |
+| `routeStyle` | Object | `{ strokeColor: '#1890ff', strokeWeight: 6, strokeOpacity: 0.8 }` | 路线样式 |
+
+### 使用示例
+
+```vue
+<template>
+  <AmapDisplay
+    :mapDisplay="true"
+    :center="{ lng: 121.265276, lat: 31.375566 }"
+    :startPoint="{ lng: 121.265276, lat: 31.375566 }"
+    :endPoint="{ lng: 121.275276, lat: 31.385566 }"
+    :routeType="'driving'"
+    :showRoute="true"
+    :routeStyle="{ strokeColor: '#52c41a', strokeWeight: 8, strokeOpacity: 0.9 }"
+  />
+</template>
+```
+
+### 路线信息显示
+
+组件会自动显示:
+- 总距离(公里)
+- 预计时间(分钟)
+- 详细路线步骤
+
+### 控制按钮
+
+- **加载地图**:初始化地图
+- **绘制路线**:根据起点和终点绘制路线
+- **清除路线**:清除当前显示的路线
+
+### 错误处理
+
+如果路线规划失败,组件会自动:
+1. 显示起点和终点标记
+2. 绘制直线连接
+3. 计算直线距离
+4. 显示错误提示
+
+### 注意事项
+
+1. **高德地图SDK要求**:确保已加载高德地图JavaScript API
+2. **坐标格式**:使用高德地图坐标系(GCJ-02)
+3. **网络要求**:路线规划需要网络连接
+4. **API限制**:注意高德地图API的使用限制和配额
+
+### 兼容性
+
+- 支持高德地图JavaScript API v1.4+
+- 自动降级处理:如果路径规划失败,会显示直线连接
+- 使用数字常量避免版本兼容性问题
+
+### 样式自定义
+
+可以通过 `routeStyle` 属性自定义路线样式:
+
+```javascript
+:routeStyle="{
+  strokeColor: '#ff4d4f',    // 路线颜色
+  strokeWeight: 8,           // 路线宽度
+  strokeOpacity: 0.8         // 路线透明度
+}"
+```
+
+### 事件监听
+
+组件会自动监听以下props变化:
+- `startPoint`:起点变化时重新绘制路线
+- `endPoint`:终点变化时重新绘制路线
+- `showRoute`:显示/隐藏路线
+- `routeType`:路线类型变化时重新计算
+
+## 完整示例
+
+```vue
+<template>
+  <div class="map-demo">
+    <AmapDisplay
+      :mapDisplay="true"
+      :center="mapCenter"
+      :startPoint="startPoint"
+      :endPoint="endPoint"
+      :routeType="routeType"
+      :showRoute="showRoute"
+      :routeStyle="routeStyle"
+    />
+    
+    <div class="controls">
+      <button @click="toggleRoute">
+        {{ showRoute ? '隐藏路线' : '显示路线' }}
+      </button>
+      <select v-model="routeType">
+        <option value="driving">驾车</option>
+        <option value="walking">步行</option>
+        <option value="transit">公交</option>
+        <option value="bicycling">骑行</option>
+      </select>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { ref } from 'vue';
+import AmapDisplay from '@/components/AmapDisplay/index.vue';
+
+const mapCenter = ref({ lng: 121.265276, lat: 31.375566 });
+const startPoint = ref({ lng: 121.265276, lat: 31.375566 });
+const endPoint = ref({ lng: 121.275276, lat: 31.385566 });
+const routeType = ref('driving');
+const showRoute = ref(false);
+const routeStyle = ref({
+  strokeColor: '#1890ff',
+  strokeWeight: 6,
+  strokeOpacity: 0.8
+});
+
+const toggleRoute = () => {
+  showRoute.value = !showRoute.value;
+};
+</script>
+```

File diff suppressed because it is too large
+ 57 - 0
src/components/AmapDisplay/index.vue


+ 69 - 3
src/views/report.vue

@@ -850,6 +850,40 @@
       
       <div class="right-menu-content">
         <!-- 添加 Tab 切换 -->
+       <!--  <div class="right-menu-tabs">
+          <div 
+            class="tab-item" 
+            :class="{ active: activeTab === 'search' }"
+            @click="activeTab = 'search'"
+          >
+            <SearchOutlined />
+            <span>搜索结果</span>
+          </div>
+          <div 
+            class="tab-item" 
+            :class="{ active: activeTab === 'preview' }"
+            @click="activeTab = 'preview'"
+          >
+            <FileOutlined />
+            <span>文档预览</span>
+          </div>
+          <div 
+            class="tab-item" 
+            :class="{ active: activeTab === 'knowledge' }"
+            @click="activeTab = 'knowledge'"
+          >
+            <DatabaseOutlined />
+            <span>知识库</span>
+          </div>
+          <div 
+            class="tab-item" 
+            :class="{ active: activeTab === 'map' }"
+            @click="activeTab = 'map'"
+          >
+            <GlobalOutlined />
+            <span>地图</span>
+          </div>
+        </div> -->
    
         <!-- 搜索面板 -->
         <div v-show="activeTab === 'search'" class="panel-container">
@@ -996,6 +1030,14 @@
             :message="currentSearchQuery"
           />
         </div>
+        <div  v-show="activeTab === 'map'" class="panel-container">
+            <!-- 地图显示区域 -->
+            <AmapDisplay 
+            v-if="mapDisplay"
+            :mapDisplay="mapDisplay"
+            :center="mapCenter"
+          />
+        </div>
       </div>
 
       
@@ -1030,7 +1072,8 @@ import {
   DownloadOutlined,
   CreditCardOutlined,
   AuditOutlined,
-  ProfileOutlined
+  ProfileOutlined,
+  SearchOutlined
 } from "@ant-design/icons-vue";
 import leftIcon from "../assets/svg/left.svg";
 import rightIcon from "../assets/svg/right.svg";
@@ -1057,6 +1100,7 @@ import dayjs from 'dayjs';
 import DocumentPreview from "../components/DocumentPreview/index.vue";
 import KnowledgeResults from "../components/KnowledgeResults/index.vue";
 import ChangePasswordDialog from '../components/ChangePasswordDialog.vue'
+import AmapDisplay from '../components/AmapDisplay/index.vue';
 import { useRouter } from 'vue-router'
 import { message } from 'ant-design-vue';
 import VueOfficeDocx from '@vue-office/docx';
@@ -1203,6 +1247,10 @@ const formatted_data = ref('');
 const showSteps = ref(false);
 const steps = ref([]);
 
+// 地图相关状态
+const mapDisplay = ref(false);
+const mapCenter = ref({ });
+
 // 进度条弹窗相关状态
 const showProgressModal = ref(false);
 const progressList = ref([]);
@@ -1248,7 +1296,13 @@ const handleSSEMessage = (event, data) => {
       updateStepElement(data.step_id, data.status, data.details, data.progress);
       break;
     case 'final_summary':
-      
+     /*  // 处理地图数据
+      if (data.map_display) {
+        mapDisplay.value = true;
+        if (data.center) {
+          mapCenter.value = data.center;
+        }
+      } */
       break;
     case 'stream_end':
       showSteps.value = false;
@@ -2238,7 +2292,19 @@ const summaryHtml=ref('')
     const messageContent = enableWebSearch.value ? responseData.answer : responseData.choices[0].message.content;
     const audioInfo = enableWebSearch.value ? responseData.audio_info?.audio : responseData.audio_info?.audio;
     const sessionId = enableWebSearch.value ? responseData.session_id : responseData.session_id;
-
+     // 处理地图数据
+     if (responseData.map_display) {
+          rightMenuWidth.value = 800;
+          isRightMenuCollapsed.value = false;
+          if (document.querySelector('.chat')) {
+            document.querySelector('.chat').style.right = `${rightMenuWidth.value}px`;
+          }
+        mapDisplay.value = true;
+        activeTab.value='map'
+        if (responseData.map_display.center) {
+          mapCenter.value = responseData.map_display.center;
+        }
+      }
     // 更新 session_id
     if (sessionId) {
       session_id.value = sessionId;

Some files were not shown because too many files changed in this diff