From 155f7ab71efd8d9378afeaf87372ee70cedf541d Mon Sep 17 00:00:00 2001 From: xudan Date: Mon, 30 Jun 2025 11:21:55 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=9B=B4=E6=96=B0API=E5=92=8CWebSocket?= =?UTF-8?q?=E4=BB=A3=E7=90=86=E5=9C=B0=E5=9D=80=EF=BC=8C=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E5=BA=93=E5=8C=BA=E7=82=B9=E7=B1=BB=E5=9E=8B=EF=BC=8C=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E5=9C=BA=E6=99=AF=E6=95=B0=E6=8D=AE=E5=A4=84=E7=90=86?= =?UTF-8?q?=E9=80=BB=E8=BE=91=EF=BC=88=E6=96=B0=E5=A2=9E=E4=BF=9D=E5=AD=98?= =?UTF-8?q?=E5=9C=BA=E6=99=AF=E8=BD=AC=E6=8D=A2=E5=9D=90=E6=A0=87=E4=B8=BA?= =?UTF-8?q?=E7=9C=9F=E5=AE=9E=E5=9C=B0=E5=9B=BE=E5=8A=9F=E8=83=BD=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/map/constant.ts | 2 + src/apis/scene/type.ts | 1 + src/assets/themes/editor-dark.json | 3 +- src/assets/themes/editor-light.json | 3 +- src/services/editor.service.ts | 86 ++++++++++++++++++++++------- vite.config.ts | 4 +- 6 files changed, 76 insertions(+), 23 deletions(-) diff --git a/src/apis/map/constant.ts b/src/apis/map/constant.ts index f092111..ebe87ad 100644 --- a/src/apis/map/constant.ts +++ b/src/apis/map/constant.ts @@ -16,6 +16,8 @@ export enum MapPointType { 避让点, /** 临时避让点 - 动态生成的临时避让位置,有特殊标记 */ 临时避让点, + /** 库区点 - 仓储作业区域 */ + 库区点, /** 电梯点 - 机器人乘坐电梯的专用点位 */ 电梯点 = 11, diff --git a/src/apis/scene/type.ts b/src/apis/scene/type.ts index 4cf92b2..687f710 100644 --- a/src/apis/scene/type.ts +++ b/src/apis/scene/type.ts @@ -27,6 +27,7 @@ export interface StandardScene { blocks?: Array<[number, number]>; // 障碍点集合 width?: number; // 场景宽度 height?: number; // 场景高度 + ratio?: number; // 坐标缩放比例 } export interface StandardScenePoint { id: string; diff --git a/src/assets/themes/editor-dark.json b/src/assets/themes/editor-dark.json index bda327b..9e23300 100644 --- a/src/assets/themes/editor-dark.json +++ b/src/assets/themes/editor-dark.json @@ -7,7 +7,8 @@ "fill-1": "#14D1A5", "fill-2": "#69C6F5", "fill-3": "#E48B1D", - "fill-4": "#E48B1D" + "fill-4": "#E48B1D", + "fill-17": "#b9bd07" }, "point-l": { "stroke": "#595959", diff --git a/src/assets/themes/editor-light.json b/src/assets/themes/editor-light.json index edf2180..21262fc 100644 --- a/src/assets/themes/editor-light.json +++ b/src/assets/themes/editor-light.json @@ -7,7 +7,8 @@ "fill-1": "#14D1A5", "fill-2": "#69C6F5", "fill-3": "#E48B1D", - "fill-4": "#E48B1D" + "fill-4": "#E48B1D", + "fill-5": "#b9bd07" }, "point-l": { "stroke": "#595959", diff --git a/src/services/editor.service.ts b/src/services/editor.service.ts index fc48971..1ccf823 100644 --- a/src/services/editor.service.ts +++ b/src/services/editor.service.ts @@ -52,10 +52,10 @@ export class EditorService extends Meta2d { scene.robotGroups = [detail.group]; scene.robots = detail.robots; } - const { robotGroups, robots, points, routes, areas, width, height } = scene; + const { robotGroups, robots, points, routes, areas, ...extraFields } = scene; - // 保存width和height字段 - this.#originalSceneData = { width, height }; + // 保存所有额外字段(包括width、height等) + this.#originalSceneData = extraFields; this.open(); this.setState(editable); @@ -79,8 +79,7 @@ export class EditorService extends Meta2d { routes: this.routes.value.map((v) => this.#mapSceneRoute(v)).filter((v) => !isNil(v)), areas: this.areas.value.map((v) => this.#mapSceneArea(v)).filter((v) => !isNil(v)), blocks: [], - width: this.#originalSceneData?.width, // 保留width字段 - height: this.#originalSceneData?.height, // 保留height字段 + ...this.#originalSceneData, // 统一保留所有额外字段(包括width、height等) }; return JSON.stringify(scene); @@ -162,12 +161,16 @@ export class EditorService extends Meta2d { const { id, label, desc, properties } = pen; const { type, robots, actions } = pen.point; const { x = 0, y = 0 } = this.getPointRect(pen) ?? {}; + + // 进行坐标转换:左上角原点 -> 中心点原点,同时应用ratio缩放 + const transformedCoords = this.#transformCoordinate(x, y); + const point: StandardScenePoint = { id: id, name: label || id, desc, - x, - y, + x: transformedCoords.x, + y: transformedCoords.y, type, config: {}, properties, @@ -200,14 +203,20 @@ export class EditorService extends Meta2d { const { x: x2, y: y2 } = this.getPointRect(p2)!; const cp1 = { x: x1 + (c1?.x ?? 0), y: y1 + (c1?.y ?? 0) }; const cp2 = { x: x2 + (c2?.x ?? 0), y: y2 + (c2?.y ?? 0) }; + switch (type) { case MapRouteType.二阶贝塞尔曲线: - route.c1 = cp1; + // 对控制点进行坐标转换 + route.c1 = this.#transformCoordinate(cp1.x, cp1.y); break; - case MapRouteType.三阶贝塞尔曲线: - route.c1 = direction < 0 ? cp2 : cp1; - route.c2 = direction < 0 ? cp1 : cp2; + case MapRouteType.三阶贝塞尔曲线: { + // 对两个控制点进行坐标转换 + const transformedCp1 = this.#transformCoordinate(cp1.x, cp1.y); + const transformedCp2 = this.#transformCoordinate(cp2.x, cp2.y); + route.c1 = direction < 0 ? transformedCp2 : transformedCp1; + route.c2 = direction < 0 ? transformedCp1 : transformedCp2; break; + } default: break; } @@ -218,14 +227,16 @@ export class EditorService extends Meta2d { const { id, label, desc, properties } = pen; const { type, points, routes } = pen.area; const { x, y, width, height } = this.getPenRect(pen); + // 进行坐标转换:左上角原点 -> 中心点原点,同时应用ratio缩放 + const transformedCoords = this.#transformCoordinate(x, y); const area: StandardSceneArea = { id, name: label || id, desc, - x, - y, - w: width, - h: height, + x: transformedCoords.x, + y: transformedCoords.y, + w: this.#transformSize(width), + h: this.#transformSize(height), type, config: {}, properties, @@ -373,8 +384,44 @@ export class EditorService extends Meta2d { } //#endregion - /** 保存width和height字段 */ - #originalSceneData?: { width?: number; height?: number }; + /** 保存从后台传来的所有额外字段(除了已处理的robotGroups、robots、points、routes、areas之外的字段) */ + #originalSceneData?: Partial; + + /** 坐标转换方法 - 将左上角原点的坐标转换为中心点原点的坐标 */ + #transformCoordinate(x: number, y: number): { x: number; y: number } { + const { ratio = 1, width = 0, height = 0 } = this.#originalSceneData ?? {}; + + // 先根据ratio进行缩放 + const scaledX = x / ratio; + const scaledY = y / ratio; + + // 再进行坐标系转换:左上角原点 -> 中心点原点 + const centerX = scaledX - width / 2; + const centerY = height / 2 - scaledY; + + // 应用精度控制:保留3位小数,之后直接舍去 + return { + x: this.#fixPrecision(centerX), + y: this.#fixPrecision(centerY), + }; + } + + /** 尺寸转换方法 - 根据ratio缩放尺寸 */ + #transformSize(size: number): number { + const { ratio = 1 } = this.#originalSceneData ?? {}; + const scaledSize = size / ratio; + + // 应用精度控制:保留3位小数,之后直接舍去 + return this.#fixPrecision(scaledSize); + } + + /** 精度控制方法 - 固定3位小数,3位之后直接舍去(不四舍五入),不足3位则补齐 */ + #fixPrecision(value: number): number { + // 先截断到3位小数(不四舍五入) + const truncated = Math.floor(value * 1000) / 1000; + // 然后格式化为固定3位小数的字符串,再转回数字 + return parseFloat(truncated.toFixed(3)); + } /** 画布变化事件流,用于触发响应式数据更新 */ readonly #change$$ = new Subject(); @@ -497,11 +544,11 @@ export class EditorService extends Meta2d { const theme = this.data().theme; const image = import.meta.env.BASE_URL + (active ? `/robot/${type}-active-${theme}.png` : `/robot/${type}-${theme}.png`); - + // 根据当前缩放比例调整iconTop,避免15%等特定缩放下的像素对齐问题(小车和光圈没重合的问题) const scale = this.store.data.scale || 1; const iconTop = Math.round(-5 * scale) / scale; - + return { image, iconWidth: 34, iconHeight: 54, iconTop }; } //#endregion @@ -834,6 +881,7 @@ function drawPoint(ctx: CanvasRenderingContext2D, pen: MapPen): void { case MapPointType.等待点: case MapPointType.避让点: case MapPointType.临时避让点: + case MapPointType.库区点: ctx.beginPath(); ctx.moveTo(x + w / 2 - r, y + r); ctx.arcTo(x + w / 2, y, x + w - r, y + h / 2 - r, r); diff --git a/vite.config.ts b/vite.config.ts index 748568b..9bcb965 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -45,12 +45,12 @@ export default ({ mode }: Record) => proxy: { '/mocks/': { target: 'http://localhost:8888/web-amr' }, '/api/': { - target: 'http://192.168.189.97:8080/jeecg-boot', + target: 'http://192.168.189.206:8080/jeecg-boot', rewrite: (path) => path.replace(/^\/api/, ''), changeOrigin: true, }, '/ws/': { - target: 'ws://192.168.189.97:8080/jeecg-boot', + target: 'ws://192.168.189.206:8080/jeecg-boot', rewrite: (path) => path.replace(/^\/ws/, ''), changeOrigin: true, ws: true,