Initial commit
This commit is contained in:
836
前端对接指南.md
Normal file
836
前端对接指南.md
Normal file
@@ -0,0 +1,836 @@
|
||||
# 前端对接指南 - KMZ文件生成系统
|
||||
|
||||
## 📋 概述
|
||||
|
||||
本指南详细说明如何在前端应用中对接KMZ文件生成系统,包括WebSocket消息监听、API接口调用、文件下载等功能。
|
||||
|
||||
## 🔗 系统架构
|
||||
|
||||
```
|
||||
前端应用 ←→ WebSocket ←→ 后端服务 ←→ MQTT ←→ GH/YGWRXT主题
|
||||
↓
|
||||
KMZ文件下载/显示
|
||||
```
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
### 1. 环境要求
|
||||
|
||||
- 支持WebSocket的现代浏览器
|
||||
- JavaScript ES6+ 支持
|
||||
- 网络连接到后端服务
|
||||
|
||||
### 2. 基础配置
|
||||
|
||||
```javascript
|
||||
// 配置信息
|
||||
const CONFIG = {
|
||||
// WebSocket连接地址
|
||||
websocketUrl: 'ws://localhost:8080/ws',
|
||||
// API基础地址
|
||||
apiBaseUrl: 'http://localhost:8080/api/v1',
|
||||
// 工作空间ID
|
||||
workspaceId: 'e3dea0f5-37f2-4d79-ae58-490af3228069',
|
||||
// 用户类型
|
||||
userType: 1
|
||||
};
|
||||
```
|
||||
|
||||
## 📡 WebSocket连接
|
||||
|
||||
### 1. 建立连接
|
||||
|
||||
```javascript
|
||||
class WebSocketManager {
|
||||
constructor(config) {
|
||||
this.config = config;
|
||||
this.websocket = null;
|
||||
this.reconnectAttempts = 0;
|
||||
this.maxReconnectAttempts = 5;
|
||||
this.reconnectInterval = 3000;
|
||||
}
|
||||
|
||||
connect() {
|
||||
try {
|
||||
this.websocket = new WebSocket(this.config.websocketUrl);
|
||||
this.setupEventListeners();
|
||||
} catch (error) {
|
||||
console.error('WebSocket连接失败:', error);
|
||||
this.handleReconnect();
|
||||
}
|
||||
}
|
||||
|
||||
setupEventListeners() {
|
||||
this.websocket.onopen = () => {
|
||||
console.log('WebSocket连接已建立');
|
||||
this.reconnectAttempts = 0;
|
||||
};
|
||||
|
||||
this.websocket.onmessage = (event) => {
|
||||
this.handleMessage(event);
|
||||
};
|
||||
|
||||
this.websocket.onclose = () => {
|
||||
console.log('WebSocket连接已关闭');
|
||||
this.handleReconnect();
|
||||
};
|
||||
|
||||
this.websocket.onerror = (error) => {
|
||||
console.error('WebSocket错误:', error);
|
||||
};
|
||||
}
|
||||
|
||||
handleReconnect() {
|
||||
if (this.reconnectAttempts < this.maxReconnectAttempts) {
|
||||
this.reconnectAttempts++;
|
||||
console.log(`尝试重连 (${this.reconnectAttempts}/${this.maxReconnectAttempts})`);
|
||||
setTimeout(() => this.connect(), this.reconnectInterval);
|
||||
} else {
|
||||
console.error('WebSocket重连失败,已达到最大重试次数');
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 消息处理
|
||||
|
||||
```javascript
|
||||
class MessageHandler {
|
||||
constructor() {
|
||||
this.handlers = new Map();
|
||||
this.setupDefaultHandlers();
|
||||
}
|
||||
|
||||
setupDefaultHandlers() {
|
||||
// GK数据消息
|
||||
this.handlers.set('gk_data', (data) => {
|
||||
console.log('收到GK数据:', data);
|
||||
this.displayGkData(data);
|
||||
});
|
||||
|
||||
// KMZ数据消息
|
||||
this.handlers.set('kmz_data', (data) => {
|
||||
console.log('收到KMZ数据:', data);
|
||||
this.handleKmzData(data);
|
||||
});
|
||||
|
||||
// KMZ文件数据消息
|
||||
this.handlers.set('kmz_file_data', (data) => {
|
||||
console.log('收到KMZ文件数据:', data);
|
||||
this.handleKmzFileData(data);
|
||||
});
|
||||
|
||||
// KMZ生成通知
|
||||
this.handlers.set('kmz_notification', (data) => {
|
||||
console.log('KMZ文件生成通知:', data);
|
||||
this.showNotification('success', data.message);
|
||||
});
|
||||
|
||||
// KMZ生成错误
|
||||
this.handlers.set('kmz_error', (data) => {
|
||||
console.error('KMZ文件生成错误:', data);
|
||||
this.showNotification('error', data.message);
|
||||
});
|
||||
}
|
||||
|
||||
handleMessage(event) {
|
||||
try {
|
||||
const message = JSON.parse(event.data);
|
||||
const { bizCode, host } = message;
|
||||
|
||||
if (this.handlers.has(bizCode)) {
|
||||
this.handlers.get(bizCode)(host);
|
||||
} else {
|
||||
console.log('未处理的消息类型:', bizCode, host);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('消息解析失败:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🗂️ KMZ文件处理
|
||||
|
||||
### 1. KMZ数据处理器
|
||||
|
||||
```javascript
|
||||
class KmzFileHandler {
|
||||
constructor() {
|
||||
this.downloadedFiles = new Map();
|
||||
}
|
||||
|
||||
// 处理KMZ数据(不包含文件内容)
|
||||
handleKmzData(kmzData) {
|
||||
console.log('KMZ文件信息:', kmzData.kmzFile);
|
||||
|
||||
// 显示文件信息
|
||||
this.displayKmzInfo(kmzData);
|
||||
|
||||
// 提供下载按钮
|
||||
this.createDownloadButton(kmzData);
|
||||
}
|
||||
|
||||
// 处理KMZ文件数据(包含文件内容)
|
||||
handleKmzFileData(kmzData) {
|
||||
console.log('KMZ文件数据:', kmzData);
|
||||
|
||||
// 自动下载文件
|
||||
this.autoDownloadKmzFile(kmzData);
|
||||
|
||||
// 显示文件信息
|
||||
this.displayKmzInfo(kmzData);
|
||||
|
||||
// 解析并显示航点信息
|
||||
if (kmzData.waypoints) {
|
||||
this.displayWaypoints(kmzData.waypoints);
|
||||
}
|
||||
}
|
||||
|
||||
// 自动下载KMZ文件
|
||||
autoDownloadKmzFile(kmzData) {
|
||||
if (!kmzData.fileData) {
|
||||
console.warn('KMZ数据中不包含文件内容');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 解码Base64数据
|
||||
const byteCharacters = atob(kmzData.fileData);
|
||||
const byteNumbers = new Array(byteCharacters.length);
|
||||
|
||||
for (let i = 0; i < byteCharacters.length; i++) {
|
||||
byteNumbers[i] = byteCharacters.charCodeAt(i);
|
||||
}
|
||||
|
||||
const byteArray = new Uint8Array(byteNumbers);
|
||||
const blob = new Blob([byteArray], { type: 'application/zip' });
|
||||
|
||||
// 创建下载链接
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = kmzData.kmzFile.fileName;
|
||||
a.style.display = 'none';
|
||||
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
window.URL.revokeObjectURL(url);
|
||||
|
||||
console.log('KMZ文件下载完成:', kmzData.kmzFile.fileName);
|
||||
|
||||
} catch (error) {
|
||||
console.error('KMZ文件下载失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 显示KMZ文件信息
|
||||
displayKmzInfo(kmzData) {
|
||||
const infoContainer = document.getElementById('kmz-info');
|
||||
if (!infoContainer) return;
|
||||
|
||||
const fileInfo = kmzData.kmzFile;
|
||||
infoContainer.innerHTML = `
|
||||
<div class="kmz-file-info">
|
||||
<h3>KMZ文件信息</h3>
|
||||
<p><strong>文件名:</strong> ${fileInfo.fileName}</p>
|
||||
<p><strong>文件大小:</strong> ${this.formatFileSize(fileInfo.fileSize)}</p>
|
||||
<p><strong>文件类型:</strong> ${fileInfo.fileType}</p>
|
||||
<p><strong>任务ID:</strong> ${kmzData.taskId}</p>
|
||||
<p><strong>设备SN:</strong> ${kmzData.deviceSn}</p>
|
||||
<p><strong>生成时间:</strong> ${new Date(kmzData.timestamp).toLocaleString()}</p>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
// 显示航点信息
|
||||
displayWaypoints(waypoints) {
|
||||
const waypointsContainer = document.getElementById('waypoints-info');
|
||||
if (!waypointsContainer) return;
|
||||
|
||||
let waypointsHtml = '<h3>航点信息</h3><ul>';
|
||||
waypoints.forEach((waypoint, index) => {
|
||||
waypointsHtml += `
|
||||
<li>
|
||||
航点 ${index + 1}:
|
||||
经度 ${waypoint.longitude},
|
||||
纬度 ${waypoint.latitude},
|
||||
高度 ${waypoint.altitude}m
|
||||
</li>
|
||||
`;
|
||||
});
|
||||
waypointsHtml += '</ul>';
|
||||
|
||||
waypointsContainer.innerHTML = waypointsHtml;
|
||||
}
|
||||
|
||||
// 格式化文件大小
|
||||
formatFileSize(bytes) {
|
||||
if (bytes === 0) return '0 Bytes';
|
||||
const k = 1024;
|
||||
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
||||
}
|
||||
|
||||
// 创建下载按钮
|
||||
createDownloadButton(kmzData) {
|
||||
const downloadBtn = document.createElement('button');
|
||||
downloadBtn.textContent = '下载KMZ文件';
|
||||
downloadBtn.className = 'download-btn';
|
||||
downloadBtn.onclick = () => this.downloadKmzFile(kmzData);
|
||||
|
||||
const container = document.getElementById('kmz-actions');
|
||||
if (container) {
|
||||
container.appendChild(downloadBtn);
|
||||
}
|
||||
}
|
||||
|
||||
// 下载KMZ文件
|
||||
async downloadKmzFile(kmzData) {
|
||||
try {
|
||||
const response = await fetch(`${CONFIG.apiBaseUrl}/kmz/download/${kmzData.taskId}?fileType=${kmzData.fileType || 'dji'}`);
|
||||
|
||||
if (response.ok) {
|
||||
const blob = await response.blob();
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = kmzData.kmzFile.fileName;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
window.URL.revokeObjectURL(url);
|
||||
} else {
|
||||
throw new Error(`下载失败: ${response.statusText}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('下载KMZ文件失败:', error);
|
||||
this.showNotification('error', '下载失败: ' + error.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🔌 API接口调用
|
||||
|
||||
### 1. API客户端
|
||||
|
||||
```javascript
|
||||
class ApiClient {
|
||||
constructor(baseUrl) {
|
||||
this.baseUrl = baseUrl;
|
||||
}
|
||||
|
||||
async request(endpoint, options = {}) {
|
||||
const url = `${this.baseUrl}${endpoint}`;
|
||||
const defaultOptions = {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
};
|
||||
|
||||
const config = { ...defaultOptions, ...options };
|
||||
|
||||
try {
|
||||
const response = await fetch(url, config);
|
||||
const data = await response.json();
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.message || `HTTP ${response.status}`);
|
||||
}
|
||||
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.error('API请求失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// 获取KMZ文件信息
|
||||
async getKmzFileInfo(taskId, fileType = 'dji') {
|
||||
return this.request(`/kmz/info/${taskId}?fileType=${fileType}`);
|
||||
}
|
||||
|
||||
// 获取任务KMZ文件列表
|
||||
async getKmzFileList(taskId) {
|
||||
return this.request(`/kmz/list/${taskId}`);
|
||||
}
|
||||
|
||||
// 获取设备KMZ文件列表
|
||||
async getDeviceKmzFileList(deviceId) {
|
||||
return this.request(`/kmz/list/device/${deviceId}`);
|
||||
}
|
||||
|
||||
// 删除KMZ文件
|
||||
async deleteKmzFile(taskId, fileType = 'dji') {
|
||||
return this.request(`/kmz/delete/${taskId}?fileType=${fileType}`, {
|
||||
method: 'DELETE'
|
||||
});
|
||||
}
|
||||
|
||||
// 重新发送KMZ数据
|
||||
async resendKmzData(taskId, fileType = 'dji') {
|
||||
return this.request(`/kmz/resend/${taskId}?fileType=${fileType}`, {
|
||||
method: 'POST'
|
||||
});
|
||||
}
|
||||
|
||||
// 获取统计信息
|
||||
async getKmzStatistics() {
|
||||
return this.request('/kmz/statistics');
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 使用示例
|
||||
|
||||
```javascript
|
||||
// 初始化API客户端
|
||||
const apiClient = new ApiClient(CONFIG.apiBaseUrl);
|
||||
|
||||
// 获取KMZ文件信息
|
||||
async function loadKmzFileInfo(taskId) {
|
||||
try {
|
||||
const result = await apiClient.getKmzFileInfo(taskId);
|
||||
if (result.success) {
|
||||
console.log('KMZ文件信息:', result.data);
|
||||
return result.data;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取KMZ文件信息失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取任务的所有KMZ文件
|
||||
async function loadTaskKmzFiles(taskId) {
|
||||
try {
|
||||
const result = await apiClient.getKmzFileList(taskId);
|
||||
if (result.success) {
|
||||
console.log('任务KMZ文件列表:', result.data);
|
||||
return result.data;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取任务KMZ文件列表失败:', error);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🎨 用户界面组件
|
||||
|
||||
### 1. HTML结构
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>KMZ文件管理系统</title>
|
||||
<style>
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.status-indicator {
|
||||
padding: 10px;
|
||||
margin: 10px 0;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.status-connected {
|
||||
background-color: #d4edda;
|
||||
color: #155724;
|
||||
border: 1px solid #c3e6cb;
|
||||
}
|
||||
|
||||
.status-disconnected {
|
||||
background-color: #f8d7da;
|
||||
color: #721c24;
|
||||
border: 1px solid #f5c6cb;
|
||||
}
|
||||
|
||||
.kmz-file-info {
|
||||
background-color: #f8f9fa;
|
||||
padding: 15px;
|
||||
border-radius: 4px;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.waypoints-info {
|
||||
background-color: #e9ecef;
|
||||
padding: 15px;
|
||||
border-radius: 4px;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.download-btn {
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 10px 20px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.download-btn:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
|
||||
.notification {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
padding: 15px;
|
||||
border-radius: 4px;
|
||||
color: white;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.notification.success {
|
||||
background-color: #28a745;
|
||||
}
|
||||
|
||||
.notification.error {
|
||||
background-color: #dc3545;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>KMZ文件管理系统</h1>
|
||||
|
||||
<!-- 连接状态 -->
|
||||
<div id="connection-status" class="status-indicator status-disconnected">
|
||||
WebSocket未连接
|
||||
</div>
|
||||
|
||||
<!-- KMZ文件信息 -->
|
||||
<div id="kmz-info"></div>
|
||||
|
||||
<!-- 航点信息 -->
|
||||
<div id="waypoints-info"></div>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<div id="kmz-actions"></div>
|
||||
|
||||
<!-- 日志区域 -->
|
||||
<div id="log-area">
|
||||
<h3>系统日志</h3>
|
||||
<div id="log-content" style="height: 300px; overflow-y: auto; border: 1px solid #ccc; padding: 10px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="websocket-manager.js"></script>
|
||||
<script src="message-handler.js"></script>
|
||||
<script src="kmz-file-handler.js"></script>
|
||||
<script src="api-client.js"></script>
|
||||
<script src="app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
### 2. 主应用逻辑
|
||||
|
||||
```javascript
|
||||
// app.js
|
||||
class KmzApp {
|
||||
constructor() {
|
||||
this.websocketManager = new WebSocketManager(CONFIG);
|
||||
this.messageHandler = new MessageHandler();
|
||||
this.kmzFileHandler = new KmzFileHandler();
|
||||
this.apiClient = new ApiClient(CONFIG.apiBaseUrl);
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
// 设置消息处理器
|
||||
this.websocketManager.onMessage = (data) => {
|
||||
this.messageHandler.handleMessage(data);
|
||||
};
|
||||
|
||||
// 连接WebSocket
|
||||
this.websocketManager.connect();
|
||||
|
||||
// 更新连接状态
|
||||
this.updateConnectionStatus();
|
||||
|
||||
// 设置定时器更新状态
|
||||
setInterval(() => {
|
||||
this.updateConnectionStatus();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
updateConnectionStatus() {
|
||||
const statusElement = document.getElementById('connection-status');
|
||||
if (this.websocketManager.websocket &&
|
||||
this.websocketManager.websocket.readyState === WebSocket.OPEN) {
|
||||
statusElement.textContent = 'WebSocket已连接';
|
||||
statusElement.className = 'status-indicator status-connected';
|
||||
} else {
|
||||
statusElement.textContent = 'WebSocket未连接';
|
||||
statusElement.className = 'status-indicator status-disconnected';
|
||||
}
|
||||
}
|
||||
|
||||
// 显示通知
|
||||
showNotification(type, message) {
|
||||
const notification = document.createElement('div');
|
||||
notification.className = `notification ${type}`;
|
||||
notification.textContent = message;
|
||||
|
||||
document.body.appendChild(notification);
|
||||
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(notification);
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
// 添加日志
|
||||
addLog(message) {
|
||||
const logContent = document.getElementById('log-content');
|
||||
const timestamp = new Date().toLocaleTimeString();
|
||||
const logEntry = document.createElement('div');
|
||||
logEntry.textContent = `[${timestamp}] ${message}`;
|
||||
logContent.appendChild(logEntry);
|
||||
logContent.scrollTop = logContent.scrollHeight;
|
||||
}
|
||||
}
|
||||
|
||||
// 启动应用
|
||||
const app = new KmzApp();
|
||||
```
|
||||
|
||||
## 📊 数据格式说明
|
||||
|
||||
### 1. WebSocket消息格式
|
||||
|
||||
```javascript
|
||||
// GK数据消息
|
||||
{
|
||||
"bizCode": "gk_data",
|
||||
"host": {
|
||||
"sid": "1581F6GKB244J00402NM",
|
||||
"tm": 1706342400000,
|
||||
"task_id": "TASK_001",
|
||||
"task_name": "巡检任务",
|
||||
"task_type": 1,
|
||||
"route": [
|
||||
{
|
||||
"longitude": 112.894686,
|
||||
"latitude": 28.207833,
|
||||
"altitude": 50.0
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
// KMZ文件数据消息
|
||||
{
|
||||
"bizCode": "kmz_file_data",
|
||||
"host": {
|
||||
"messageType": "kmz_file_data",
|
||||
"taskId": "TASK_001",
|
||||
"taskName": "巡检任务",
|
||||
"deviceSn": "1581F6GKB244J00402NM",
|
||||
"dataType": "route",
|
||||
"timestamp": 1706342400000,
|
||||
"kmzFile": {
|
||||
"fileName": "巡检任务_1581F6GKB244J00402NM_dji_20250127_143022.kmz",
|
||||
"fileSize": 3891,
|
||||
"filePath": "/opt/dji/routes/巡检任务_1581F6GKB244J00402NM_dji_20250127_143022.kmz",
|
||||
"downloadUrl": "/api/v1/kmz/download/TASK_001",
|
||||
"fileType": "kmz"
|
||||
},
|
||||
"fileData": "UEsDBBQAAAAIAA...", // Base64编码的文件内容
|
||||
"waypoints": [
|
||||
{
|
||||
"longitude": 112.894686,
|
||||
"latitude": 28.207833,
|
||||
"altitude": 50.0
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. API响应格式
|
||||
|
||||
```javascript
|
||||
// 成功响应
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
// 具体数据
|
||||
},
|
||||
"message": "操作成功"
|
||||
}
|
||||
|
||||
// 错误响应
|
||||
{
|
||||
"success": false,
|
||||
"message": "错误信息",
|
||||
"code": "ERROR_CODE"
|
||||
}
|
||||
```
|
||||
|
||||
## 🔧 配置选项
|
||||
|
||||
### 1. 环境配置
|
||||
|
||||
```javascript
|
||||
const ENV_CONFIG = {
|
||||
development: {
|
||||
websocketUrl: 'ws://localhost:8080/ws',
|
||||
apiBaseUrl: 'http://localhost:8080/api/v1',
|
||||
workspaceId: 'e3dea0f5-37f2-4d79-ae58-490af3228069'
|
||||
},
|
||||
production: {
|
||||
websocketUrl: 'wss://your-domain.com/ws',
|
||||
apiBaseUrl: 'https://your-domain.com/api/v1',
|
||||
workspaceId: 'your-workspace-id'
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### 2. 功能配置
|
||||
|
||||
```javascript
|
||||
const FEATURE_CONFIG = {
|
||||
// 是否自动下载KMZ文件
|
||||
autoDownload: true,
|
||||
// 是否显示详细日志
|
||||
verboseLogging: true,
|
||||
// 重连配置
|
||||
reconnect: {
|
||||
maxAttempts: 5,
|
||||
interval: 3000
|
||||
},
|
||||
// 文件大小限制(字节)
|
||||
maxFileSize: 10 * 1024 * 1024 // 10MB
|
||||
};
|
||||
```
|
||||
|
||||
## 🚨 错误处理
|
||||
|
||||
### 1. 常见错误类型
|
||||
|
||||
```javascript
|
||||
class ErrorHandler {
|
||||
static handleWebSocketError(error) {
|
||||
console.error('WebSocket错误:', error);
|
||||
// 处理WebSocket连接错误
|
||||
}
|
||||
|
||||
static handleApiError(error) {
|
||||
console.error('API错误:', error);
|
||||
// 处理API调用错误
|
||||
}
|
||||
|
||||
static handleFileError(error) {
|
||||
console.error('文件处理错误:', error);
|
||||
// 处理文件下载/解析错误
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 错误恢复策略
|
||||
|
||||
```javascript
|
||||
class ErrorRecovery {
|
||||
static retryOperation(operation, maxRetries = 3) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let attempts = 0;
|
||||
|
||||
const tryOperation = () => {
|
||||
attempts++;
|
||||
operation()
|
||||
.then(resolve)
|
||||
.catch(error => {
|
||||
if (attempts < maxRetries) {
|
||||
console.log(`操作失败,重试中 (${attempts}/${maxRetries})`);
|
||||
setTimeout(tryOperation, 1000 * attempts);
|
||||
} else {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
tryOperation();
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 📝 最佳实践
|
||||
|
||||
### 1. 性能优化
|
||||
|
||||
- 使用防抖和节流处理频繁的消息
|
||||
- 合理使用缓存避免重复请求
|
||||
- 及时清理不需要的资源
|
||||
|
||||
### 2. 用户体验
|
||||
|
||||
- 提供清晰的状态指示
|
||||
- 显示操作进度
|
||||
- 提供错误提示和恢复建议
|
||||
|
||||
### 3. 安全性
|
||||
|
||||
- 验证所有输入数据
|
||||
- 使用HTTPS/WSS连接
|
||||
- 避免在客户端存储敏感信息
|
||||
|
||||
## 🔍 调试指南
|
||||
|
||||
### 1. 开启调试模式
|
||||
|
||||
```javascript
|
||||
const DEBUG = true;
|
||||
|
||||
if (DEBUG) {
|
||||
// 开启详细日志
|
||||
console.log('调试模式已开启');
|
||||
|
||||
// 监听所有WebSocket消息
|
||||
const originalOnMessage = WebSocket.prototype.onmessage;
|
||||
WebSocket.prototype.onmessage = function(event) {
|
||||
console.log('WebSocket消息:', event.data);
|
||||
originalOnMessage.call(this, event);
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 常见问题排查
|
||||
|
||||
1. **WebSocket连接失败**
|
||||
- 检查URL是否正确
|
||||
- 确认服务器是否运行
|
||||
- 检查网络连接
|
||||
|
||||
2. **KMZ文件下载失败**
|
||||
- 检查文件是否存在
|
||||
- 验证API接口是否正常
|
||||
- 确认文件权限
|
||||
|
||||
3. **消息处理异常**
|
||||
- 检查消息格式是否正确
|
||||
- 验证消息处理器是否注册
|
||||
- 查看控制台错误信息
|
||||
|
||||
## 📞 技术支持
|
||||
|
||||
如有问题,请联系开发团队或查看相关文档:
|
||||
|
||||
- API文档:`/api/v1/kmz/docs`
|
||||
- 系统日志:检查浏览器控制台和后端日志
|
||||
- 问题反馈:提交Issue到项目仓库
|
||||
|
||||
---
|
||||
|
||||
**注意**: 本指南基于当前系统实现,如有更新请及时同步文档。
|
||||
Reference in New Issue
Block a user