From b2e68202685d4ccf3b600fe8eb2bfff22e2e74e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E6=98=8C?= <392871505@qq.com> Date: Sun, 24 May 2026 11:00:59 +0800 Subject: [PATCH] =?UTF-8?q?=E7=94=B5=E8=84=91=E7=AB=AF=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E6=9C=AC=E5=9C=B0=E9=83=A8=E7=BD=B2=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- run_local.bat | 40 +++++++++++++++++++++++++++ software/src/软件电脑端/js/ui.js | 26 ++++++++++------- 2 files changed, 56 insertions(+), 10 deletions(-) create mode 100644 run_local.bat diff --git a/run_local.bat b/run_local.bat new file mode 100644 index 00000000..4f9ba45a --- /dev/null +++ b/run_local.bat @@ -0,0 +1,40 @@ +@echo off +chcp 65001 >nul +title 智途投送 - 电脑端本地服务 + +echo ========================================= +echo 智途投送电脑端 - 本地部署 +echo ========================================= +echo. +echo ✅ 完全本地运行,数据不走外网 +echo ✅ 浏览器直接连 P600 rosbridge +echo 🔗 API 数据中转云服务器 +echo. +echo 浏览器打开: http://localhost:5000 +echo rosbridge: ws://192.168.1.14:8080 +echo. +echo 按 Ctrl+C 停止服务 +echo. + +cd /d %~dp0software\src\软件电脑端 + +echo [1/3] 检查 Python ... +python --version >nul 2>&1 +if errorlevel 1 ( + echo ❌ 未安装 Python 3 + pause + exit /b +) + +echo [2/3] 启动 HTTP 服务 ... +echo. +echo 🚀 打开浏览器访问 http://localhost:5000 +echo. +echo 连接地址填: ws://192.168.1.14:8080 +echo. + +REM 启动 Python HTTP 服务器,仅提供静态文件 +REM API 请求自动转发到云服务器 121.41.216.243(由前端自动处理) +python -m http.server 5000 --bind 0.0.0.0 + +pause diff --git a/software/src/软件电脑端/js/ui.js b/software/src/软件电脑端/js/ui.js index dc16522c..abcc390c 100644 --- a/software/src/软件电脑端/js/ui.js +++ b/software/src/软件电脑端/js/ui.js @@ -5,6 +5,12 @@ */ const UIModule = (() => { + // ---- API 地址 ---- + // 从云服务器加载时,API 同源,用空串 + // 本地部署时(localhost),API 指向云服务器 + const API_BASE = (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1') + ? 'http://121.41.216.243' : ''; + // ---- 状态 ---- let droneConnected = false; let missionRunning = false; @@ -115,7 +121,7 @@ const UIModule = (() => { // ===== 从后端获取飞行中任务 ===== async function fetchActiveTasks() { try { - const resp = await fetch('/api/tasks'); + const resp = await fetch(API_BASE + '/api/tasks'); if (!resp.ok) return; const data = await resp.json(); if (data.tasks && Array.isArray(data.tasks)) { @@ -137,7 +143,7 @@ const UIModule = (() => { // ===== 从后端获取需求列表 ===== async function fetchDemands() { try { - const resp = await fetch('/api/demands'); + const resp = await fetch(API_BASE + '/api/demands'); if (!resp.ok) return; const data = await resp.json(); if (data.demands && Array.isArray(data.demands)) { @@ -278,7 +284,7 @@ const UIModule = (() => { async function cancelActiveTask(taskId) { try { - var resp = await fetch('/api/tasks/' + encodeURIComponent(taskId) + '/cancel', { method: 'POST' }); + var resp = await fetch(API_BASE + '/api/tasks/' + encodeURIComponent(taskId) + '/cancel', { method: 'POST' }); var data = await resp.json(); if (data.ok) { addLog('success', '已取消调度: ' + taskId); @@ -349,7 +355,7 @@ const UIModule = (() => { function onReject() { if (!selectedTask) return; // 同步更新后端状态,防止轮询时恢复 - fetch('/api/demands/' + selectedTask.id + '/reject', { method: 'POST' }); + fetch(API_BASE + '/api/demands/' + selectedTask.id + '/reject', { method: 'POST' }); addLog('info', '已拒绝需求: ' + selectedTask.id); pendingTasks = pendingTasks.filter(t => t.id !== selectedTask.id); renderPendingList(); @@ -367,7 +373,7 @@ const UIModule = (() => { // 向后端创建任务 try { - var dispatchResp = await fetch('/api/task/dispatch', { + var dispatchResp = await fetch(API_BASE + '/api/task/dispatch', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ @@ -476,7 +482,7 @@ const UIModule = (() => { async function fetchSoldiers() { try { - const resp = await fetch('/api/soldiers'); + const resp = await fetch(API_BASE + '/api/soldiers'); if (!resp.ok) return; const data = await resp.json(); if (data.soldiers && Array.isArray(data.soldiers)) { @@ -527,7 +533,7 @@ const UIModule = (() => { async function fetchZones() { try { - const resp = await fetch('/api/zones'); + const resp = await fetch(API_BASE + '/api/zones'); if (!resp.ok) return; const data = await resp.json(); if (data.zones && Array.isArray(data.zones)) { @@ -563,7 +569,7 @@ const UIModule = (() => { const description = '无人机被摧毁'; try { - const resp = await fetch('/api/danger-zones', { + const resp = await fetch(API_BASE + '/api/danger-zones', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ lat, lng, radius, description }) @@ -686,7 +692,7 @@ const UIModule = (() => { if (isNaN(lat) || isNaN(lng)) { addLog('warning', '请输入有效的经纬度'); return; } try { - var resp = await fetch('/api/zones', { + var resp = await fetch(API_BASE + '/api/zones', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ @@ -712,7 +718,7 @@ const UIModule = (() => { async function deleteZone(id) { try { - var resp = await fetch('/api/zones/' + id, { method: 'DELETE' }); + var resp = await fetch(API_BASE + '/api/zones/' + id, { method: 'DELETE' }); if (resp.ok) { addLog('info', '已删除区域 #' + id); fetchZones();