aldehyde 0.2.494 → 0.2.495
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/lib/controls/icon-selector/icon/phonenode-menu-icon/iconfont.css +63 -63
- package/lib/draw-canvas-edit/components/asset-bar/index.less +35 -35
- package/lib/draw-canvas-edit/components/main-header/index.less +23 -23
- package/lib/layout2/page.d.ts +2 -1
- package/lib/layout2/page.d.ts.map +1 -1
- package/lib/layout2/page.js +19 -8
- package/lib/layout2/page.js.map +1 -1
- package/lib/layout2/type/layout-type.d.ts +1 -0
- package/lib/layout2/type/layout-type.d.ts.map +1 -1
- package/lib/lowcode-components/base-table/index.less +61 -61
- package/lib/lowcode-components/base-text/index.less +19 -19
- package/lib/lowcode-components/data-number/index.less +10 -10
- package/lib/lowcode-components/date-time/index.less +4 -4
- package/lib/lowcode-components/four-angle-glow-border/index.less +49 -49
- package/lib/lowcode-components/lowcode-view/component/font/FontGlobal.css +26 -26
- package/lib/lowcode-components/lowcode-view/component/screen-fit/index.less +13 -13
- package/lib/lowcode-components/text-scroller/index.less +28 -28
- package/lib/module/ltmpl-table.d.ts +7 -0
- package/lib/module/ltmpl-table.d.ts.map +1 -1
- package/lib/module/ltmpl-table.js +12 -16
- package/lib/module/ltmpl-table.js.map +1 -1
- package/lib/routable/dtmpl-route.d.ts.map +1 -1
- package/lib/routable/dtmpl-route.js +8 -2
- package/lib/routable/dtmpl-route.js.map +1 -1
- package/lib/routable/import-route.d.ts.map +1 -1
- package/lib/routable/import-route.js +9 -1
- package/lib/routable/import-route.js.map +1 -1
- package/lib/routable/ltmpl-route.d.ts.map +1 -1
- package/lib/routable/ltmpl-route.js +13 -6
- package/lib/routable/ltmpl-route.js.map +1 -1
- package/lib/routable/splitview-ltmpl-route.d.ts.map +1 -1
- package/lib/routable/splitview-ltmpl-route.js +11 -10
- package/lib/routable/splitview-ltmpl-route.js.map +1 -1
- package/lib/routable/ttmpl-route.d.ts.map +1 -1
- package/lib/routable/ttmpl-route.js +9 -2
- package/lib/routable/ttmpl-route.js.map +1 -1
- package/lib/table/act-table.d.ts +1 -0
- package/lib/table/act-table.d.ts.map +1 -1
- package/lib/table/act-table.js +31 -9
- package/lib/table/act-table.js.map +1 -1
- package/lib/table/page-chart.js +1 -1
- package/lib/table/page-chart.js.map +1 -1
- package/lib/table/row-table.d.ts +6 -0
- package/lib/table/row-table.d.ts.map +1 -1
- package/lib/table/row-table.js +21 -6
- package/lib/table/row-table.js.map +1 -1
- package/lib/tmpl/interface.d.ts +1 -0
- package/lib/tmpl/interface.d.ts.map +1 -1
- package/lib/tree/act-tree.d.ts +1 -0
- package/lib/tree/act-tree.d.ts.map +1 -1
- package/lib/tree/act-tree.js +6 -7
- package/lib/tree/act-tree.js.map +1 -1
- package/lib/tree/tree-utils.d.ts +1 -1
- package/lib/tree/tree-utils.d.ts.map +1 -1
- package/lib/tree/tree-utils.js +4 -4
- package/lib/tree/tree-utils.js.map +1 -1
- package/lib/units/index.d.ts +4 -0
- package/lib/units/index.d.ts.map +1 -1
- package/lib/units/index.js +10 -3
- package/lib/units/index.js.map +1 -1
- package/package.json +1 -1
- package/src/aldehyde/controls/icon-selector/icon/phonenode-menu-icon/iconfont.css +63 -63
- package/src/aldehyde/controls/icon-selector/icon/phonenode-menu-icon/iconfont.json +93 -93
- package/src/aldehyde/draw-canvas-edit/components/asset-bar/index.less +35 -35
- package/src/aldehyde/draw-canvas-edit/components/asset-bar/index.tsx +110 -110
- package/src/aldehyde/draw-canvas-edit/components/main-header/index.less +23 -23
- package/src/aldehyde/draw-canvas-edit/components/main-header/index.tsx +263 -263
- package/src/aldehyde/draw-canvas-edit/components/render/draws/index.ts +7 -7
- package/src/aldehyde/draw-canvas-edit/components/render/graphs/base-graph.ts +241 -241
- package/src/aldehyde/draw-canvas-edit/components/render/graphs/circle.ts +699 -699
- package/src/aldehyde/draw-canvas-edit/components/render/graphs/curve.ts +500 -500
- package/src/aldehyde/draw-canvas-edit/components/render/graphs/index.ts +5 -5
- package/src/aldehyde/draw-canvas-edit/components/render/graphs/line.ts +493 -493
- package/src/aldehyde/draw-canvas-edit/components/render/graphs/rect.ts +680 -680
- package/src/aldehyde/draw-canvas-edit/components/render/handlers/drag-handlers.ts +68 -68
- package/src/aldehyde/draw-canvas-edit/components/render/handlers/graph-handlers.ts +113 -113
- package/src/aldehyde/draw-canvas-edit/components/render/handlers/index.ts +9 -9
- package/src/aldehyde/draw-canvas-edit/components/render/handlers/key-move-handlers.ts +49 -49
- package/src/aldehyde/draw-canvas-edit/components/render/handlers/link-handlers.ts +45 -45
- package/src/aldehyde/draw-canvas-edit/components/render/handlers/shutcut-handlers.ts +45 -45
- package/src/aldehyde/draw-canvas-edit/components/render/handlers/text-handlers.ts +81 -81
- package/src/aldehyde/draw-canvas-edit/components/render/handlers/zoom-handlers.ts +59 -59
- package/src/aldehyde/draw-canvas-edit/components/render/tools/align-tool.ts +89 -89
- package/src/aldehyde/draw-canvas-edit/components/render/tools/asset-tool.ts +154 -154
- package/src/aldehyde/draw-canvas-edit/components/render/tools/link-tool.ts +222 -222
- package/src/aldehyde/draw-canvas-edit/components/render/tools/z-index-tool.ts +224 -224
- package/src/aldehyde/draw-canvas-edit/components/render/utils/a-star.ts +116 -116
- package/src/aldehyde/draw-canvas-edit/components/render/utils/bezier-scene-func.ts +72 -72
- package/src/aldehyde/draw-canvas-edit/components/setting-form/imag-upload.tsx +119 -119
- package/src/aldehyde/layout2/page.tsx +17 -9
- package/src/aldehyde/layout2/type/layout-type.ts +1 -0
- package/src/aldehyde/layout4/imgs/user.svg +26 -26
- package/src/aldehyde/lowcode-components/base-color-block/index.tsx +31 -31
- package/src/aldehyde/lowcode-components/base-table/index.less +61 -61
- package/src/aldehyde/lowcode-components/base-text/index.less +19 -19
- package/src/aldehyde/lowcode-components/data-number/index.less +10 -10
- package/src/aldehyde/lowcode-components/date-time/index.less +4 -4
- package/src/aldehyde/lowcode-components/date-time/index.tsx +64 -64
- package/src/aldehyde/lowcode-components/four-angle-glow-border/index.less +49 -49
- package/src/aldehyde/lowcode-components/four-angle-glow-border/index.tsx +53 -53
- package/src/aldehyde/lowcode-components/lowcode-view/component/abstract-controller.ts +64 -64
- package/src/aldehyde/lowcode-components/lowcode-view/component/abstract-definition.ts +77 -77
- package/src/aldehyde/lowcode-components/lowcode-view/component/abstract-designer-loader.ts +36 -36
- package/src/aldehyde/lowcode-components/lowcode-view/component/component-container.tsx +91 -91
- package/src/aldehyde/lowcode-components/lowcode-view/component/font/FontGlobal.css +26 -26
- package/src/aldehyde/lowcode-components/lowcode-view/component/group-layer/controller.ts +36 -36
- package/src/aldehyde/lowcode-components/lowcode-view/component/group-layer/definition.ts +53 -53
- package/src/aldehyde/lowcode-components/lowcode-view/component/group-layer/index.tsx +15 -15
- package/src/aldehyde/lowcode-components/lowcode-view/component/layer-builder.tsx +98 -98
- package/src/aldehyde/lowcode-components/lowcode-view/component/screen-fit/index.less +13 -13
- package/src/aldehyde/lowcode-components/lowcode-view/component/screen-fit/index.tsx +121 -121
- package/src/aldehyde/lowcode-components/placeholder-component/index.tsx +81 -81
- package/src/aldehyde/lowcode-components/text-scroller/index.less +28 -28
- package/src/aldehyde/lowcode-components/text-scroller/index.tsx +173 -173
- package/src/aldehyde/module/ltmpl-table.tsx +14 -15
- package/src/aldehyde/routable/dtmpl-route.tsx +14 -8
- package/src/aldehyde/routable/import-route.tsx +12 -5
- package/src/aldehyde/routable/ltmpl-route.tsx +14 -9
- package/src/aldehyde/routable/splitview-ltmpl-route.tsx +11 -8
- package/src/aldehyde/routable/ttmpl-route.tsx +13 -8
- package/src/aldehyde/table/act-table.tsx +28 -9
- package/src/aldehyde/table/page-chart.tsx +1 -1
- package/src/aldehyde/table/row-table.tsx +29 -6
- package/src/aldehyde/tmpl/interface.tsx +1 -0
- package/src/aldehyde/tree/act-tree.tsx +8 -6
- package/src/aldehyde/tree/tree-utils.tsx +4 -4
- package/src/aldehyde/units/index.tsx +11 -3
|
@@ -1,264 +1,264 @@
|
|
|
1
|
-
import React, { useState, useEffect, useCallback, useMemo } from 'react';
|
|
2
|
-
import { Dropdown, Modal, Space, Button, Divider, Tooltip, message } from 'antd';
|
|
3
|
-
import { ImportOutlined, ExportOutlined, SaveOutlined, QuestionCircleOutlined, MergeCellsOutlined, NumberOutlined, SettingOutlined } from '@ant-design/icons';
|
|
4
|
-
import { gzipSync, strToU8 } from 'fflate';
|
|
5
|
-
import { uint8ArrayToHex } from 'uint8array-extras';
|
|
6
|
-
import HcserviceV3 from "../../../tmpl/hcservice-v3";
|
|
7
|
-
import IconFont from "../../../icon/aliIcon";
|
|
8
|
-
import { Render } from '../render';
|
|
9
|
-
import { GraphType, LinkType, AlignType } from '../render/types';
|
|
10
|
-
import * as Draws from '../render/draws';
|
|
11
|
-
import UploadReadExcel from "../../../controls/upload-read-excel";
|
|
12
|
-
import './index.less';
|
|
13
|
-
|
|
14
|
-
// 布局类型
|
|
15
|
-
const alignTypes = [
|
|
16
|
-
{ label: '垂直居中', value: 'Middle', icon: "icon-middle-L" },
|
|
17
|
-
{ label: '左对齐', value: 'Left', icon: "icon-left-L" },
|
|
18
|
-
{ label: '右对齐', value: 'Right', icon: "icon-right-L" },
|
|
19
|
-
{ label: '水平居中', value: 'Center', icon: "icon-center-L" },
|
|
20
|
-
{ label: '上对齐', value: 'Top', icon: "icon-top-L" },
|
|
21
|
-
{ label: '下对齐', value: 'Bottom', icon: "icon-bottom-L" }
|
|
22
|
-
];
|
|
23
|
-
|
|
24
|
-
// 连线类型
|
|
25
|
-
const lineTypes = [
|
|
26
|
-
{ label: '折线', value: 'curve', icon: "icon-zhexian" },
|
|
27
|
-
{ label: '贝塞尔曲线', value: 'bezier', icon: "icon-bezier" },
|
|
28
|
-
{ label: '自动', value: 'auto', icon: "icon-zhexian-auto" },
|
|
29
|
-
];
|
|
30
|
-
|
|
31
|
-
// 图形类型
|
|
32
|
-
const graphTypes = [
|
|
33
|
-
{ label: '折线', value: 'Curve', icon: "icon-zhexian" },
|
|
34
|
-
{ label: '贝塞尔曲线', value: 'Bezier', icon: "icon-bezier" },
|
|
35
|
-
{ label: '矩形', value: 'Rect', icon: 'icon-rect' },
|
|
36
|
-
{ label: '圆', value: 'Circle', icon: 'icon-circle' },
|
|
37
|
-
];
|
|
38
|
-
|
|
39
|
-
interface MainHeaderProps {
|
|
40
|
-
render: Render | null;
|
|
41
|
-
graphType?: GraphType; // 图类型
|
|
42
|
-
texting?: boolean; // 添加文本状态
|
|
43
|
-
showGrid?: boolean; // 显示网格
|
|
44
|
-
showAttract?: boolean; // 显示磁吸
|
|
45
|
-
onGraphTypeChange: (type: GraphType | undefined) => void; // 更新图类型
|
|
46
|
-
onTexting: (texting: boolean) => void;
|
|
47
|
-
setShowGrid?: (show: boolean) => void;
|
|
48
|
-
setShowAttract?: (show: boolean) => void;
|
|
49
|
-
recordCode: string;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const MainHeader = (props: MainHeaderProps) => {
|
|
53
|
-
const { render, graphType, onGraphTypeChange, onTexting, texting, recordCode, showGrid, setShowGrid, showAttract, setShowAttract } = props;
|
|
54
|
-
const [scale, setScale] = useState<number>(100); // 缩放
|
|
55
|
-
const [history, setHistory] = useState<string[]>([]); // 历史记录
|
|
56
|
-
const [historyIndex, setHistoryIndex] = useState(-1); // 当前历史记录标签
|
|
57
|
-
const [selection, setSelection] = useState<unknown[]>([]); // 选中组件
|
|
58
|
-
const [currentLinkType, setCurrentLinkType] = useState<LinkType>("curve"); // 连接线类型
|
|
59
|
-
const [showShortCut, setShowShortCut] = useState<boolean>(false); // 快捷键显示
|
|
60
|
-
const [loading, setLoading] = useState<boolean>(false);
|
|
61
|
-
|
|
62
|
-
// 文件导入
|
|
63
|
-
const handleRestore = useCallback(() => {
|
|
64
|
-
if (!render) return;
|
|
65
|
-
const input = document.createElement('input');
|
|
66
|
-
input.type = 'file';
|
|
67
|
-
input.accept = '.json';
|
|
68
|
-
input.onchange = () => {
|
|
69
|
-
const file = input.files?.[0];
|
|
70
|
-
if (file) {
|
|
71
|
-
const reader = new FileReader();
|
|
72
|
-
reader.onload = async () => {
|
|
73
|
-
await render.importExportTool.restore(reader.result as string);
|
|
74
|
-
render.positionTool.positionFit();
|
|
75
|
-
}
|
|
76
|
-
reader.readAsText(file);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
input.click();
|
|
80
|
-
}, [render]);
|
|
81
|
-
|
|
82
|
-
// 批量设置组件属性
|
|
83
|
-
const handleBatchSetNodeConfig = useCallback((data: { [key: string]: any }[]) => {
|
|
84
|
-
if (!render || !data?.length) return;
|
|
85
|
-
const allAssets = render.getAllAssets();
|
|
86
|
-
data.forEach((item) => {
|
|
87
|
-
let nodeId, setting;
|
|
88
|
-
switch (item["组件类型"]) {
|
|
89
|
-
case "workstation":
|
|
90
|
-
const order = item["序号"];
|
|
91
|
-
const workstationNumber = item["工位编号"];
|
|
92
|
-
nodeId = allAssets.find((asset) => asset.componentType === "workstation" && asset.settings.order === order)?.id;
|
|
93
|
-
setting = { workstationNumber };
|
|
94
|
-
break;
|
|
95
|
-
default:
|
|
96
|
-
break;
|
|
97
|
-
}
|
|
98
|
-
if (nodeId) {
|
|
99
|
-
render.updateAssetById(nodeId, setting);
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
message.success("设置成功");
|
|
103
|
-
}, [render]);
|
|
104
|
-
|
|
105
|
-
// 保存
|
|
106
|
-
const handleSave = async () => {
|
|
107
|
-
if (!recordCode) {
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
|
-
setLoading(true);
|
|
111
|
-
const data = render.importExportTool.save();
|
|
112
|
-
// 1. 将普通字符串转换为 Uint8Array
|
|
113
|
-
const dataBuffer = strToU8(data);
|
|
114
|
-
// 2. 压缩为 ByteArray
|
|
115
|
-
const content = gzipSync(dataBuffer, { level: 9 });
|
|
116
|
-
// 3. 将 Uint8Array 转为 16进制字符串
|
|
117
|
-
const hexString = uint8ArrayToHex(content);
|
|
118
|
-
await HcserviceV3.postDiagram2DConfig(recordCode, hexString);
|
|
119
|
-
setLoading(false);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// 数据导出
|
|
123
|
-
const handleExport = useCallback((type: 'json' | 'svg' | 'asset' | 'png' | 'assetPng', action?: "save" | "download") => {
|
|
124
|
-
if (!render) return;
|
|
125
|
-
switch (type) {
|
|
126
|
-
case 'json':
|
|
127
|
-
if (action === "save") {
|
|
128
|
-
handleSave();
|
|
129
|
-
} else {
|
|
130
|
-
download("data.json", render.importExportTool.save());
|
|
131
|
-
}
|
|
132
|
-
return;
|
|
133
|
-
case 'asset':
|
|
134
|
-
download("asset.json", render.importExportTool.getAsset());
|
|
135
|
-
return;
|
|
136
|
-
case 'png':
|
|
137
|
-
download('image.png', render.importExportTool.getAssetImage(2));
|
|
138
|
-
return;
|
|
139
|
-
case 'assetPng':
|
|
140
|
-
download('image.png', render.importExportTool.getAssetImage());
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
}, [render]);
|
|
144
|
-
|
|
145
|
-
// 下载辅助函数
|
|
146
|
-
const download = (name: string, content: string) => {
|
|
147
|
-
const a = document.createElement('a');
|
|
148
|
-
a.download = name;
|
|
149
|
-
a.href = content.startsWith('blob:') ? content : URL.createObjectURL(new Blob([content]));
|
|
150
|
-
a.click();
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// 工具操作
|
|
154
|
-
const handleAlign = useCallback((type: AlignType) => {
|
|
155
|
-
render?.alignTool.align(type);
|
|
156
|
-
}, [render])
|
|
157
|
-
|
|
158
|
-
// 更改组件连接线类型
|
|
159
|
-
const handleLinkType = useCallback((type: LinkType) => {
|
|
160
|
-
(render?.draws[Draws.LinkDraw.NAME] as unknown as { changeLinkType: (t: LinkType) => void })?.changeLinkType(type);
|
|
161
|
-
}, [render])
|
|
162
|
-
|
|
163
|
-
// 重置缩放
|
|
164
|
-
const handleScale = useCallback((action: 'fit' | 'reset' | 'position') => {
|
|
165
|
-
const tool = render?.positionTool;
|
|
166
|
-
if (!tool) return;
|
|
167
|
-
action === 'fit' ? tool.positionFit() : action === 'reset' ? tool.positionZoomReset() : tool.positionReset();
|
|
168
|
-
}, [render])
|
|
169
|
-
|
|
170
|
-
// 更改图类型
|
|
171
|
-
const handleGraph = (type: GraphType) => onGraphTypeChange(graphType === type ? undefined : type);
|
|
172
|
-
|
|
173
|
-
// 绑定事件
|
|
174
|
-
useEffect(() => {
|
|
175
|
-
if (!render) return;
|
|
176
|
-
render.on('selection-change', setSelection);
|
|
177
|
-
render.on('history-change', ({ records, index }: { records: string[]; index: number }) => {
|
|
178
|
-
setHistory(records);
|
|
179
|
-
setHistoryIndex(index);
|
|
180
|
-
});
|
|
181
|
-
render.on('link-type-change', setCurrentLinkType);
|
|
182
|
-
render.on('scale-change', (v: number) => setScale(v * 100));
|
|
183
|
-
render.on('loading', setLoading);
|
|
184
|
-
}, [render]);
|
|
185
|
-
|
|
186
|
-
// 是否选中多个组件
|
|
187
|
-
const isSelects = useMemo(() => selection.length <= 1, [selection]);
|
|
188
|
-
|
|
189
|
-
// 缩放菜单选项
|
|
190
|
-
const scaleMenu = [
|
|
191
|
-
{ key: "fit", label: <a onClick={() => handleScale('fit')}>自适应</a> },
|
|
192
|
-
{ key: "reset", label: <a onClick={() => handleScale('reset')}>重置位置及缩放</a> },
|
|
193
|
-
{ key: "position", label: <a onClick={() => handleScale('position')}>仅重置位置</a> }
|
|
194
|
-
];
|
|
195
|
-
|
|
196
|
-
return (
|
|
197
|
-
<div className="main-header">
|
|
198
|
-
<Space size={4} separator={<Divider vertical styles={{ root: { margin: "0 4px" } }} />}>
|
|
199
|
-
<Dropdown menu={{ items: scaleMenu }}>
|
|
200
|
-
<span style={{ cursor: "pointer" }}>{`${scale.toFixed(0)}%`}</span>
|
|
201
|
-
</Dropdown>
|
|
202
|
-
<Tooltip title="撤销">
|
|
203
|
-
<Button type="text" onClick={() => render?.prevHistory()} disabled={historyIndex <= 0} >↶</Button>
|
|
204
|
-
</Tooltip>
|
|
205
|
-
<Tooltip title="恢复">
|
|
206
|
-
<Button type="text" onClick={() => render?.nextHistory()} disabled={historyIndex >= history.length - 1} >↷</Button>
|
|
207
|
-
</Tooltip>
|
|
208
|
-
{alignTypes.map(type => (
|
|
209
|
-
<Tooltip title={type.label}>
|
|
210
|
-
<Button type="text" key={type.value} onClick={() => handleAlign(type.value as AlignType)} disabled={isSelects} ><IconFont type={type.icon} /></Button>
|
|
211
|
-
</Tooltip>
|
|
212
|
-
))}
|
|
213
|
-
{lineTypes.map(type => (
|
|
214
|
-
<Tooltip title={`连接线:${type.label}`}>
|
|
215
|
-
<Button type="text" key={type.value} onClick={() => handleLinkType(type.value as LinkType)} disabled={currentLinkType === type.value}><IconFont type={type.icon} /></Button>
|
|
216
|
-
</Tooltip>
|
|
217
|
-
))}
|
|
218
|
-
{graphTypes.map(type => (
|
|
219
|
-
<Tooltip title={`画${type.label}`}>
|
|
220
|
-
<Button type="text" key={type.value} onClick={() => handleGraph(type.value as GraphType)} className={graphType === type.value ? 'active' : ''} ><IconFont type={type.icon} /></Button>
|
|
221
|
-
</Tooltip>
|
|
222
|
-
))}
|
|
223
|
-
<Tooltip title="插入文字">
|
|
224
|
-
<Button type="text" onClick={() => onTexting(true)} className={texting ? "active" : ""} ><IconFont type="icon-wenben" /></Button>
|
|
225
|
-
</Tooltip>
|
|
226
|
-
<Tooltip title="网格">
|
|
227
|
-
<Button type="text" onClick={() => setShowGrid(!showGrid)} className={showGrid ? "active" : ""} ><NumberOutlined /></Button>
|
|
228
|
-
</Tooltip>
|
|
229
|
-
<Tooltip title="磁吸">
|
|
230
|
-
<Button type="text" onClick={() => setShowAttract(!showAttract)} className={showAttract ? "active" : ""} ><MergeCellsOutlined /></Button>
|
|
231
|
-
</Tooltip>
|
|
232
|
-
</Space>
|
|
233
|
-
<Space size={4} separator={<Divider vertical styles={{ root: { margin: "0 4px" } }} />}>
|
|
234
|
-
<Tooltip title="快捷键">
|
|
235
|
-
<Button type="text" onClick={() => setShowShortCut(true)} ><QuestionCircleOutlined /></Button>
|
|
236
|
-
</Tooltip>
|
|
237
|
-
<Tooltip title="组件属性批量配置">
|
|
238
|
-
<>
|
|
239
|
-
<UploadReadExcel onChangeData={handleBatchSetNodeConfig} >
|
|
240
|
-
<Button type="text" ><SettingOutlined /></Button>
|
|
241
|
-
</UploadReadExcel>
|
|
242
|
-
</>
|
|
243
|
-
</Tooltip>
|
|
244
|
-
<Tooltip title="导入">
|
|
245
|
-
<Button type="text" onClick={handleRestore} ><ImportOutlined /></Button>
|
|
246
|
-
</Tooltip>
|
|
247
|
-
<Tooltip title="导出">
|
|
248
|
-
<Button type="text" onClick={() => handleExport("json")} ><ExportOutlined /></Button>
|
|
249
|
-
</Tooltip>
|
|
250
|
-
<Tooltip title="保存">
|
|
251
|
-
<Button loading={loading} type="text" onClick={() => handleExport("json", "save")} ><SaveOutlined /></Button>
|
|
252
|
-
</Tooltip>
|
|
253
|
-
</Space>
|
|
254
|
-
{showShortCut &&
|
|
255
|
-
<Modal title="快捷键" width={600} footer={null} open={showShortCut} onCancel={() => setShowShortCut(false)}>
|
|
256
|
-
<p>1、复制、粘贴、多选、全选、删除、上一步、下一步等快捷键与一般文档编辑器类似;</p>
|
|
257
|
-
<p>2、放大缩小,【Win】鼠标上滚动下滚动,【Mac】触控板双指放大、缩小;</p>
|
|
258
|
-
<p>3、画布拖动,在空白处,【Win】右键按下移动,【Mac】control + 触控板三指移动;</p>
|
|
259
|
-
</Modal>}
|
|
260
|
-
</div >
|
|
261
|
-
)
|
|
262
|
-
}
|
|
263
|
-
|
|
1
|
+
import React, { useState, useEffect, useCallback, useMemo } from 'react';
|
|
2
|
+
import { Dropdown, Modal, Space, Button, Divider, Tooltip, message } from 'antd';
|
|
3
|
+
import { ImportOutlined, ExportOutlined, SaveOutlined, QuestionCircleOutlined, MergeCellsOutlined, NumberOutlined, SettingOutlined } from '@ant-design/icons';
|
|
4
|
+
import { gzipSync, strToU8 } from 'fflate';
|
|
5
|
+
import { uint8ArrayToHex } from 'uint8array-extras';
|
|
6
|
+
import HcserviceV3 from "../../../tmpl/hcservice-v3";
|
|
7
|
+
import IconFont from "../../../icon/aliIcon";
|
|
8
|
+
import { Render } from '../render';
|
|
9
|
+
import { GraphType, LinkType, AlignType } from '../render/types';
|
|
10
|
+
import * as Draws from '../render/draws';
|
|
11
|
+
import UploadReadExcel from "../../../controls/upload-read-excel";
|
|
12
|
+
import './index.less';
|
|
13
|
+
|
|
14
|
+
// 布局类型
|
|
15
|
+
const alignTypes = [
|
|
16
|
+
{ label: '垂直居中', value: 'Middle', icon: "icon-middle-L" },
|
|
17
|
+
{ label: '左对齐', value: 'Left', icon: "icon-left-L" },
|
|
18
|
+
{ label: '右对齐', value: 'Right', icon: "icon-right-L" },
|
|
19
|
+
{ label: '水平居中', value: 'Center', icon: "icon-center-L" },
|
|
20
|
+
{ label: '上对齐', value: 'Top', icon: "icon-top-L" },
|
|
21
|
+
{ label: '下对齐', value: 'Bottom', icon: "icon-bottom-L" }
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
// 连线类型
|
|
25
|
+
const lineTypes = [
|
|
26
|
+
{ label: '折线', value: 'curve', icon: "icon-zhexian" },
|
|
27
|
+
{ label: '贝塞尔曲线', value: 'bezier', icon: "icon-bezier" },
|
|
28
|
+
{ label: '自动', value: 'auto', icon: "icon-zhexian-auto" },
|
|
29
|
+
];
|
|
30
|
+
|
|
31
|
+
// 图形类型
|
|
32
|
+
const graphTypes = [
|
|
33
|
+
{ label: '折线', value: 'Curve', icon: "icon-zhexian" },
|
|
34
|
+
{ label: '贝塞尔曲线', value: 'Bezier', icon: "icon-bezier" },
|
|
35
|
+
{ label: '矩形', value: 'Rect', icon: 'icon-rect' },
|
|
36
|
+
{ label: '圆', value: 'Circle', icon: 'icon-circle' },
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
interface MainHeaderProps {
|
|
40
|
+
render: Render | null;
|
|
41
|
+
graphType?: GraphType; // 图类型
|
|
42
|
+
texting?: boolean; // 添加文本状态
|
|
43
|
+
showGrid?: boolean; // 显示网格
|
|
44
|
+
showAttract?: boolean; // 显示磁吸
|
|
45
|
+
onGraphTypeChange: (type: GraphType | undefined) => void; // 更新图类型
|
|
46
|
+
onTexting: (texting: boolean) => void;
|
|
47
|
+
setShowGrid?: (show: boolean) => void;
|
|
48
|
+
setShowAttract?: (show: boolean) => void;
|
|
49
|
+
recordCode: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const MainHeader = (props: MainHeaderProps) => {
|
|
53
|
+
const { render, graphType, onGraphTypeChange, onTexting, texting, recordCode, showGrid, setShowGrid, showAttract, setShowAttract } = props;
|
|
54
|
+
const [scale, setScale] = useState<number>(100); // 缩放
|
|
55
|
+
const [history, setHistory] = useState<string[]>([]); // 历史记录
|
|
56
|
+
const [historyIndex, setHistoryIndex] = useState(-1); // 当前历史记录标签
|
|
57
|
+
const [selection, setSelection] = useState<unknown[]>([]); // 选中组件
|
|
58
|
+
const [currentLinkType, setCurrentLinkType] = useState<LinkType>("curve"); // 连接线类型
|
|
59
|
+
const [showShortCut, setShowShortCut] = useState<boolean>(false); // 快捷键显示
|
|
60
|
+
const [loading, setLoading] = useState<boolean>(false);
|
|
61
|
+
|
|
62
|
+
// 文件导入
|
|
63
|
+
const handleRestore = useCallback(() => {
|
|
64
|
+
if (!render) return;
|
|
65
|
+
const input = document.createElement('input');
|
|
66
|
+
input.type = 'file';
|
|
67
|
+
input.accept = '.json';
|
|
68
|
+
input.onchange = () => {
|
|
69
|
+
const file = input.files?.[0];
|
|
70
|
+
if (file) {
|
|
71
|
+
const reader = new FileReader();
|
|
72
|
+
reader.onload = async () => {
|
|
73
|
+
await render.importExportTool.restore(reader.result as string);
|
|
74
|
+
render.positionTool.positionFit();
|
|
75
|
+
}
|
|
76
|
+
reader.readAsText(file);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
input.click();
|
|
80
|
+
}, [render]);
|
|
81
|
+
|
|
82
|
+
// 批量设置组件属性
|
|
83
|
+
const handleBatchSetNodeConfig = useCallback((data: { [key: string]: any }[]) => {
|
|
84
|
+
if (!render || !data?.length) return;
|
|
85
|
+
const allAssets = render.getAllAssets();
|
|
86
|
+
data.forEach((item) => {
|
|
87
|
+
let nodeId, setting;
|
|
88
|
+
switch (item["组件类型"]) {
|
|
89
|
+
case "workstation":
|
|
90
|
+
const order = item["序号"];
|
|
91
|
+
const workstationNumber = item["工位编号"];
|
|
92
|
+
nodeId = allAssets.find((asset) => asset.componentType === "workstation" && asset.settings.order === order)?.id;
|
|
93
|
+
setting = { workstationNumber };
|
|
94
|
+
break;
|
|
95
|
+
default:
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
if (nodeId) {
|
|
99
|
+
render.updateAssetById(nodeId, setting);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
message.success("设置成功");
|
|
103
|
+
}, [render]);
|
|
104
|
+
|
|
105
|
+
// 保存
|
|
106
|
+
const handleSave = async () => {
|
|
107
|
+
if (!recordCode) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
setLoading(true);
|
|
111
|
+
const data = render.importExportTool.save();
|
|
112
|
+
// 1. 将普通字符串转换为 Uint8Array
|
|
113
|
+
const dataBuffer = strToU8(data);
|
|
114
|
+
// 2. 压缩为 ByteArray
|
|
115
|
+
const content = gzipSync(dataBuffer, { level: 9 });
|
|
116
|
+
// 3. 将 Uint8Array 转为 16进制字符串
|
|
117
|
+
const hexString = uint8ArrayToHex(content);
|
|
118
|
+
await HcserviceV3.postDiagram2DConfig(recordCode, hexString);
|
|
119
|
+
setLoading(false);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// 数据导出
|
|
123
|
+
const handleExport = useCallback((type: 'json' | 'svg' | 'asset' | 'png' | 'assetPng', action?: "save" | "download") => {
|
|
124
|
+
if (!render) return;
|
|
125
|
+
switch (type) {
|
|
126
|
+
case 'json':
|
|
127
|
+
if (action === "save") {
|
|
128
|
+
handleSave();
|
|
129
|
+
} else {
|
|
130
|
+
download("data.json", render.importExportTool.save());
|
|
131
|
+
}
|
|
132
|
+
return;
|
|
133
|
+
case 'asset':
|
|
134
|
+
download("asset.json", render.importExportTool.getAsset());
|
|
135
|
+
return;
|
|
136
|
+
case 'png':
|
|
137
|
+
download('image.png', render.importExportTool.getAssetImage(2));
|
|
138
|
+
return;
|
|
139
|
+
case 'assetPng':
|
|
140
|
+
download('image.png', render.importExportTool.getAssetImage());
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
}, [render]);
|
|
144
|
+
|
|
145
|
+
// 下载辅助函数
|
|
146
|
+
const download = (name: string, content: string) => {
|
|
147
|
+
const a = document.createElement('a');
|
|
148
|
+
a.download = name;
|
|
149
|
+
a.href = content.startsWith('blob:') ? content : URL.createObjectURL(new Blob([content]));
|
|
150
|
+
a.click();
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// 工具操作
|
|
154
|
+
const handleAlign = useCallback((type: AlignType) => {
|
|
155
|
+
render?.alignTool.align(type);
|
|
156
|
+
}, [render])
|
|
157
|
+
|
|
158
|
+
// 更改组件连接线类型
|
|
159
|
+
const handleLinkType = useCallback((type: LinkType) => {
|
|
160
|
+
(render?.draws[Draws.LinkDraw.NAME] as unknown as { changeLinkType: (t: LinkType) => void })?.changeLinkType(type);
|
|
161
|
+
}, [render])
|
|
162
|
+
|
|
163
|
+
// 重置缩放
|
|
164
|
+
const handleScale = useCallback((action: 'fit' | 'reset' | 'position') => {
|
|
165
|
+
const tool = render?.positionTool;
|
|
166
|
+
if (!tool) return;
|
|
167
|
+
action === 'fit' ? tool.positionFit() : action === 'reset' ? tool.positionZoomReset() : tool.positionReset();
|
|
168
|
+
}, [render])
|
|
169
|
+
|
|
170
|
+
// 更改图类型
|
|
171
|
+
const handleGraph = (type: GraphType) => onGraphTypeChange(graphType === type ? undefined : type);
|
|
172
|
+
|
|
173
|
+
// 绑定事件
|
|
174
|
+
useEffect(() => {
|
|
175
|
+
if (!render) return;
|
|
176
|
+
render.on('selection-change', setSelection);
|
|
177
|
+
render.on('history-change', ({ records, index }: { records: string[]; index: number }) => {
|
|
178
|
+
setHistory(records);
|
|
179
|
+
setHistoryIndex(index);
|
|
180
|
+
});
|
|
181
|
+
render.on('link-type-change', setCurrentLinkType);
|
|
182
|
+
render.on('scale-change', (v: number) => setScale(v * 100));
|
|
183
|
+
render.on('loading', setLoading);
|
|
184
|
+
}, [render]);
|
|
185
|
+
|
|
186
|
+
// 是否选中多个组件
|
|
187
|
+
const isSelects = useMemo(() => selection.length <= 1, [selection]);
|
|
188
|
+
|
|
189
|
+
// 缩放菜单选项
|
|
190
|
+
const scaleMenu = [
|
|
191
|
+
{ key: "fit", label: <a onClick={() => handleScale('fit')}>自适应</a> },
|
|
192
|
+
{ key: "reset", label: <a onClick={() => handleScale('reset')}>重置位置及缩放</a> },
|
|
193
|
+
{ key: "position", label: <a onClick={() => handleScale('position')}>仅重置位置</a> }
|
|
194
|
+
];
|
|
195
|
+
|
|
196
|
+
return (
|
|
197
|
+
<div className="main-header">
|
|
198
|
+
<Space size={4} separator={<Divider vertical styles={{ root: { margin: "0 4px" } }} />}>
|
|
199
|
+
<Dropdown menu={{ items: scaleMenu }}>
|
|
200
|
+
<span style={{ cursor: "pointer" }}>{`${scale.toFixed(0)}%`}</span>
|
|
201
|
+
</Dropdown>
|
|
202
|
+
<Tooltip title="撤销">
|
|
203
|
+
<Button type="text" onClick={() => render?.prevHistory()} disabled={historyIndex <= 0} >↶</Button>
|
|
204
|
+
</Tooltip>
|
|
205
|
+
<Tooltip title="恢复">
|
|
206
|
+
<Button type="text" onClick={() => render?.nextHistory()} disabled={historyIndex >= history.length - 1} >↷</Button>
|
|
207
|
+
</Tooltip>
|
|
208
|
+
{alignTypes.map(type => (
|
|
209
|
+
<Tooltip title={type.label}>
|
|
210
|
+
<Button type="text" key={type.value} onClick={() => handleAlign(type.value as AlignType)} disabled={isSelects} ><IconFont type={type.icon} /></Button>
|
|
211
|
+
</Tooltip>
|
|
212
|
+
))}
|
|
213
|
+
{lineTypes.map(type => (
|
|
214
|
+
<Tooltip title={`连接线:${type.label}`}>
|
|
215
|
+
<Button type="text" key={type.value} onClick={() => handleLinkType(type.value as LinkType)} disabled={currentLinkType === type.value}><IconFont type={type.icon} /></Button>
|
|
216
|
+
</Tooltip>
|
|
217
|
+
))}
|
|
218
|
+
{graphTypes.map(type => (
|
|
219
|
+
<Tooltip title={`画${type.label}`}>
|
|
220
|
+
<Button type="text" key={type.value} onClick={() => handleGraph(type.value as GraphType)} className={graphType === type.value ? 'active' : ''} ><IconFont type={type.icon} /></Button>
|
|
221
|
+
</Tooltip>
|
|
222
|
+
))}
|
|
223
|
+
<Tooltip title="插入文字">
|
|
224
|
+
<Button type="text" onClick={() => onTexting(true)} className={texting ? "active" : ""} ><IconFont type="icon-wenben" /></Button>
|
|
225
|
+
</Tooltip>
|
|
226
|
+
<Tooltip title="网格">
|
|
227
|
+
<Button type="text" onClick={() => setShowGrid(!showGrid)} className={showGrid ? "active" : ""} ><NumberOutlined /></Button>
|
|
228
|
+
</Tooltip>
|
|
229
|
+
<Tooltip title="磁吸">
|
|
230
|
+
<Button type="text" onClick={() => setShowAttract(!showAttract)} className={showAttract ? "active" : ""} ><MergeCellsOutlined /></Button>
|
|
231
|
+
</Tooltip>
|
|
232
|
+
</Space>
|
|
233
|
+
<Space size={4} separator={<Divider vertical styles={{ root: { margin: "0 4px" } }} />}>
|
|
234
|
+
<Tooltip title="快捷键">
|
|
235
|
+
<Button type="text" onClick={() => setShowShortCut(true)} ><QuestionCircleOutlined /></Button>
|
|
236
|
+
</Tooltip>
|
|
237
|
+
<Tooltip title="组件属性批量配置">
|
|
238
|
+
<>
|
|
239
|
+
<UploadReadExcel onChangeData={handleBatchSetNodeConfig} >
|
|
240
|
+
<Button type="text" ><SettingOutlined /></Button>
|
|
241
|
+
</UploadReadExcel>
|
|
242
|
+
</>
|
|
243
|
+
</Tooltip>
|
|
244
|
+
<Tooltip title="导入">
|
|
245
|
+
<Button type="text" onClick={handleRestore} ><ImportOutlined /></Button>
|
|
246
|
+
</Tooltip>
|
|
247
|
+
<Tooltip title="导出">
|
|
248
|
+
<Button type="text" onClick={() => handleExport("json")} ><ExportOutlined /></Button>
|
|
249
|
+
</Tooltip>
|
|
250
|
+
<Tooltip title="保存">
|
|
251
|
+
<Button loading={loading} type="text" onClick={() => handleExport("json", "save")} ><SaveOutlined /></Button>
|
|
252
|
+
</Tooltip>
|
|
253
|
+
</Space>
|
|
254
|
+
{showShortCut &&
|
|
255
|
+
<Modal title="快捷键" width={600} footer={null} open={showShortCut} onCancel={() => setShowShortCut(false)}>
|
|
256
|
+
<p>1、复制、粘贴、多选、全选、删除、上一步、下一步等快捷键与一般文档编辑器类似;</p>
|
|
257
|
+
<p>2、放大缩小,【Win】鼠标上滚动下滚动,【Mac】触控板双指放大、缩小;</p>
|
|
258
|
+
<p>3、画布拖动,在空白处,【Win】右键按下移动,【Mac】control + 触控板三指移动;</p>
|
|
259
|
+
</Modal>}
|
|
260
|
+
</div >
|
|
261
|
+
)
|
|
262
|
+
}
|
|
263
|
+
|
|
264
264
|
export default MainHeader;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { BgDraw } from './bg-draw';
|
|
2
|
-
export { RulerDraw } from './ruler-draw';
|
|
3
|
-
export { RefLineDraw } from './ref-line-draw';
|
|
4
|
-
export { ContextmenuDraw } from './contextmenu-draw';
|
|
5
|
-
export { PreviewDraw } from './preview-draw';
|
|
6
|
-
export { LinkDraw } from './link-draw';
|
|
7
|
-
export { GraphDraw } from './graph-draw';
|
|
1
|
+
export { BgDraw } from './bg-draw';
|
|
2
|
+
export { RulerDraw } from './ruler-draw';
|
|
3
|
+
export { RefLineDraw } from './ref-line-draw';
|
|
4
|
+
export { ContextmenuDraw } from './contextmenu-draw';
|
|
5
|
+
export { PreviewDraw } from './preview-draw';
|
|
6
|
+
export { LinkDraw } from './link-draw';
|
|
7
|
+
export { GraphDraw } from './graph-draw';
|