@pisell/materials 1.8.54 → 1.8.55
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/lowcode/assets-daily.json +11 -11
- package/build/lowcode/assets-dev.json +2 -2
- package/build/lowcode/assets-prod.json +11 -11
- package/build/lowcode/meta.js +3 -3
- package/build/lowcode/render/default/view.css +1 -1
- package/build/lowcode/render/default/view.js +35 -35
- package/build/lowcode/view.css +1 -1
- package/build/lowcode/view.js +35 -35
- package/es/components/buttonGroupPreview/index.js +8 -4
- package/es/components/pisellFloorMapLayout/PisellFloorMapLayout.js +207 -49
- package/es/components/pisellFloorMapLayout/PisellFloorMapLayout.less +33 -2
- package/es/components/pisellFloorMapLayout/appearance/floorMapAppearance.js +50 -2
- package/es/components/pisellFloorMapLayout/components/EdgeLayer.js +252 -0
- package/es/components/pisellFloorMapLayout/components/EdgeLayer.less +11 -0
- package/es/components/pisellFloorMapLayout/components/EditableItemLayer.js +179 -29
- package/es/components/pisellFloorMapLayout/components/EditableItemLayer.less +0 -28
- package/es/components/pisellFloorMapLayout/components/FloorMapEdgeEditPanel.js +131 -0
- package/es/components/pisellFloorMapLayout/components/FloorMapEdgeEditPanel.less +65 -0
- package/es/components/pisellFloorMapLayout/components/FloorMapEditPanel.js +5 -4
- package/es/components/pisellFloorMapLayout/components/FloorMapEditPanel.less +12 -1
- package/es/components/pisellFloorMapLayout/components/FloorMapEditQuickActions.js +8 -1
- package/es/components/pisellFloorMapLayout/components/FloorMapOverview.js +16 -8
- package/es/components/pisellFloorMapLayout/components/FloorMapOverview.less +69 -17
- package/es/components/pisellFloorMapLayout/components/FloorMapToolbar.js +290 -147
- package/es/components/pisellFloorMapLayout/components/FloorMapToolbar.less +210 -11
- package/es/components/pisellFloorMapLayout/components/FloorMapToolbarViewAllModal.js +81 -0
- package/es/components/pisellFloorMapLayout/components/FloorMapZoneElement.d.ts +8 -0
- package/es/components/pisellFloorMapLayout/components/FloorMapZoneElement.js +21 -0
- package/es/components/pisellFloorMapLayout/components/FloorMapZoneElement.less +74 -0
- package/es/components/pisellFloorMapLayout/components/ItemLayer.less +3 -1
- package/es/components/pisellFloorMapLayout/components/NodePortMarkers.js +70 -0
- package/es/components/pisellFloorMapLayout/components/NodePortMarkers.less +33 -0
- package/es/components/pisellFloorMapLayout/components/ViewControls.js +13 -5
- package/es/components/pisellFloorMapLayout/components/ViewControlsWithZoom.js +2 -0
- package/es/components/pisellFloorMapLayout/context/mergeFloorMapLayoutContext.js +2 -1
- package/es/components/pisellFloorMapLayout/floorMapLayoutConstants.js +1 -1
- package/es/components/pisellFloorMapLayout/hooks/useFloorMapEdgeEditing.js +340 -0
- package/es/components/pisellFloorMapLayout/hooks/useFloorMapEdgeViewModel.js +102 -0
- package/es/components/pisellFloorMapLayout/hooks/useFloorMapEditState.js +244 -84
- package/es/components/pisellFloorMapLayout/hooks/useFloorMapTransformMetrics.js +54 -0
- package/es/components/pisellFloorMapLayout/hooks/useShopFloorPlanSubscription.js +7 -4
- package/es/components/pisellFloorMapLayout/index.d.ts +5 -1
- package/es/components/pisellFloorMapLayout/locales-ja.js +14 -2
- package/es/components/pisellFloorMapLayout/locales-pt.js +14 -2
- package/es/components/pisellFloorMapLayout/locales.js +161 -8
- package/es/components/pisellFloorMapLayout/types.d.ts +86 -4
- package/es/components/pisellFloorMapLayout/types.js +5 -1
- package/es/components/pisellFloorMapLayout/utils/alignSnap.js +170 -0
- package/es/components/pisellFloorMapLayout/utils/batchScenePlacementLayout.js +86 -0
- package/es/components/pisellFloorMapLayout/utils/edgeRouting.js +942 -0
- package/es/components/pisellFloorMapLayout/utils/floorMapCanvasDisplay.d.ts +7 -0
- package/es/components/pisellFloorMapLayout/utils/floorMapCanvasStage.js +23 -1
- package/es/components/pisellFloorMapLayout/utils/floorMapConfigMerge.js +11 -2
- package/es/components/pisellFloorMapLayout/utils/floorMapElementKindUtils.js +20 -3
- package/es/components/pisellFloorMapLayout/utils/floorMapFallbackRender.js +11 -5
- package/es/components/pisellFloorMapLayout/utils/floorMapOverviewLayout.js +5 -3
- package/es/components/pisellFloorMapLayout/utils/floorMapResourcePickerDisplay.d.ts +20 -0
- package/es/components/pisellFloorMapLayout/utils/floorMapResourcePickerDisplay.js +62 -0
- package/es/components/pisellFloorMapLayout/utils/floorMapResourcePickerTypes.d.ts +83 -0
- package/es/components/pisellFloorMapLayout/utils/floorMapResourcePickerTypes.js +29 -0
- package/es/components/pisellFloorMapLayout/utils/floorMapToolbarPalette.js +51 -0
- package/es/components/productCard/cartSkuCard/components/BookingItem/index.js +14 -0
- package/es/components/productCard/cartSkuCard/components/BookingItem/index.less +32 -0
- package/es/components/productCard/cartSkuCard/components/timeRange/index.js +1 -2
- package/es/components/productCard/cartSkuCard/index.js +17 -11
- package/es/components/productCard/lineItem/BookingLineItem.js +6 -4
- package/es/components/productCard/lineItem/components/Resources/index.js +45 -0
- package/es/components/productCard/lineItem/components/TimeRange/index.js +64 -0
- package/es/components/productCard/lineItem/index.js +2 -1
- package/es/components/productCard/lineItem/index.less +21 -10
- package/es/index.d.ts +6 -2
- package/es/index.js +6 -2
- package/es/pisell-materials.tw.css +3 -0
- package/lib/components/buttonGroupPreview/index.js +8 -4
- package/lib/components/pisellFloorMapLayout/PisellFloorMapLayout.js +206 -48
- package/lib/components/pisellFloorMapLayout/PisellFloorMapLayout.less +33 -2
- package/lib/components/pisellFloorMapLayout/appearance/floorMapAppearance.js +50 -2
- package/lib/components/pisellFloorMapLayout/components/EdgeLayer.js +255 -0
- package/lib/components/pisellFloorMapLayout/components/EdgeLayer.less +11 -0
- package/lib/components/pisellFloorMapLayout/components/EditableItemLayer.js +179 -29
- package/lib/components/pisellFloorMapLayout/components/EditableItemLayer.less +0 -28
- package/lib/components/pisellFloorMapLayout/components/FloorMapEdgeEditPanel.js +134 -0
- package/lib/components/pisellFloorMapLayout/components/FloorMapEdgeEditPanel.less +65 -0
- package/lib/components/pisellFloorMapLayout/components/FloorMapEditPanel.js +4 -3
- package/lib/components/pisellFloorMapLayout/components/FloorMapEditPanel.less +12 -1
- package/lib/components/pisellFloorMapLayout/components/FloorMapEditQuickActions.js +8 -1
- package/lib/components/pisellFloorMapLayout/components/FloorMapOverview.js +16 -8
- package/lib/components/pisellFloorMapLayout/components/FloorMapOverview.less +69 -17
- package/lib/components/pisellFloorMapLayout/components/FloorMapToolbar.js +287 -144
- package/lib/components/pisellFloorMapLayout/components/FloorMapToolbar.less +210 -11
- package/lib/components/pisellFloorMapLayout/components/FloorMapToolbarViewAllModal.js +84 -0
- package/lib/components/pisellFloorMapLayout/components/FloorMapZoneElement.d.ts +8 -0
- package/lib/components/pisellFloorMapLayout/components/FloorMapZoneElement.js +23 -0
- package/lib/components/pisellFloorMapLayout/components/FloorMapZoneElement.less +74 -0
- package/lib/components/pisellFloorMapLayout/components/ItemLayer.less +3 -1
- package/lib/components/pisellFloorMapLayout/components/NodePortMarkers.js +73 -0
- package/lib/components/pisellFloorMapLayout/components/NodePortMarkers.less +33 -0
- package/lib/components/pisellFloorMapLayout/components/ViewControls.js +12 -4
- package/lib/components/pisellFloorMapLayout/components/ViewControlsWithZoom.js +2 -0
- package/lib/components/pisellFloorMapLayout/context/mergeFloorMapLayoutContext.js +2 -1
- package/lib/components/pisellFloorMapLayout/floorMapLayoutConstants.js +1 -1
- package/lib/components/pisellFloorMapLayout/hooks/useFloorMapEdgeEditing.js +341 -0
- package/lib/components/pisellFloorMapLayout/hooks/useFloorMapEdgeViewModel.js +103 -0
- package/lib/components/pisellFloorMapLayout/hooks/useFloorMapEditState.js +242 -82
- package/lib/components/pisellFloorMapLayout/hooks/useFloorMapTransformMetrics.js +54 -0
- package/lib/components/pisellFloorMapLayout/hooks/useShopFloorPlanSubscription.js +7 -4
- package/lib/components/pisellFloorMapLayout/index.d.ts +5 -1
- package/lib/components/pisellFloorMapLayout/locales-ja.js +14 -2
- package/lib/components/pisellFloorMapLayout/locales-pt.js +14 -2
- package/lib/components/pisellFloorMapLayout/locales.js +161 -8
- package/lib/components/pisellFloorMapLayout/types.d.ts +86 -4
- package/lib/components/pisellFloorMapLayout/types.js +5 -0
- package/lib/components/pisellFloorMapLayout/utils/alignSnap.js +170 -0
- package/lib/components/pisellFloorMapLayout/utils/batchScenePlacementLayout.js +87 -0
- package/lib/components/pisellFloorMapLayout/utils/edgeRouting.js +956 -0
- package/lib/components/pisellFloorMapLayout/utils/floorMapCanvasDisplay.d.ts +7 -0
- package/lib/components/pisellFloorMapLayout/utils/floorMapCanvasStage.js +23 -0
- package/lib/components/pisellFloorMapLayout/utils/floorMapConfigMerge.js +11 -2
- package/lib/components/pisellFloorMapLayout/utils/floorMapElementKindUtils.js +21 -2
- package/lib/components/pisellFloorMapLayout/utils/floorMapFallbackRender.js +11 -5
- package/lib/components/pisellFloorMapLayout/utils/floorMapOverviewLayout.js +5 -3
- package/lib/components/pisellFloorMapLayout/utils/floorMapResourcePickerDisplay.d.ts +20 -0
- package/lib/components/pisellFloorMapLayout/utils/floorMapResourcePickerDisplay.js +64 -0
- package/lib/components/pisellFloorMapLayout/utils/floorMapResourcePickerTypes.d.ts +83 -0
- package/lib/components/pisellFloorMapLayout/utils/floorMapResourcePickerTypes.js +29 -0
- package/lib/components/pisellFloorMapLayout/utils/floorMapToolbarPalette.js +54 -0
- package/lib/components/productCard/cartSkuCard/components/BookingItem/index.js +17 -0
- package/lib/components/productCard/cartSkuCard/components/BookingItem/index.less +32 -0
- package/lib/components/productCard/cartSkuCard/components/timeRange/index.js +1 -2
- package/lib/components/productCard/cartSkuCard/index.js +17 -11
- package/lib/components/productCard/lineItem/BookingLineItem.js +6 -4
- package/lib/components/productCard/lineItem/components/Resources/index.js +47 -0
- package/lib/components/productCard/lineItem/components/TimeRange/index.js +67 -0
- package/lib/components/productCard/lineItem/index.js +2 -1
- package/lib/components/productCard/lineItem/index.less +21 -10
- package/lib/index.d.ts +6 -2
- package/lib/index.js +11 -0
- package/lib/pisell-materials.tw.css +3 -0
- package/package.json +4 -1
|
@@ -8,9 +8,12 @@ const require_floorMapElementKindUtils = require("../utils/floorMapElementKindUt
|
|
|
8
8
|
const require_useEngineContext = require("../../../hooks/useEngineContext.js");
|
|
9
9
|
const require_utils = require("../../translation/utils.js");
|
|
10
10
|
const require_floorMapCanvasDisplay = require("../utils/floorMapCanvasDisplay.js");
|
|
11
|
+
const require_layoutMeasurements = require("../utils/layoutMeasurements.js");
|
|
11
12
|
const require_floorMapConfigMerge = require("../utils/floorMapConfigMerge.js");
|
|
12
13
|
const require_useDraftConfigHistory = require("./useDraftConfigHistory.js");
|
|
13
14
|
const require_floorMapViewConfigDiff = require("../utils/floorMapViewConfigDiff.js");
|
|
15
|
+
const require_floorMapCanvasStage = require("../utils/floorMapCanvasStage.js");
|
|
16
|
+
const require_batchScenePlacementLayout = require("../utils/batchScenePlacementLayout.js");
|
|
14
17
|
let react = require("react");
|
|
15
18
|
let _pisell_utils = require("@pisell/utils");
|
|
16
19
|
let antd = require("antd");
|
|
@@ -35,6 +38,11 @@ const BUILTIN_SHAPE_PLACE_DEFAULT = {
|
|
|
35
38
|
height: 96
|
|
36
39
|
};
|
|
37
40
|
const I18N_PLACEMENT_FALLBACK_IMAGE = "pisell-floor-map-layout.placement.fallback-image-name";
|
|
41
|
+
const I18N_PLACEMENT_ZONE_NAME = "pisell-floor-map-layout.zone.unnamed";
|
|
42
|
+
const ZONE_PLACE_DEFAULT = {
|
|
43
|
+
width: 240,
|
|
44
|
+
height: 160
|
|
45
|
+
};
|
|
38
46
|
const GRID_VIS_STORAGE_PREFIX = "pisell-floor-map-layout.grid-visible";
|
|
39
47
|
function getGridVisStorageKey(canvasId) {
|
|
40
48
|
return `${GRID_VIS_STORAGE_PREFIX}:${canvasId}`;
|
|
@@ -55,8 +63,18 @@ function writeStoredGridVisible(canvasId, visible) {
|
|
|
55
63
|
localStorage.setItem(getGridVisStorageKey(canvasId), visible ? "1" : "0");
|
|
56
64
|
} catch (_unused2) {}
|
|
57
65
|
}
|
|
58
|
-
/**
|
|
59
|
-
|
|
66
|
+
/** 与 props 同步 / dirty 基线一致:合并 localStorage 中的网格显隐偏好 */
|
|
67
|
+
function normalizeFloorMapConfigWithStoredGrid(floorMapConfigProp) {
|
|
68
|
+
const baseConfig = require_floorMapViewConfigDiff.normalizeFloorMapViewConfigFromProp(floorMapConfigProp);
|
|
69
|
+
return require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, baseConfig), {}, { canvases: baseConfig.canvases.map((canvas) => {
|
|
70
|
+
var _canvas$mapLayer;
|
|
71
|
+
const stored = readStoredGridVisible(canvas.id);
|
|
72
|
+
if (stored == null) return canvas;
|
|
73
|
+
return require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, canvas), {}, { mapLayer: require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, (_canvas$mapLayer = canvas.mapLayer) !== null && _canvas$mapLayer !== void 0 ? _canvas$mapLayer : {}), {}, { showGrid: stored }) });
|
|
74
|
+
}) });
|
|
75
|
+
}
|
|
76
|
+
/** 复制单个图元时的错位偏移(内容坐标) */
|
|
77
|
+
const DUPLICATE_PLACE_OFFSET = 16;
|
|
60
78
|
function newInstanceId() {
|
|
61
79
|
return `elm_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
|
|
62
80
|
}
|
|
@@ -66,9 +84,61 @@ function duplicateBinding(elements, binding, exceptInstanceId) {
|
|
|
66
84
|
return e.instanceId !== exceptInstanceId && ((_e$dataBinding = e.dataBinding) === null || _e$dataBinding === void 0 ? void 0 : _e$dataBinding.dataSourceKey) === binding.dataSourceKey && ((_e$dataBinding2 = e.dataBinding) === null || _e$dataBinding2 === void 0 ? void 0 : _e$dataBinding2.recordId) === binding.recordId;
|
|
67
85
|
});
|
|
68
86
|
}
|
|
87
|
+
/** 解析落点图元的默认像素尺寸(与 applyScenePlacementAtCoords 一致) */
|
|
88
|
+
function resolveScenePlacementDimensions(config, scene) {
|
|
89
|
+
var _scene$builtinShapeKe, _FLOOR_MAP_BUILTIN_SH, _builtinDef$defaultSi, _builtinDef$defaultSi2;
|
|
90
|
+
const defaultPlacementWidth = require_floorMapElementKindUtils.FLOOR_MAP_RESOURCE_PLACE_DEFAULT.width;
|
|
91
|
+
const defaultPlacementHeight = require_floorMapElementKindUtils.FLOOR_MAP_RESOURCE_PLACE_DEFAULT.height;
|
|
92
|
+
const defaultDecoSize = 48;
|
|
93
|
+
const kindConfig = require_floorMapElementKindUtils.getElementKindConfig(config, scene.elementKind);
|
|
94
|
+
const policy = require_floorMapElementKindUtils.resolveDataBindingPolicy(kindConfig);
|
|
95
|
+
const isStage = scene.elementKind === require_types.FLOOR_MAP_STAGE_ELEMENT_KIND;
|
|
96
|
+
const isZone = scene.elementKind === require_types.FLOOR_MAP_ZONE_ELEMENT_KIND;
|
|
97
|
+
const isImage = require_floorMapElementKindUtils.isFloorMapImageElementKind(scene.elementKind);
|
|
98
|
+
const isBuiltinShape = require_floorMapElementKindUtils.isFloorMapBuiltinShapeElementKind(scene.elementKind);
|
|
99
|
+
const initialBuiltinShapeKey = isBuiltinShape ? (_scene$builtinShapeKe = scene.builtinShapeKey) !== null && _scene$builtinShapeKe !== void 0 ? _scene$builtinShapeKe : (_FLOOR_MAP_BUILTIN_SH = require_floorMapBuiltinShapes.FLOOR_MAP_BUILTIN_SHAPES[0]) === null || _FLOOR_MAP_BUILTIN_SH === void 0 ? void 0 : _FLOOR_MAP_BUILTIN_SH.key : void 0;
|
|
100
|
+
const builtinDef = isBuiltinShape ? require_floorMapBuiltinShapes.getFloorMapBuiltinShapeDef(initialBuiltinShapeKey) : void 0;
|
|
101
|
+
const width = isImage ? IMAGE_PLACE_DEFAULT.width : isZone ? ZONE_PLACE_DEFAULT.width : isStage ? require_floorMapStageDefaults.STAGE_DECO_DEFAULT.width : isBuiltinShape ? (_builtinDef$defaultSi = builtinDef === null || builtinDef === void 0 ? void 0 : builtinDef.defaultSize.width) !== null && _builtinDef$defaultSi !== void 0 ? _builtinDef$defaultSi : BUILTIN_SHAPE_PLACE_DEFAULT.width : defaultPlacementWidth;
|
|
102
|
+
const height = isImage ? IMAGE_PLACE_DEFAULT.height : isZone ? ZONE_PLACE_DEFAULT.height : isStage ? require_floorMapStageDefaults.STAGE_DECO_DEFAULT.height : isBuiltinShape ? (_builtinDef$defaultSi2 = builtinDef === null || builtinDef === void 0 ? void 0 : builtinDef.defaultSize.height) !== null && _builtinDef$defaultSi2 !== void 0 ? _builtinDef$defaultSi2 : BUILTIN_SHAPE_PLACE_DEFAULT.height : defaultPlacementHeight;
|
|
103
|
+
const useDecoSize = policy === "none" && !isStage && !isZone && !isImage && !isBuiltinShape;
|
|
104
|
+
return {
|
|
105
|
+
width: useDecoSize ? defaultDecoSize : width,
|
|
106
|
+
height: useDecoSize ? defaultDecoSize : height,
|
|
107
|
+
useDecoSize,
|
|
108
|
+
isStage,
|
|
109
|
+
isZone,
|
|
110
|
+
isImage,
|
|
111
|
+
isBuiltinShape,
|
|
112
|
+
initialBuiltinShapeKey,
|
|
113
|
+
kindConfig
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
function buildPlacedSceneElement(params, dims) {
|
|
117
|
+
const { canvasId, scene, x, y, name, dataBinding } = params;
|
|
118
|
+
const { width, height, isStage, isZone, isImage, isBuiltinShape, initialBuiltinShapeKey, kindConfig } = dims;
|
|
119
|
+
return require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({
|
|
120
|
+
instanceId: newInstanceId(),
|
|
121
|
+
canvasId,
|
|
122
|
+
x: Math.round(x),
|
|
123
|
+
y: Math.round(y),
|
|
124
|
+
name,
|
|
125
|
+
zIndex: isZone ? -100 : isImage || isBuiltinShape ? -5 : 0,
|
|
126
|
+
width: Math.round(width),
|
|
127
|
+
height: Math.round(height),
|
|
128
|
+
elementKind: scene.elementKind,
|
|
129
|
+
shape: isStage || isZone || isImage || isBuiltinShape ? "rect" : kindConfig === null || kindConfig === void 0 ? void 0 : kindConfig.defaultShape,
|
|
130
|
+
dataBinding
|
|
131
|
+
}, isZone ? { isZone: true } : {}), isImage ? { imageUrl: "" } : {}), isBuiltinShape ? { builtinShapeKey: initialBuiltinShapeKey } : {});
|
|
132
|
+
}
|
|
69
133
|
function useFloorMapEditState(params) {
|
|
70
134
|
var _engineCtx$engine, _selectedItem$_sceneE;
|
|
71
|
-
const { floorMapConfigProp, isFloorMapView, itemsProp, cellSizeProp, dataSources, onSave, onDataSourceRecordSave, dataSourceFormColumns, dataSourceRecordForm, dataSourceLabels, layoutPrefix, contentOffsetRef, showDataSourceRecordFormBlock } = params;
|
|
135
|
+
const { floorMapConfigProp, isFloorMapView, itemsProp, cellSizeProp, dataSources, onSave, onDataSourceRecordSave, dataSourceFormColumns, dataSourceRecordForm, dataSourceLabels, layoutPrefix, contentOffsetRef, showDataSourceRecordFormBlock, focusViewportOnBoundsRef } = params;
|
|
136
|
+
const scheduleFocusOnPlacements = (0, react.useCallback)((positions, sizes) => {
|
|
137
|
+
var _focusViewportOnBound;
|
|
138
|
+
const box = require_batchScenePlacementLayout.getPlacementBoundingBox(positions, sizes);
|
|
139
|
+
if (!box) return;
|
|
140
|
+
focusViewportOnBoundsRef === null || focusViewportOnBoundsRef === void 0 || (_focusViewportOnBound = focusViewportOnBoundsRef.current) === null || _focusViewportOnBound === void 0 || _focusViewportOnBound.call(focusViewportOnBoundsRef, box);
|
|
141
|
+
}, [focusViewportOnBoundsRef]);
|
|
72
142
|
const engineCtx = require_useEngineContext.default();
|
|
73
143
|
const engineLocale = (engineCtx === null || engineCtx === void 0 || (_engineCtx$engine = engineCtx.engine) === null || _engineCtx$engine === void 0 || (_engineCtx$engine = _engineCtx$engine.props) === null || _engineCtx$engine === void 0 ? void 0 : _engineCtx$engine.locale) || "zh-CN";
|
|
74
144
|
/**
|
|
@@ -97,21 +167,32 @@ function useFloorMapEditState(params) {
|
|
|
97
167
|
const config = isFloorMapView ? draftConfig !== null && draftConfig !== void 0 ? draftConfig : floorMapConfigProp : null;
|
|
98
168
|
const configRef = (0, react.useRef)(config);
|
|
99
169
|
configRef.current = config;
|
|
170
|
+
/** 上一次已从 props 写入草稿的配置;用于区分「接口刚下发」与「用户本地改过」 */
|
|
171
|
+
const lastSyncedPropConfigRef = (0, react.useRef)(null);
|
|
100
172
|
(0, react.useEffect)(() => {
|
|
101
|
-
if (!floorMapConfigProp)
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
173
|
+
if (!floorMapConfigProp) {
|
|
174
|
+
lastSyncedPropConfigRef.current = null;
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
const nextConfig = normalizeFloorMapConfigWithStoredGrid(floorMapConfigProp);
|
|
178
|
+
const lastSynced = lastSyncedPropConfigRef.current;
|
|
179
|
+
/**
|
|
180
|
+
* 仅当「自上次 props 同步后用户又改过草稿」时拒绝覆盖:
|
|
181
|
+
* - 接口/订阅首次带回 layout:草稿仍等于上次 props → 必须 replace,否则会空白;
|
|
182
|
+
* - 编辑中落了新图元:草稿已与 lastSynced 不同 → 拒绝旧 props 覆盖。
|
|
183
|
+
*/
|
|
184
|
+
if (draftConfig && lastSynced != null) {
|
|
185
|
+
const propMatchesDraft = require_floorMapViewConfigDiff.floorMapViewConfigsEqual(draftConfig, nextConfig);
|
|
186
|
+
const draftMatchesLastSynced = require_floorMapViewConfigDiff.floorMapViewConfigsEqual(draftConfig, lastSynced);
|
|
187
|
+
if (!propMatchesDraft && !draftMatchesLastSynced) return;
|
|
188
|
+
}
|
|
109
189
|
/**
|
|
110
190
|
* 上游配置变更:直接 replace(不进入历史栈),并清空 undo/redo;
|
|
111
191
|
* 同时清空本地临时保存基线,让 dirty/未保存提示与上游对齐。
|
|
112
192
|
*/
|
|
113
193
|
replaceDraft(nextConfig);
|
|
114
|
-
|
|
194
|
+
lastSyncedPropConfigRef.current = nextConfig;
|
|
195
|
+
setSavedBaselineConfig((prev) => prev != null && require_floorMapViewConfigDiff.floorMapViewConfigsEqual(prev, nextConfig) ? prev : null);
|
|
115
196
|
const enabled = nextConfig.canvases.filter((c) => c.enabled).sort((a, b) => a.order - b.order);
|
|
116
197
|
setCurrentCanvasId((prev) => {
|
|
117
198
|
var _enabled$0$id, _enabled$;
|
|
@@ -121,7 +202,7 @@ function useFloorMapEditState(params) {
|
|
|
121
202
|
/** 当前草稿与上游持久化 `floorMapConfig`(经同等规范化)是否不一致 */
|
|
122
203
|
const isLayoutDirty = (0, react.useMemo)(() => {
|
|
123
204
|
if (!isFloorMapView || !draftConfig || !floorMapConfigProp) return false;
|
|
124
|
-
return !require_floorMapViewConfigDiff.floorMapViewConfigsEqual(draftConfig, savedBaselineConfig !== null && savedBaselineConfig !== void 0 ? savedBaselineConfig :
|
|
205
|
+
return !require_floorMapViewConfigDiff.floorMapViewConfigsEqual(draftConfig, savedBaselineConfig !== null && savedBaselineConfig !== void 0 ? savedBaselineConfig : normalizeFloorMapConfigWithStoredGrid(floorMapConfigProp));
|
|
125
206
|
}, [
|
|
126
207
|
isFloorMapView,
|
|
127
208
|
draftConfig,
|
|
@@ -216,6 +297,40 @@ function useFloorMapEditState(params) {
|
|
|
216
297
|
cellSizeProp
|
|
217
298
|
]);
|
|
218
299
|
const items = isFloorMapView ? mergedItems : itemsProp;
|
|
300
|
+
const getBatchPlacementLayoutContext = (0, react.useCallback)(() => {
|
|
301
|
+
var _config$sceneElements, _config$mapLayer, _canvas$mapLayer2;
|
|
302
|
+
const existingElements = ((_config$sceneElements = config === null || config === void 0 ? void 0 : config.sceneElements) !== null && _config$sceneElements !== void 0 ? _config$sceneElements : []).filter((e) => e.canvasId === currentCanvasId).map((e) => {
|
|
303
|
+
var _e$x, _e$y, _e$width, _e$height;
|
|
304
|
+
return {
|
|
305
|
+
x: Math.round((_e$x = e.x) !== null && _e$x !== void 0 ? _e$x : 0),
|
|
306
|
+
y: Math.round((_e$y = e.y) !== null && _e$y !== void 0 ? _e$y : 0),
|
|
307
|
+
width: Math.round((_e$width = e.width) !== null && _e$width !== void 0 ? _e$width : require_floorMapElementKindUtils.FLOOR_MAP_RESOURCE_PLACE_DEFAULT.width),
|
|
308
|
+
height: Math.round((_e$height = e.height) !== null && _e$height !== void 0 ? _e$height : require_floorMapElementKindUtils.FLOOR_MAP_RESOURCE_PLACE_DEFAULT.height)
|
|
309
|
+
};
|
|
310
|
+
});
|
|
311
|
+
const canvas = config === null || config === void 0 ? void 0 : config.canvases.find((c) => c.id === currentCanvasId);
|
|
312
|
+
const mapLayer = require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, (_config$mapLayer = config === null || config === void 0 ? void 0 : config.mapLayer) !== null && _config$mapLayer !== void 0 ? _config$mapLayer : {}), (_canvas$mapLayer2 = canvas === null || canvas === void 0 ? void 0 : canvas.mapLayer) !== null && _canvas$mapLayer2 !== void 0 ? _canvas$mapLayer2 : {});
|
|
313
|
+
const padSingle = typeof mapLayer.boundingPadding === "number" ? mapLayer.boundingPadding : 56;
|
|
314
|
+
const stage = require_floorMapCanvasStage.computeFloorMapContentStage({
|
|
315
|
+
items: mergedItems,
|
|
316
|
+
cellSize: cellSizeProp !== null && cellSizeProp !== void 0 ? cellSizeProp : 64,
|
|
317
|
+
itemGap: require_layoutMeasurements.gapToPx(mapLayer.gap),
|
|
318
|
+
itemUnit: "pixel",
|
|
319
|
+
boundingPadding: padSingle,
|
|
320
|
+
preferPixelBoundingBox: true
|
|
321
|
+
});
|
|
322
|
+
return {
|
|
323
|
+
existingElements,
|
|
324
|
+
contentWidth: stage.contentWidth,
|
|
325
|
+
contentHeight: stage.contentHeight,
|
|
326
|
+
boundingPadding: padSingle
|
|
327
|
+
};
|
|
328
|
+
}, [
|
|
329
|
+
config,
|
|
330
|
+
currentCanvasId,
|
|
331
|
+
mergedItems,
|
|
332
|
+
cellSizeProp
|
|
333
|
+
]);
|
|
219
334
|
const updateDraftSceneElement = (0, react.useCallback)((instanceId, patch) => {
|
|
220
335
|
commitDraft((prev) => {
|
|
221
336
|
var _prev$sceneElements2, _prev$sceneElements3;
|
|
@@ -244,43 +359,15 @@ function useFloorMapEditState(params) {
|
|
|
244
359
|
* @returns 是否已成功写入草稿(校验失败时为 false)
|
|
245
360
|
*/
|
|
246
361
|
const applyScenePlacementAtCoords = (0, react.useCallback)((contentX, contentY, scene) => {
|
|
247
|
-
var _kindConfig$allowedDa, _ref, _scene$dataSourceKey
|
|
362
|
+
var _kindConfig$allowedDa, _ref, _scene$dataSourceKey;
|
|
248
363
|
if (!config || !currentCanvasId) return false;
|
|
249
|
-
const
|
|
250
|
-
const
|
|
251
|
-
const defaultDecoSize = 48;
|
|
252
|
-
const kindConfig = require_floorMapElementKindUtils.getElementKindConfig(config, scene.elementKind);
|
|
364
|
+
const dims = resolveScenePlacementDimensions(config, scene);
|
|
365
|
+
const kindConfig = dims.kindConfig;
|
|
253
366
|
const policy = require_floorMapElementKindUtils.resolveDataBindingPolicy(kindConfig);
|
|
254
367
|
const allKeys = Object.keys(dataSources !== null && dataSources !== void 0 ? dataSources : {});
|
|
255
368
|
const allowedKeys = (kindConfig === null || kindConfig === void 0 || (_kindConfig$allowedDa = kindConfig.allowedDataSourceKeys) === null || _kindConfig$allowedDa === void 0 ? void 0 : _kindConfig$allowedDa.length) ? kindConfig.allowedDataSourceKeys.filter((k) => allKeys.includes(k)) : allKeys;
|
|
256
369
|
const pickKey = (_ref = (_scene$dataSourceKey = scene.dataSourceKey) !== null && _scene$dataSourceKey !== void 0 ? _scene$dataSourceKey : allowedKeys[0]) !== null && _ref !== void 0 ? _ref : allKeys[0];
|
|
257
370
|
const recordIdsToPlace = scene.recordIds && scene.recordIds.length > 0 ? scene.recordIds : scene.recordId ? [scene.recordId] : [];
|
|
258
|
-
const isStage = scene.elementKind === require_types.FLOOR_MAP_STAGE_ELEMENT_KIND;
|
|
259
|
-
const isImage = require_floorMapElementKindUtils.isFloorMapImageElementKind(scene.elementKind);
|
|
260
|
-
const isBuiltinShape = require_floorMapElementKindUtils.isFloorMapBuiltinShapeElementKind(scene.elementKind);
|
|
261
|
-
/**
|
|
262
|
-
* 内置图形 kind 的初始 `builtinShapeKey`:优先用侧栏 Select 预选的 key
|
|
263
|
-
* (`scene.builtinShapeKey`,由 toolbar 写入 placeMode / drag payload 透传),
|
|
264
|
-
* 未预选时回退为枚举首项,避免空白占位。
|
|
265
|
-
*/
|
|
266
|
-
const initialBuiltinShapeKey = isBuiltinShape ? (_scene$builtinShapeKe = scene.builtinShapeKey) !== null && _scene$builtinShapeKe !== void 0 ? _scene$builtinShapeKe : (_FLOOR_MAP_BUILTIN_SH = require_floorMapBuiltinShapes.FLOOR_MAP_BUILTIN_SHAPES[0]) === null || _FLOOR_MAP_BUILTIN_SH === void 0 ? void 0 : _FLOOR_MAP_BUILTIN_SH.key : void 0;
|
|
267
|
-
const builtinDef = isBuiltinShape ? require_floorMapBuiltinShapes.getFloorMapBuiltinShapeDef(initialBuiltinShapeKey) : void 0;
|
|
268
|
-
const w = isImage ? IMAGE_PLACE_DEFAULT.width : isStage ? require_floorMapStageDefaults.STAGE_DECO_DEFAULT.width : isBuiltinShape ? (_builtinDef$defaultSi = builtinDef === null || builtinDef === void 0 ? void 0 : builtinDef.defaultSize.width) !== null && _builtinDef$defaultSi !== void 0 ? _builtinDef$defaultSi : BUILTIN_SHAPE_PLACE_DEFAULT.width : defaultPlacementWidth;
|
|
269
|
-
const h = isImage ? IMAGE_PLACE_DEFAULT.height : isStage ? require_floorMapStageDefaults.STAGE_DECO_DEFAULT.height : isBuiltinShape ? (_builtinDef$defaultSi2 = builtinDef === null || builtinDef === void 0 ? void 0 : builtinDef.defaultSize.height) !== null && _builtinDef$defaultSi2 !== void 0 ? _builtinDef$defaultSi2 : BUILTIN_SHAPE_PLACE_DEFAULT.height : defaultPlacementHeight;
|
|
270
|
-
const useDecoSize = policy === "none" && scene.elementKind !== "stage" && !isImage && !isBuiltinShape;
|
|
271
|
-
const buildOneElement = (dataBinding, x, y, name) => require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({
|
|
272
|
-
instanceId: newInstanceId(),
|
|
273
|
-
canvasId: currentCanvasId,
|
|
274
|
-
x,
|
|
275
|
-
y,
|
|
276
|
-
name,
|
|
277
|
-
zIndex: isImage || isBuiltinShape ? -5 : 0,
|
|
278
|
-
width: useDecoSize ? defaultDecoSize : w,
|
|
279
|
-
height: useDecoSize ? defaultDecoSize : h,
|
|
280
|
-
elementKind: scene.elementKind,
|
|
281
|
-
shape: isStage || isImage || isBuiltinShape ? "rect" : kindConfig === null || kindConfig === void 0 ? void 0 : kindConfig.defaultShape,
|
|
282
|
-
dataBinding
|
|
283
|
-
}, isImage ? { imageUrl: "" } : {}), isBuiltinShape ? { builtinShapeKey: initialBuiltinShapeKey } : {});
|
|
284
371
|
let dataBinding;
|
|
285
372
|
if (policy !== "none" && pickKey) {
|
|
286
373
|
var _dataSources$pickKey;
|
|
@@ -310,10 +397,9 @@ function useFloorMapEditState(params) {
|
|
|
310
397
|
}
|
|
311
398
|
dataBinding = cand;
|
|
312
399
|
} else {
|
|
313
|
-
const
|
|
400
|
+
const pending = [];
|
|
314
401
|
let skippedDup = 0;
|
|
315
402
|
let skippedMissing = 0;
|
|
316
|
-
let placeIndex = 0;
|
|
317
403
|
const seenInBatch = /* @__PURE__ */ new Set();
|
|
318
404
|
recordIdsToPlace.forEach((rid) => {
|
|
319
405
|
var _row$name;
|
|
@@ -332,46 +418,78 @@ function useFloorMapEditState(params) {
|
|
|
332
418
|
}
|
|
333
419
|
seenInBatch.add(rid);
|
|
334
420
|
const row = record;
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
421
|
+
pending.push({
|
|
422
|
+
binding: cand,
|
|
423
|
+
name: String((_row$name = row === null || row === void 0 ? void 0 : row.name) !== null && _row$name !== void 0 ? _row$name : rid)
|
|
424
|
+
});
|
|
338
425
|
});
|
|
339
426
|
if (skippedDup > 0) antd.message.warning(`已跳过 ${skippedDup} 条已在平面图中绑定的记录`);
|
|
340
427
|
if (skippedMissing > 0) antd.message.warning(`有 ${skippedMissing} 条记录不存在,已跳过`);
|
|
341
|
-
if (
|
|
428
|
+
if (pending.length === 0) {
|
|
342
429
|
antd.message.warning("没有可落位的记录");
|
|
343
430
|
return false;
|
|
344
431
|
}
|
|
432
|
+
const sizes = pending.map(() => ({
|
|
433
|
+
width: dims.width,
|
|
434
|
+
height: dims.height
|
|
435
|
+
}));
|
|
436
|
+
const positions = require_batchScenePlacementLayout.computeBatchScenePlacementPositions(sizes, getBatchPlacementLayoutContext());
|
|
437
|
+
const newEls = pending.map((p, i) => buildPlacedSceneElement({
|
|
438
|
+
canvasId: currentCanvasId,
|
|
439
|
+
scene,
|
|
440
|
+
x: positions[i].x,
|
|
441
|
+
y: positions[i].y,
|
|
442
|
+
name: p.name,
|
|
443
|
+
dataBinding: p.binding
|
|
444
|
+
}, dims));
|
|
345
445
|
commitDraft((prev) => {
|
|
346
446
|
var _prev$sceneElements4;
|
|
347
447
|
return prev ? require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, prev), {}, { sceneElements: [...(_prev$sceneElements4 = prev.sceneElements) !== null && _prev$sceneElements4 !== void 0 ? _prev$sceneElements4 : [], ...newEls] }) : prev;
|
|
348
448
|
});
|
|
449
|
+
scheduleFocusOnPlacements(positions, sizes);
|
|
349
450
|
return true;
|
|
350
451
|
}
|
|
351
452
|
}
|
|
352
|
-
const
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
453
|
+
const newEl = buildPlacedSceneElement({
|
|
454
|
+
canvasId: currentCanvasId,
|
|
455
|
+
scene,
|
|
456
|
+
x: contentX,
|
|
457
|
+
y: contentY,
|
|
458
|
+
name: (() => {
|
|
459
|
+
var _kindConfig$defaultPr, _kindConfig$defaultPr2;
|
|
460
|
+
if (dims.isStage) return require_floorMapStageDefaults.STAGE_DECO_DEFAULT.name;
|
|
461
|
+
if (dims.isZone) return _pisell_utils.locales.getText(I18N_PLACEMENT_ZONE_NAME);
|
|
462
|
+
if (dims.isImage) return _pisell_utils.locales.getText(I18N_PLACEMENT_FALLBACK_IMAGE);
|
|
463
|
+
const db = dataBinding;
|
|
464
|
+
const rid = recordIdsToPlace[0];
|
|
465
|
+
if (db && rid) {
|
|
466
|
+
var _dataSources$db$dataS, _row$name2;
|
|
467
|
+
const row = dataSources === null || dataSources === void 0 || (_dataSources$db$dataS = dataSources[db.dataSourceKey]) === null || _dataSources$db$dataS === void 0 ? void 0 : _dataSources$db$dataS.find((r) => r.id === rid);
|
|
468
|
+
return String((_row$name2 = row === null || row === void 0 ? void 0 : row.name) !== null && _row$name2 !== void 0 ? _row$name2 : rid);
|
|
469
|
+
}
|
|
470
|
+
return (_kindConfig$defaultPr = kindConfig === null || kindConfig === void 0 || (_kindConfig$defaultPr2 = kindConfig.defaultPresentation) === null || _kindConfig$defaultPr2 === void 0 ? void 0 : _kindConfig$defaultPr2.title) !== null && _kindConfig$defaultPr !== void 0 ? _kindConfig$defaultPr : "";
|
|
471
|
+
})(),
|
|
472
|
+
dataBinding
|
|
473
|
+
}, dims);
|
|
366
474
|
commitDraft((prev) => {
|
|
367
475
|
var _prev$sceneElements5;
|
|
368
476
|
return prev ? require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, prev), {}, { sceneElements: [...(_prev$sceneElements5 = prev.sceneElements) !== null && _prev$sceneElements5 !== void 0 ? _prev$sceneElements5 : [], newEl] }) : prev;
|
|
369
477
|
});
|
|
478
|
+
scheduleFocusOnPlacements([{
|
|
479
|
+
x: contentX,
|
|
480
|
+
y: contentY
|
|
481
|
+
}], [{
|
|
482
|
+
width: dims.width,
|
|
483
|
+
height: dims.height
|
|
484
|
+
}]);
|
|
370
485
|
return true;
|
|
371
486
|
}, [
|
|
372
487
|
config,
|
|
373
488
|
currentCanvasId,
|
|
374
|
-
dataSources
|
|
489
|
+
dataSources,
|
|
490
|
+
getBatchPlacementLayoutContext,
|
|
491
|
+
commitDraft,
|
|
492
|
+
scheduleFocusOnPlacements
|
|
375
493
|
]);
|
|
376
494
|
const handleCanvasPlaceClick = (0, react.useCallback)((e) => {
|
|
377
495
|
if (!placeMode || placeMode.type !== "scene" || !config || !currentCanvasId) return;
|
|
@@ -387,8 +505,48 @@ function useFloorMapEditState(params) {
|
|
|
387
505
|
]);
|
|
388
506
|
/** 从左侧图元栏拖拽到画布落位(与点击落点规则一致) */
|
|
389
507
|
const placeSceneElementFromPaletteDrop = (0, react.useCallback)((contentX, contentY, scene) => {
|
|
390
|
-
|
|
508
|
+
const ok = applyScenePlacementAtCoords(contentX, contentY, scene);
|
|
509
|
+
if (ok) setPlaceMode(null);
|
|
510
|
+
return ok;
|
|
391
511
|
}, [applyScenePlacementAtCoords]);
|
|
512
|
+
/**
|
|
513
|
+
* 批量落点(弹窗多选、侧栏多选数据行等):在画布右侧空白区按近方阵网格排列。
|
|
514
|
+
*/
|
|
515
|
+
const bulkPlacePaletteItems = (0, react.useCallback)((items) => {
|
|
516
|
+
if (!items.length || !config || !currentCanvasId) return;
|
|
517
|
+
const scenes = items.map((item) => require_objectSpread2._objectSpread2({
|
|
518
|
+
type: "scene",
|
|
519
|
+
elementKind: item.elementKind
|
|
520
|
+
}, item.builtinShapeKey ? { builtinShapeKey: item.builtinShapeKey } : {}));
|
|
521
|
+
const dimsList = scenes.map((scene) => resolveScenePlacementDimensions(config, scene));
|
|
522
|
+
const sizes = dimsList.map((d) => ({
|
|
523
|
+
width: d.width,
|
|
524
|
+
height: d.height
|
|
525
|
+
}));
|
|
526
|
+
const positions = require_batchScenePlacementLayout.computeBatchScenePlacementPositions(sizes, getBatchPlacementLayoutContext());
|
|
527
|
+
const newEls = scenes.map((scene, i) => {
|
|
528
|
+
var _ref2, _dimsList$i$kindConfi, _dimsList$i$kindConfi2, _dimsList$i$kindConfi3;
|
|
529
|
+
return buildPlacedSceneElement({
|
|
530
|
+
canvasId: currentCanvasId,
|
|
531
|
+
scene,
|
|
532
|
+
x: positions[i].x,
|
|
533
|
+
y: positions[i].y,
|
|
534
|
+
name: (_ref2 = (_dimsList$i$kindConfi = (_dimsList$i$kindConfi2 = dimsList[i].kindConfig) === null || _dimsList$i$kindConfi2 === void 0 ? void 0 : _dimsList$i$kindConfi2.label) !== null && _dimsList$i$kindConfi !== void 0 ? _dimsList$i$kindConfi : (_dimsList$i$kindConfi3 = dimsList[i].kindConfig) === null || _dimsList$i$kindConfi3 === void 0 || (_dimsList$i$kindConfi3 = _dimsList$i$kindConfi3.defaultPresentation) === null || _dimsList$i$kindConfi3 === void 0 ? void 0 : _dimsList$i$kindConfi3.title) !== null && _ref2 !== void 0 ? _ref2 : scene.elementKind
|
|
535
|
+
}, dimsList[i]);
|
|
536
|
+
});
|
|
537
|
+
commitDraft((prev) => {
|
|
538
|
+
var _prev$sceneElements6;
|
|
539
|
+
return prev ? require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, prev), {}, { sceneElements: [...(_prev$sceneElements6 = prev.sceneElements) !== null && _prev$sceneElements6 !== void 0 ? _prev$sceneElements6 : [], ...newEls] }) : prev;
|
|
540
|
+
});
|
|
541
|
+
scheduleFocusOnPlacements(positions, sizes);
|
|
542
|
+
setPlaceMode(null);
|
|
543
|
+
}, [
|
|
544
|
+
config,
|
|
545
|
+
currentCanvasId,
|
|
546
|
+
getBatchPlacementLayoutContext,
|
|
547
|
+
commitDraft,
|
|
548
|
+
scheduleFocusOnPlacements
|
|
549
|
+
]);
|
|
392
550
|
const handleSave = (0, react.useCallback)(() => {
|
|
393
551
|
if (!draftConfig || !onSave) return;
|
|
394
552
|
setSaving(true);
|
|
@@ -415,16 +573,13 @@ function useFloorMapEditState(params) {
|
|
|
415
573
|
const discardDraft = (0, react.useCallback)(() => {
|
|
416
574
|
if (!floorMapConfigProp) {
|
|
417
575
|
replaceDraft(null);
|
|
576
|
+
lastSyncedPropConfigRef.current = null;
|
|
418
577
|
setSavedBaselineConfig(null);
|
|
419
578
|
return;
|
|
420
579
|
}
|
|
421
|
-
const
|
|
422
|
-
replaceDraft(
|
|
423
|
-
|
|
424
|
-
const stored = readStoredGridVisible(canvas.id);
|
|
425
|
-
if (stored == null) return canvas;
|
|
426
|
-
return require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, canvas), {}, { mapLayer: require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, (_canvas$mapLayer2 = canvas.mapLayer) !== null && _canvas$mapLayer2 !== void 0 ? _canvas$mapLayer2 : {}), {}, { showGrid: stored }) });
|
|
427
|
-
}) }));
|
|
580
|
+
const nextConfig = normalizeFloorMapConfigWithStoredGrid(floorMapConfigProp);
|
|
581
|
+
replaceDraft(nextConfig);
|
|
582
|
+
lastSyncedPropConfigRef.current = nextConfig;
|
|
428
583
|
setSavedBaselineConfig(null);
|
|
429
584
|
}, [floorMapConfigProp, replaceDraft]);
|
|
430
585
|
/** 切换当前画布草稿中的 mapLayer.showGrid(随布局保存持久化) */
|
|
@@ -461,12 +616,15 @@ function useFloorMapEditState(params) {
|
|
|
461
616
|
const handleEditPanelDelete = (0, react.useCallback)(() => {
|
|
462
617
|
if (!selectedId) return;
|
|
463
618
|
commitDraft((prev) => {
|
|
464
|
-
var _prev$
|
|
619
|
+
var _prev$sceneElements7, _prev$edges;
|
|
465
620
|
if (!prev) return prev;
|
|
466
|
-
return require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, prev), {}, {
|
|
621
|
+
return require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, prev), {}, {
|
|
622
|
+
sceneElements: ((_prev$sceneElements7 = prev.sceneElements) !== null && _prev$sceneElements7 !== void 0 ? _prev$sceneElements7 : []).filter((e) => e.instanceId !== selectedId),
|
|
623
|
+
edges: ((_prev$edges = prev.edges) !== null && _prev$edges !== void 0 ? _prev$edges : []).filter((edge) => edge.sourceId !== selectedId && edge.targetId !== selectedId)
|
|
624
|
+
});
|
|
467
625
|
});
|
|
468
626
|
setSelectedId(null);
|
|
469
|
-
}, [selectedId]);
|
|
627
|
+
}, [selectedId, commitDraft]);
|
|
470
628
|
/** 与编辑侧栏锁定按钮同源:切换 `layoutTransformLocked` */
|
|
471
629
|
const toggleSelectedLayoutLock = (0, react.useCallback)(() => {
|
|
472
630
|
var _configRef$current2;
|
|
@@ -478,21 +636,21 @@ function useFloorMapEditState(params) {
|
|
|
478
636
|
* 复制选中图元:新实例 + 位移,**清除 dataBinding**(避免与侧栏一致的「同一记录不可重复绑定」冲突)。
|
|
479
637
|
*/
|
|
480
638
|
const duplicateSelectedElement = (0, react.useCallback)(() => {
|
|
481
|
-
var _prev$
|
|
639
|
+
var _prev$sceneElements8, _el$x, _el$y, _prev$sceneElements9;
|
|
482
640
|
if (!selectedId) return;
|
|
483
641
|
const prev = configRef.current;
|
|
484
642
|
if (!prev) return;
|
|
485
|
-
const el = ((_prev$
|
|
643
|
+
const el = ((_prev$sceneElements8 = prev.sceneElements) !== null && _prev$sceneElements8 !== void 0 ? _prev$sceneElements8 : []).find((e) => e.instanceId === selectedId);
|
|
486
644
|
if (!el) return;
|
|
487
645
|
const newId = newInstanceId();
|
|
488
646
|
const copy = require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, el), {}, {
|
|
489
647
|
instanceId: newId,
|
|
490
|
-
x: Math.round(((_el$x = el.x) !== null && _el$x !== void 0 ? _el$x : 0) +
|
|
491
|
-
y: Math.round(((_el$y = el.y) !== null && _el$y !== void 0 ? _el$y : 0) +
|
|
648
|
+
x: Math.round(((_el$x = el.x) !== null && _el$x !== void 0 ? _el$x : 0) + DUPLICATE_PLACE_OFFSET),
|
|
649
|
+
y: Math.round(((_el$y = el.y) !== null && _el$y !== void 0 ? _el$y : 0) + DUPLICATE_PLACE_OFFSET),
|
|
492
650
|
dataBinding: void 0,
|
|
493
651
|
layoutTransformLocked: false
|
|
494
652
|
});
|
|
495
|
-
commitDraft(require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, prev), {}, { sceneElements: [...(_prev$
|
|
653
|
+
commitDraft(require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, prev), {}, { sceneElements: [...(_prev$sceneElements9 = prev.sceneElements) !== null && _prev$sceneElements9 !== void 0 ? _prev$sceneElements9 : [], copy] }));
|
|
496
654
|
setSelectedId(newId);
|
|
497
655
|
}, [selectedId]);
|
|
498
656
|
const selectedItem = selectedId ? mergedItems.find((m) => m.id === selectedId) : null;
|
|
@@ -516,6 +674,7 @@ function useFloorMapEditState(params) {
|
|
|
516
674
|
handleSave,
|
|
517
675
|
discardDraft,
|
|
518
676
|
placeSceneElementFromPaletteDrop,
|
|
677
|
+
bulkPlacePaletteItems,
|
|
519
678
|
editPanelParams: selectedItem && config && selectedId && !((_selectedItem$_sceneE = selectedItem._sceneElement) === null || _selectedItem$_sceneE === void 0 ? void 0 : _selectedItem$_sceneE.layoutTransformLocked) ? {
|
|
520
679
|
itemId: selectedId,
|
|
521
680
|
sceneElement: selectedItem._sceneElement,
|
|
@@ -538,7 +697,8 @@ function useFloorMapEditState(params) {
|
|
|
538
697
|
undoDraft,
|
|
539
698
|
redoDraft,
|
|
540
699
|
canUndo,
|
|
541
|
-
canRedo
|
|
700
|
+
canRedo,
|
|
701
|
+
commitDraft
|
|
542
702
|
};
|
|
543
703
|
}
|
|
544
704
|
//#endregion
|
|
@@ -347,6 +347,59 @@ function useFloorMapTransformMetrics(params) {
|
|
|
347
347
|
/** 让"进入伪全屏后自动 fit"的 effect 能拿到最新的 fitBounds 实现 */
|
|
348
348
|
fitBoundsRef.current = fitBounds;
|
|
349
349
|
/**
|
|
350
|
+
* 将视口平移/缩放至能看见指定内容区包围盒(场景坐标,与 sceneElement x/y 一致)。
|
|
351
|
+
* 批量落点后调用;视口锁定时跳过。
|
|
352
|
+
*/
|
|
353
|
+
const focusContentBounds = (0, react.useCallback)((bounds) => {
|
|
354
|
+
var _ref, _cur$scale;
|
|
355
|
+
if (viewportLockedRef.current || !bounds) return false;
|
|
356
|
+
const ctx = transformRef.current;
|
|
357
|
+
const container = containerRef.current;
|
|
358
|
+
if (!ctx || !container) return false;
|
|
359
|
+
const wrapper = container.querySelector(".react-transform-wrapper");
|
|
360
|
+
if (!wrapper) return false;
|
|
361
|
+
const wEl = wrapper;
|
|
362
|
+
const wrapperRect = wrapper.getBoundingClientRect();
|
|
363
|
+
const layoutW = wEl.clientWidth > 0 ? wEl.clientWidth : wrapperRect.width;
|
|
364
|
+
const layoutH = wEl.clientHeight > 0 ? wEl.clientHeight : wrapperRect.height;
|
|
365
|
+
if (layoutW <= 0 || layoutH <= 0) return false;
|
|
366
|
+
const ox = contentOffsetRef.current.x;
|
|
367
|
+
const oy = contentOffsetRef.current.y;
|
|
368
|
+
const visMinL = bounds.minLeft + ox;
|
|
369
|
+
const visMinT = bounds.minTop + oy;
|
|
370
|
+
const visMaxR = bounds.maxRight + ox;
|
|
371
|
+
const visMaxB = bounds.maxBottom + oy;
|
|
372
|
+
const bw = Math.max(1, visMaxR - visMinL);
|
|
373
|
+
const bh = Math.max(1, visMaxB - visMinT);
|
|
374
|
+
const edgePx = 48;
|
|
375
|
+
const availW = Math.max(1, layoutW - 2 * edgePx);
|
|
376
|
+
const availH = Math.max(1, layoutH - 2 * edgePx);
|
|
377
|
+
const clampFitScale = (raw) => {
|
|
378
|
+
var _zoom$min3, _zoom$max3;
|
|
379
|
+
return Math.max((_zoom$min3 = zoom.min) !== null && _zoom$min3 !== void 0 ? _zoom$min3 : .5, Math.min(raw, (_zoom$max3 = zoom.max) !== null && _zoom$max3 !== void 0 ? _zoom$max3 : 2));
|
|
380
|
+
};
|
|
381
|
+
const cur = lastTransformRef.current;
|
|
382
|
+
const curScale = (_ref = (_cur$scale = cur === null || cur === void 0 ? void 0 : cur.scale) !== null && _cur$scale !== void 0 ? _cur$scale : zoomConfig.initialScale) !== null && _ref !== void 0 ? _ref : 1;
|
|
383
|
+
const rawFit = Math.min(availW / bw, availH / bh);
|
|
384
|
+
let nextScale = curScale;
|
|
385
|
+
if (bw * curScale > availW || bh * curScale > availH) nextScale = clampFitScale(rawFit);
|
|
386
|
+
const bboxCx = visMinL + bw / 2;
|
|
387
|
+
const bboxCy = visMinT + bh / 2;
|
|
388
|
+
const x = layoutW / 2 - bboxCx * nextScale;
|
|
389
|
+
const y = layoutH / 2 - bboxCy * nextScale;
|
|
390
|
+
clearFitBoundsTweenHold();
|
|
391
|
+
lastFitSnapshotRef.current = null;
|
|
392
|
+
setIsAtFitBounds(false);
|
|
393
|
+
ctx.setTransform(x, y, nextScale);
|
|
394
|
+
return true;
|
|
395
|
+
}, [
|
|
396
|
+
clearFitBoundsTweenHold,
|
|
397
|
+
contentOffsetRef,
|
|
398
|
+
transformRef,
|
|
399
|
+
zoom,
|
|
400
|
+
zoomConfig.initialScale
|
|
401
|
+
]);
|
|
402
|
+
/**
|
|
350
403
|
* autoFitOnMount:每个画布在「有图元且 content 尺寸已按包围盒算好」后执行一次 fitBounds。
|
|
351
404
|
* 避免首帧 items 仍为空时用占位尺寸 fit 完并标记 done,导致异步图元加载后不再适配。
|
|
352
405
|
*/
|
|
@@ -694,6 +747,7 @@ function useFloorMapTransformMetrics(params) {
|
|
|
694
747
|
isFullscreen,
|
|
695
748
|
toggleFullscreen,
|
|
696
749
|
fitBounds,
|
|
750
|
+
focusContentBounds,
|
|
697
751
|
isAtFitBounds,
|
|
698
752
|
notifyTransformed,
|
|
699
753
|
persistCurrentViewport,
|
|
@@ -12,11 +12,15 @@ function useShopFloorPlanSubscription(params) {
|
|
|
12
12
|
onDetailRef.current = onDetail;
|
|
13
13
|
const onLoadErrorRef = (0, react.useRef)(onLoadError);
|
|
14
14
|
onLoadErrorRef.current = onLoadError;
|
|
15
|
+
const ensureByCodeRef = (0, react.useRef)(ensureByCode);
|
|
16
|
+
ensureByCodeRef.current = ensureByCode;
|
|
17
|
+
const unsubscribeQueryRef = (0, react.useRef)(unsubscribeQuery);
|
|
18
|
+
unsubscribeQueryRef.current = unsubscribeQuery;
|
|
15
19
|
(0, react.useEffect)(() => {
|
|
16
20
|
if (!enabled) return;
|
|
17
21
|
let cancelled = false;
|
|
18
22
|
const subId = subscriberId;
|
|
19
|
-
|
|
23
|
+
ensureByCodeRef.current(code, {
|
|
20
24
|
osServer,
|
|
21
25
|
subscriberId: subId,
|
|
22
26
|
callback: (res) => {
|
|
@@ -36,14 +40,13 @@ function useShopFloorPlanSubscription(params) {
|
|
|
36
40
|
});
|
|
37
41
|
return () => {
|
|
38
42
|
cancelled = true;
|
|
39
|
-
|
|
43
|
+
unsubscribeQueryRef.current(subId);
|
|
40
44
|
};
|
|
45
|
+
/** ensureByCode / unsubscribeQuery 走 ref,避免调用方内联函数导致反复退订再订阅 */
|
|
41
46
|
}, [
|
|
42
47
|
enabled,
|
|
43
48
|
code,
|
|
44
49
|
subscriberId,
|
|
45
|
-
ensureByCode,
|
|
46
|
-
unsubscribeQuery,
|
|
47
50
|
osServer
|
|
48
51
|
]);
|
|
49
52
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FloorMapResourcePickerSlotProps, PisellCardPickerCardMeta, PisellCardPickerCategoryConfig, PisellCardPickerCategoryLevelConfig, PisellCardPickerCategoryMode, PisellCardPickerCategoryPath, PisellCardPickerItem, PisellCardPickerMode, parseNestedPathSegments } from "./utils/floorMapResourcePickerTypes.js";
|
|
2
|
+
import { DataSourceFormColumn, FLOOR_MAP_BUILTIN_SHAPE_ELEMENT_KIND, FLOOR_MAP_IMAGE_ELEMENT_KIND, FLOOR_MAP_STAGE_ELEMENT_KIND, FLOOR_MAP_ZONE_ELEMENT_KIND, FloorMapBackgroundType, FloorMapCanvas, FloorMapCanvasNameI18n, FloorMapCanvasUiConfig, FloorMapControlsConfig, FloorMapDataSourceRecordFormContent, FloorMapDataSources, FloorMapEdge, FloorMapEdgeAnchor, FloorMapEdgeStatus, FloorMapElementDataBindingPolicy, FloorMapElementDefaultPresentation, FloorMapElementKindCategory, FloorMapElementKindConfig, FloorMapFullscreenMode, FloorMapGridLayoutConfig, FloorMapItemBase, FloorMapItemShape, FloorMapItemUnit, FloorMapLayerConfig, FloorMapLayoutContextValue, FloorMapLayoutMode, FloorMapMergedItem, FloorMapPanBoundary, FloorMapPanConfig, FloorMapRecordFormRenderContext, FloorMapRenderOptions, FloorMapSceneElement, FloorMapSceneElementDataBinding, FloorMapTextSlot, FloorMapViewConfig, FloorMapViewportOverlayRenderArgs, FloorMapZoomConfig, PisellFloorMapLayoutProps, PisellFloorMapLayoutRef } from "./types.js";
|
|
2
3
|
import { PisellFloorMapLayout } from "./PisellFloorMapLayout.js";
|
|
3
4
|
import { renderFloorMapFallbackPlaceholder } from "./utils/floorMapFallbackRender.js";
|
|
4
5
|
import { isFloorMapBuiltinShapeElementKind, isFloorMapImageElementKind } from "./utils/floorMapElementKindUtils.js";
|
|
@@ -13,6 +14,9 @@ import { sceneElementsToShopLayout, shopLayoutToSceneElements } from "./shopFloo
|
|
|
13
14
|
import { WrapFloorMapOnSaveWithRemotePersistParams, wrapFloorMapOnSaveWithRemotePersist } from "./utils/floorMapRemotePersist.js";
|
|
14
15
|
import { EMPTY_FLOOR_MAP_LAYOUT_CONTEXT, FloorMapLayoutProvider, FloorMapLayoutProviderProps, useFloorMapLayoutContext } from "./context/FloorMapLayoutContext.js";
|
|
15
16
|
import { mergeFloorMapLayoutPropsFromContext } from "./context/mergeFloorMapLayoutContext.js";
|
|
17
|
+
import { FloorMapResourcePickerRecord, floorMapResourcePickerRecordSearchText, getFloorMapCardPickerCategoryConfig, getFloorMapResourcePickerCardMeta } from "./utils/floorMapResourcePickerDisplay.js";
|
|
18
|
+
import { initFloorMapLayoutLocales } from "./utils/floorMapCanvasDisplay.js";
|
|
16
19
|
import { FloorMapImageElement } from "./components/FloorMapImageElement.js";
|
|
17
20
|
import { FloorMapBuiltinShapeElement } from "./components/FloorMapBuiltinShapeElement.js";
|
|
21
|
+
import { FloorMapZoneElement } from "./components/FloorMapZoneElement.js";
|
|
18
22
|
import { FigmaTableCardItem, FigmaTableStatus, getFigmaTableCardFromMerged, getRenderItemByKindRoundTable, getRenderItemByKindTable, renderFigmaStyleRoundTableCard, renderFigmaStyleTableCard } from "./components/FigmaTableCard.js";
|