feat: 加载地图

This commit is contained in:
zhanghao 2026-06-12 17:27:59 +08:00
parent 780665fa9a
commit 6af1118a3c
8 changed files with 69 additions and 30 deletions

View File

@ -10,3 +10,5 @@ VITE_APP_BASE_API = '/dev-api'
VITE_API_URL = http://192.168.28.10:13080 VITE_API_URL = http://192.168.28.10:13080
VITE_WS_URL = ws://192.168.0.201:13080/ws VITE_WS_URL = ws://192.168.0.201:13080/ws
# explanation
VITE_INSPECTION_TYPE = "inspection"

View File

@ -15,3 +15,6 @@ VITE_NODE_RED_URL = 'http://10.148.108.59:13080'
VITE_API_URL = http://192.168.28.10:13080 VITE_API_URL = http://192.168.28.10:13080
VITE_WS_URL = ws://192.168.0.201:13080/ws VITE_WS_URL = ws://192.168.0.201:13080/ws
# explanation
VITE_INSPECTION_TYPE = "inspection"

View File

@ -29,4 +29,29 @@ export function deleteRobot(id) {
url: `/inspection/robot/${id}`, url: `/inspection/robot/${id}`,
method: 'delete' method: 'delete'
}) })
}
/**
* 获取机器人地图
* @param {*} robotId
* @returns
*/
export function getMapByRobot(robotId) {
return request({
url: `/inspection/robot/${robotId}/maps`,
method: 'get'
})
}
/**
* 获取地图JSON数据
* @param {*} params
* @returns
*/
export function getMapJson(params) {
return request({
url: `/inspection/robot/${params.robotId}/download-map`,
method: 'get',
params
})
} }

View File

@ -153,7 +153,7 @@ async function loadMapIntoApplication(parsedMap) {
const worldHeightMeters = parsedMap.maxY - parsedMap.originY; // const worldHeightMeters = parsedMap.maxY - parsedMap.originY; //
const fitScaleX = inspectionStore.canvasWidthPx / worldWidthMeters; // const fitScaleX = inspectionStore.canvasWidthPx / worldWidthMeters; //
const fitScaleY = inspectionStore.canvasHeightPx / worldHeightMeters; // const fitScaleY = inspectionStore.canvasHeightPx / worldHeightMeters; //
inspectionStore.camera.pixelsPerMeter = Math.max(1, Math.min(fitScaleX, fitScaleY) * 1); // inspectionStore.camera.pixelsPerMeter = Math.max(1, Math.max(fitScaleX, fitScaleY) * 1); //
// UI // UI
applicationState.isMapLoaded = true; applicationState.isMapLoaded = true;

View File

@ -65,10 +65,10 @@
</div> </div>
</div> </div>
<div class="right-container"> <div class="right-container">
<div class="sensor-container"> <!-- <div class="sensor-container">
<div class="sensor-title">传感器数据</div> <div class="sensor-title">传感器数据</div>
</div> </div> -->
<div class="split-line"></div> <!-- <div class="split-line"></div> -->
<div class="alarm-container"> <div class="alarm-container">
<div class="container-title">告警记录</div> <div class="container-title">告警记录</div>
<div class="alarm-box" v-for="item, index in 2"> <div class="alarm-box" v-for="item, index in 2">
@ -85,6 +85,8 @@ import SvgIcon from "@/components/SvgIcon";
import MapCanvas from "./MapCanvas.vue"; import MapCanvas from "./MapCanvas.vue";
import { onMounted, onUnmounted } from "vue"; import { onMounted, onUnmounted } from "vue";
console.log('sss', import.meta.env.VITE_INSPECTION_TYPE)
const robotState = ref('online') const robotState = ref('online')
const mapCanvasRef = ref(null) const mapCanvasRef = ref(null)

View File

@ -88,7 +88,7 @@
import { useContainerHeight } from "@/hooks/tableHeight"; import { useContainerHeight } from "@/hooks/tableHeight";
import { addMap, updateMap, deleteMap, getMapList } from "../../../api/inspection/map"; import { addMap, updateMap, deleteMap, getMapList } from "../../../api/inspection/map";
import { getRobotList } from "../../../api/inspection/robot"; import { getRobotList, getMapByRobot, getMapJson } from "../../../api/inspection/robot";
import { onMounted } from "vue"; import { onMounted } from "vue";
import { import {
@ -171,6 +171,7 @@ function cancel() {
} }
window.removeEventListener('resize', resizeCanvasToContainer) window.removeEventListener('resize', resizeCanvasToContainer)
canvasCtx.clearRect(0, 0, applicationState.canvasWidthPx, applicationState.canvasHeightPx);
canvasCtx = null canvasCtx = null
} }
@ -215,6 +216,7 @@ function handleUpdate(row) {
isNew.value = false; isNew.value = false;
open.value = true; open.value = true;
title.value = "修改地图"; title.value = "修改地图";
getMapArr(row.mapSourceRobotId)
setTimeout(() => { setTimeout(() => {
init(); init();
if (form.value.mapSourceName) { if (form.value.mapSourceName) {
@ -265,12 +267,6 @@ function handleDelete(row) {
} }
const loadSourceMap = async (url) => {
const response = await fetch(url);
if (!response.ok) throw new Error(`加载失败:${response.status}`);
return response.text();
};
function parseSmapJson(rawJson) { function parseSmapJson(rawJson) {
// header // header
const header = rawJson.header || rawJson; // header const header = rawJson.header || rawJson; // header
@ -360,7 +356,6 @@ const init = () => {
*/ */
function resizeCanvasToContainer() { function resizeCanvasToContainer() {
const containerRect = mapCanvas.parentElement.getBoundingClientRect(); // const containerRect = mapCanvas.parentElement.getBoundingClientRect(); //
console.log('containerRect', containerRect)
devicePixelRatio = window.devicePixelRatio || 1; // devicePixelRatio = window.devicePixelRatio || 1; //
applicationState.canvasWidthPx = containerRect.width; // applicationState.canvasWidthPx = containerRect.width; //
applicationState.canvasHeightPx = containerRect.height; // = - applicationState.canvasHeightPx = containerRect.height; // = -
@ -386,7 +381,7 @@ async function loadMapIntoApplication(parsedMap) {
const worldHeightMeters = parsedMap.maxY - parsedMap.originY; // const worldHeightMeters = parsedMap.maxY - parsedMap.originY; //
const fitScaleX = applicationState.canvasWidthPx / worldWidthMeters; // const fitScaleX = applicationState.canvasWidthPx / worldWidthMeters; //
const fitScaleY = applicationState.canvasHeightPx / worldHeightMeters; // const fitScaleY = applicationState.canvasHeightPx / worldHeightMeters; //
applicationState.camera.pixelsPerMeter = Math.max(1, Math.min(fitScaleX, fitScaleY)); // 12% applicationState.camera.pixelsPerMeter = Math.max(1, Math.max(fitScaleX, fitScaleY)); // 12%
// UI // UI
applicationState.isMapLoaded = true; applicationState.isMapLoaded = true;
@ -443,10 +438,16 @@ const bindEvent = () => {
*/ */
const loadUserFile = async () => { const loadUserFile = async () => {
try { try {
const filemapDesc = await loadSourceMap('/3.smap'); const res = await getMapJson({
const rawJsonObject = JSON.parse(filemapDesc); // JSON robotId: form.value.mapSourceRobotId,
const parsedMap = parseSmapJson(rawJsonObject); // mapName: form.value.mapSourceName
await loadMapIntoApplication(parsedMap); // });
if (res.code === 200) {
const rawJsonObject = JSON.parse(res.data); // JSON
const parsedMap = parseSmapJson(rawJsonObject); //
await loadMapIntoApplication(parsedMap); //
}
} catch (parseError) { } catch (parseError) {
alert('Parse error: ' + parseError.message); // alert('Parse error: ' + parseError.message); //
} }
@ -530,13 +531,13 @@ const getRobotArr = () => {
}); });
} }
const getMapArr = (robotId) => { const getMapArr = async (robotId) => {
// TODO: robotId const res = await getMapByRobot(robotId)
mapList.value = [ if (res.code === 200) {
{ label: "地图1", value: "map1" }, mapList.value = res.data.map(item => {
{ label: "地图2", value: "map2" }, return { label: item, value: item }
{ label: "地图3", value: "map3" }, })
] }
} }
const robotChange = (value) => { const robotChange = (value) => {

View File

@ -26,7 +26,12 @@
<div :style="containerHeight"> <div :style="containerHeight">
<el-table v-loading="loading" height="100%" style="width: 100%" :data="tableDataList"> <el-table v-loading="loading" height="100%" style="width: 100%" :data="tableDataList">
<el-table-column label="机器人名称" align="center" prop="robotName" /> <el-table-column label="机器人名称" align="center" prop="robotName" />
<el-table-column label="机器人类型" align="center" prop="robotType" /> <el-table-column label="机器人编码" align="center" prop="robotCode" />
<el-table-column label="机器人类型" align="center" prop="robotType">
<template #default="scope">
{{ scope.row.robotType == 1 ? '讲解机器人' : '巡检机器人' }}
</template>
</el-table-column>
<el-table-column label="IP地址" align="center" prop="ipAddress" min-width="160" show-overflow-tooltip /> <el-table-column label="IP地址" align="center" prop="ipAddress" min-width="160" show-overflow-tooltip />
<el-table-column label="电量" align="center" prop="batteryLevel" /> <el-table-column label="电量" align="center" prop="batteryLevel" />
<el-table-column label="状态" align="center" prop="status" /> <el-table-column label="状态" align="center" prop="status" />
@ -49,6 +54,9 @@
<el-form-item label="机器人名称" prop="robotName"> <el-form-item label="机器人名称" prop="robotName">
<el-input v-model="form.robotName" placeholder="请输入机器人名称" /> <el-input v-model="form.robotName" placeholder="请输入机器人名称" />
</el-form-item> </el-form-item>
<el-form-item label="机器人编码" prop="robotCode">
<el-input v-model="form.robotCode" placeholder="请输入机器人编码" />
</el-form-item>
<el-form-item label="机器人类型" prop="robotType"> <el-form-item label="机器人类型" prop="robotType">
<el-select v-model="form.robotType" placeholder="请输入机器人类型" clearable style="width: 100%"> <el-select v-model="form.robotType" placeholder="请输入机器人类型" clearable style="width: 100%">
<el-option v-for="type in robot_type" :key="type.value" :label="type.label" <el-option v-for="type in robot_type" :key="type.value" :label="type.label"
@ -126,6 +134,9 @@ const data = reactive({
robotName: [ robotName: [
{ required: true, message: "请输入机器人名称", trigger: "change" }, { required: true, message: "请输入机器人名称", trigger: "change" },
], ],
robotCode: [
{ required: true, message: "请输入机器人编码", trigger: "change" },
],
robotType: [ robotType: [
{ required: true, message: "请输入机器人类型", trigger: "change" }, { required: true, message: "请输入机器人类型", trigger: "change" },
], ],

View File

@ -616,11 +616,6 @@ onUnmounted(() => {
font-size: 14px; font-size: 14px;
font-weight: bold; font-weight: bold;
} }
.run-log-container {
}
} }
} }
} }