Compare commits
2 Commits
86489c326c
...
3065abf7dd
Author | SHA1 | Date | |
---|---|---|---|
3065abf7dd | |||
495e153db9 |
@ -25,7 +25,6 @@ export type RobotPen = Pen & {
|
||||
isFault?: boolean;
|
||||
isCharging?: boolean; // 是否充电中
|
||||
isCarrying?: boolean; // 是否载货
|
||||
isNotAcceptingOrders?: boolean; // 是否不接单
|
||||
path?: { x: number; y: number }[];
|
||||
angle?: number;
|
||||
};
|
||||
@ -48,7 +47,6 @@ export interface RobotInfo {
|
||||
isLoading?: 0 | 1; // 载货状态:1载货,0空载(实时数据透传)
|
||||
isCharging?: boolean; // 是否充电中
|
||||
isCarrying?: boolean; // 是否载货
|
||||
isNotAcceptingOrders?: boolean; // 是否不接单
|
||||
}
|
||||
|
||||
export interface RobotDetail extends RobotInfo {
|
||||
@ -72,7 +70,6 @@ export interface RobotRealtimeInfo extends RobotInfo {
|
||||
isFault?: boolean; // 是否故障
|
||||
isCharging?: boolean; // 是否充电中
|
||||
isCarrying?: boolean; // 是否载货
|
||||
isNotAcceptingOrders?: boolean; // 是否不接单
|
||||
}
|
||||
|
||||
// AMR Redis状态接口 - 更新为实际返回的数据结构
|
||||
|
@ -18,7 +18,7 @@
|
||||
</div>
|
||||
<div class="robot-extra-statuses">
|
||||
<span v-if="robotInfo.isCarrying" class="extra-status-tag">载货中</span>
|
||||
<span v-if="robotInfo.isNotAcceptingOrders" class="extra-status-tag">不接单</span>
|
||||
<span v-if="!robotInfo.canOrder" class="extra-status-tag">不接单</span>
|
||||
<span v-if="robotInfo.isCharging" class="extra-status-tag">充电中</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -3,6 +3,7 @@ import type { EditorService } from '@core/editor.service';
|
||||
import { useToolbar } from '@core/useToolbar';
|
||||
import { computed, inject, type InjectionKey, onBeforeUnmount, onMounted, ref, type ShallowRef } from 'vue';
|
||||
|
||||
import { useViewState } from '../services/useViewState';
|
||||
import ColorConfigPanel from './color/color-config-panel.vue';
|
||||
|
||||
// 通用地图工具栏(右下角),临时中文按钮
|
||||
@ -21,14 +22,11 @@ const editorRef = inject(props.token)!;
|
||||
// 颜色配置面板状态
|
||||
const showColorConfig = ref(false);
|
||||
|
||||
// 使用 useToolbar 的相关能力(内部使用 jumpToPosition、修改 store 等)
|
||||
const {
|
||||
toggleGrid: _toggleGrid,
|
||||
toggleRule: _toggleRule,
|
||||
// fitView: _fitView,
|
||||
zoomIn: _zoomIn,
|
||||
zoomOut: _zoomOut,
|
||||
} = useToolbar();
|
||||
// 使用 useToolbar 的相关能力
|
||||
const { toggleGrid: _toggleGrid, toggleRule: _toggleRule, zoomIn: _zoomIn, zoomOut: _zoomOut } = useToolbar();
|
||||
|
||||
// 使用 useViewState 的相关能力
|
||||
const { jumpToPosition, calculateCenterPoint } = useViewState();
|
||||
|
||||
const zoomIn = () => {
|
||||
if (editorRef.value) _zoomIn(editorRef.value);
|
||||
@ -36,42 +34,16 @@ const zoomIn = () => {
|
||||
const zoomOut = () => {
|
||||
if (editorRef.value) _zoomOut(editorRef.value);
|
||||
};
|
||||
// const fitView = async () => {
|
||||
// if (editorRef.value) await _fitView(editorRef.value);
|
||||
// };
|
||||
|
||||
// const toggleFullscreen = async () => {
|
||||
// try {
|
||||
// const el = props.containerEl || document.documentElement;
|
||||
// if (!document.fullscreenElement) {
|
||||
// await el.requestFullscreen?.();
|
||||
// } else {
|
||||
// await document.exitFullscreen?.();
|
||||
// }
|
||||
// } catch (e) {
|
||||
// console.warn('全屏切换失败', e);
|
||||
// }
|
||||
// };
|
||||
// 定位到中心点并缩放
|
||||
const locateCenter = () => {
|
||||
if (editorRef.value) {
|
||||
const { centerX, centerY } = calculateCenterPoint(editorRef.value);
|
||||
jumpToPosition(editorRef.value, centerX, centerY, false, 0.05);
|
||||
}
|
||||
};
|
||||
|
||||
// const downloadBase64 = (base64: string, filename = 'map.png') => {
|
||||
// const a = document.createElement('a');
|
||||
// a.href = base64;
|
||||
// a.download = filename;
|
||||
// document.body.appendChild(a);
|
||||
// a.click();
|
||||
// document.body.removeChild(a);
|
||||
// };
|
||||
|
||||
// const exportImage = () => {
|
||||
// try {
|
||||
// const base64 = editorRef.value?.toPng?.(2);
|
||||
// if (base64) downloadBase64(base64, '地图截图.png');
|
||||
// } catch (e) {
|
||||
// console.warn('截图失败', e);
|
||||
// }
|
||||
// };
|
||||
|
||||
// 网格/标尺开关:调用 useToolbar 封装
|
||||
// 网格/标尺开关
|
||||
const toggleGrid = () => editorRef.value && _toggleGrid(editorRef.value);
|
||||
const toggleRule = () => editorRef.value && _toggleRule(editorRef.value);
|
||||
|
||||
@ -176,7 +148,7 @@ defineOptions({
|
||||
<a-button class="icon-btn tool-btn" size="small" :title="'缩小'" @click="zoomOut">
|
||||
<img src="/src/assets/icons/png/shrink.png" alt="缩小" class="toolbar-icon" />
|
||||
</a-button>
|
||||
<!-- <a-button class="icon-btn tool-btn" size="small" :title="'适配视图'" @click="fitView"> 适配视图 </a-button> -->
|
||||
<a-button class="icon-btn tool-btn" size="small" :title="'定位'" @click="locateCenter"> 定位 </a-button>
|
||||
<a-button
|
||||
class="icon-btn tool-btn"
|
||||
size="small"
|
||||
@ -188,8 +160,6 @@ defineOptions({
|
||||
>
|
||||
<img src="/src/assets/icons/png/rule.png" alt="测量尺" class="toolbar-icon" :class="{ active: measuring }" />
|
||||
</a-button>
|
||||
<!-- <a-button class="icon-btn tool-btn" size="small" :title="'标尺'" @click="toggleRule">标尺</a-button>
|
||||
<a-button class="icon-btn tool-btn" size="small" :title="'网格'" @click="toggleGrid">网格</a-button> -->
|
||||
<a-button
|
||||
class="icon-btn tool-btn"
|
||||
size="small"
|
||||
@ -205,15 +175,6 @@ defineOptions({
|
||||
:class="{ active: showColorConfig }"
|
||||
/>
|
||||
</a-button>
|
||||
<!-- <a-button class="icon-btn tool-btn" size="small" :title="'截图'" @click="exportImage">截图</a-button>
|
||||
<a-button
|
||||
class="icon-btn tool-btn"
|
||||
size="small"
|
||||
:title="isFullscreen ? '退出全屏' : '全屏'"
|
||||
@click="toggleFullscreen"
|
||||
>
|
||||
{{ isFullscreen ? '退出全屏' : '全屏' }}
|
||||
</a-button> -->
|
||||
</a-space>
|
||||
</div>
|
||||
|
||||
|
@ -153,7 +153,7 @@ const monitorScene = async () => {
|
||||
isFault,
|
||||
isCharging = 0,
|
||||
isCarrying = 0,
|
||||
isNotAcceptingOrders = 1,
|
||||
canOrder,
|
||||
...rest
|
||||
} = data;
|
||||
|
||||
@ -162,7 +162,7 @@ const monitorScene = async () => {
|
||||
...rest,
|
||||
isCharging: isCharging as any,
|
||||
isCarrying: isCarrying as any,
|
||||
isNotAcceptingOrders: isNotAcceptingOrders as any,
|
||||
canOrder: canOrder as any,
|
||||
});
|
||||
|
||||
// 2. 准备图元(pen)的更新负载对象,将多个更新合并
|
||||
@ -184,7 +184,7 @@ const monitorScene = async () => {
|
||||
if (isFault !== undefined) robotState.isFault = isFault;
|
||||
if (isCharging !== undefined) robotState.isCharging = isCharging;
|
||||
if (isCarrying !== undefined) robotState.isCarrying = isCarrying;
|
||||
if (isNotAcceptingOrders !== undefined) robotState.isNotAcceptingOrders = isNotAcceptingOrders;
|
||||
if (canOrder !== undefined) robotState.canOrder = canOrder;
|
||||
|
||||
// 将合并后的状态赋给 payload
|
||||
if (Object.keys(robotState).length > 0) {
|
||||
|
@ -1337,11 +1337,11 @@ export class EditorService extends Meta2d {
|
||||
const r2 = this.getRobotById(pen.id || '');
|
||||
const toBool = (v: any) => v === true || v === 1 || v === '1';
|
||||
const isCarrying = toBool(r1?.isCarrying ?? r2?.isCarrying);
|
||||
const isNotAcceptingOrders = toBool(r1?.isNotAcceptingOrders ?? r2?.isNotAcceptingOrders);
|
||||
const canOrder = toBool(r1?.canOrder ?? r2?.canOrder);
|
||||
const isCharging = toBool(r1?.isCharging ?? r2?.isCharging);
|
||||
|
||||
if (isCarrying) return cargoIcon;
|
||||
if (isNotAcceptingOrders) return notAcceptingOrdersIcon;
|
||||
if (!canOrder) return notAcceptingOrdersIcon;
|
||||
if (isCharging) return chargingIcon;
|
||||
return null;
|
||||
}
|
||||
|
@ -205,16 +205,21 @@ export function useViewState() {
|
||||
* @param x X坐标
|
||||
* @param y Y坐标
|
||||
* @param isRestoring 是否为恢复视图状态,true时保持当前缩放比例
|
||||
* @param scale 目标缩放比例
|
||||
*/
|
||||
const jumpToPosition = async (editor: EditorService, x: number, y: number, isRestoring = false): Promise<void> => {
|
||||
const jumpToPosition = async (
|
||||
editor: EditorService,
|
||||
x: number,
|
||||
y: number,
|
||||
isRestoring = false,
|
||||
scale?: number,
|
||||
): Promise<void> => {
|
||||
try {
|
||||
// 检查是否已存在临时点
|
||||
const existingTempPoints = editor
|
||||
.find('point')
|
||||
.filter((point) => point.id && point.id.includes('view-center-point'));
|
||||
|
||||
// 如果不是恢复状态且没有临时点,调整缩放比例到8%
|
||||
if (!isRestoring && existingTempPoints.length === 0) {
|
||||
// 如果传递了 scale,则无论如何都应用缩放
|
||||
if (typeof scale === 'number') {
|
||||
editor.scale(scale);
|
||||
} else if (!isRestoring) {
|
||||
// 仅在非恢复状态且未指定 scale 时使用默认缩放
|
||||
editor.scale(0.08);
|
||||
}
|
||||
|
||||
@ -239,16 +244,15 @@ export function useViewState() {
|
||||
editor.inactive();
|
||||
}, 10); // 短暂延迟确保跳转完成
|
||||
|
||||
// 延迟清理临时点(保存时已自动过滤,这里只是为了清理画布显示)
|
||||
// 延迟清理临时点
|
||||
setTimeout(() => {
|
||||
const remainingPoints = editor
|
||||
.find('point')
|
||||
.filter((point) => point.id && point.id.includes('view-center-point'));
|
||||
if (remainingPoints && remainingPoints.length > 0) {
|
||||
if (remainingPoints.length > 0) {
|
||||
editor.delete(remainingPoints);
|
||||
console.log(`清理了 ${remainingPoints.length} 个临时点`);
|
||||
}
|
||||
}, 500); // 增加延迟确保跳转完成
|
||||
}, 500);
|
||||
} catch (error) {
|
||||
console.error('跳转到指定位置失败:', error);
|
||||
}
|
||||
@ -291,8 +295,6 @@ export function useViewState() {
|
||||
|
||||
/**
|
||||
* 自动保存和恢复视图状态
|
||||
* 如果本地没有保存的key,则先保存当前状态(用于定位地图),然后恢复
|
||||
* 如果有key,则直接按原来逻辑恢复
|
||||
* @param editor 编辑器服务实例
|
||||
* @param sceneId 场景ID
|
||||
* @param groupId 群组ID (可选)
|
||||
@ -306,30 +308,17 @@ export function useViewState() {
|
||||
const hasExistingState = hasViewState(sceneId, groupId);
|
||||
|
||||
if (!hasExistingState) {
|
||||
// 首次进入:先居中显示获取中心点坐标
|
||||
editor.centerView();
|
||||
|
||||
// 等待一小段时间让centerView完成
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
|
||||
// 获取当前视图状态(主要是为了获取中心点坐标)
|
||||
const currentState = getCurrentViewState(editor);
|
||||
|
||||
// 缩放到8%并跳转到中心点(首次进入的默认行为)
|
||||
await jumpToPosition(editor, currentState.centerX, currentState.centerY, false);
|
||||
|
||||
// 保存当前状态(包含8%缩放和中心点坐标)
|
||||
await saveViewState(editor, sceneId, groupId);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
// 直接恢复已有状态
|
||||
return await restoreViewState(editor, sceneId, groupId);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('自动保存和恢复视图状态失败:', error);
|
||||
|
||||
// 如果出错,至少执行centerView作为fallback
|
||||
editor.centerView();
|
||||
return false;
|
||||
}
|
||||
@ -345,7 +334,7 @@ export function useViewState() {
|
||||
getViewStateInfo,
|
||||
getCurrentViewState,
|
||||
autoSaveAndRestoreViewState,
|
||||
// 对外暴露跳转方法,供工具栏或其他模块使用(例如适配视图时用该方法居中跳转)
|
||||
jumpToPosition,
|
||||
calculateCenterPoint,
|
||||
};
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user