@robot-admin/naive-ui-components 0.4.3 → 0.4.5

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.
Files changed (297) hide show
  1. package/dist/C_ActionBar.cjs +1 -5
  2. package/dist/C_ActionBar.js +1 -4
  3. package/dist/C_ActionBar.js.map +1 -0
  4. package/dist/C_ActionBar2.js +1 -195
  5. package/dist/C_ActionBar2.js.map +1 -1
  6. package/dist/{C_AntV-DGjscTWa.css.map → C_AntV-A3NXx_sF.css.map} +1 -1
  7. package/dist/C_AntV.cjs +1 -8
  8. package/dist/C_AntV.js +1 -4
  9. package/dist/C_AntV.js.map +1 -0
  10. package/dist/C_AntV2.js +4 -3149
  11. package/dist/C_AntV2.js.map +1 -1
  12. package/dist/C_Barcode.cjs +1 -4
  13. package/dist/C_Barcode.js +1 -3
  14. package/dist/C_Barcode.js.map +1 -0
  15. package/dist/C_Barcode2.js +1 -67
  16. package/dist/C_Barcode2.js.map +1 -1
  17. package/dist/C_Captcha.cjs +1 -4
  18. package/dist/C_Captcha.js +1 -3
  19. package/dist/C_Captcha.js.map +1 -0
  20. package/dist/C_Captcha2.js +1 -154
  21. package/dist/C_Captcha2.js.map +1 -1
  22. package/dist/C_Cascade.cjs +1 -4
  23. package/dist/C_Cascade.js +1 -3
  24. package/dist/C_Cascade.js.map +1 -0
  25. package/dist/C_Cascade2.js +1 -102
  26. package/dist/C_Cascade2.js.map +1 -1
  27. package/dist/C_City.cjs +1 -4
  28. package/dist/C_City.js +1 -3
  29. package/dist/C_City.js.map +1 -0
  30. package/dist/C_City2.js +1 -840
  31. package/dist/C_City2.js.map +1 -1
  32. package/dist/C_Code.cjs +1 -5
  33. package/dist/C_Code.js +1 -4
  34. package/dist/C_Code.js.map +1 -0
  35. package/dist/C_Code2.js +1 -346
  36. package/dist/C_Code2.js.map +1 -1
  37. package/dist/C_CollapsePanel.cjs +1 -6
  38. package/dist/C_CollapsePanel.js +1 -4
  39. package/dist/C_CollapsePanel.js.map +1 -0
  40. package/dist/C_CollapsePanel2.js +1 -318
  41. package/dist/C_CollapsePanel2.js.map +1 -1
  42. package/dist/C_Cron.cjs +1 -15
  43. package/dist/C_Cron.js +1 -4
  44. package/dist/C_Cron.js.map +1 -0
  45. package/dist/C_Cron2.js +1 -1209
  46. package/dist/C_Cron2.js.map +1 -1
  47. package/dist/C_Date.cjs +1 -4
  48. package/dist/C_Date.js +1 -3
  49. package/dist/C_Date.js.map +1 -0
  50. package/dist/C_Date2.js +1 -218
  51. package/dist/C_Date2.js.map +1 -1
  52. package/dist/C_Draggable.cjs +1 -5
  53. package/dist/C_Draggable.js +1 -3
  54. package/dist/C_Draggable.js.map +1 -0
  55. package/dist/C_Draggable2.js +1 -294
  56. package/dist/C_Draggable2.js.map +1 -1
  57. package/dist/C_Editor.cjs +1 -4
  58. package/dist/C_Editor.js +1 -3
  59. package/dist/C_Editor.js.map +1 -0
  60. package/dist/C_Editor2.js +1 -159
  61. package/dist/C_Editor2.js.map +1 -1
  62. package/dist/{C_FilePreview-B4XgTv-h.css.map → C_FilePreview-DHGlV4OR.css.map} +1 -1
  63. package/dist/C_FilePreview.cjs +1 -7
  64. package/dist/C_FilePreview.js +1 -4
  65. package/dist/C_FilePreview.js.map +1 -0
  66. package/dist/C_FilePreview2.js +1 -1031
  67. package/dist/C_FilePreview2.js.map +1 -1
  68. package/dist/{C_Form-DLb9FtAb.css.map → C_Form-CKHvXL3O.css.map} +1 -1
  69. package/dist/C_Form.cjs +1 -16
  70. package/dist/C_Form.js +1 -5
  71. package/dist/C_Form.js.map +1 -0
  72. package/dist/C_Form2.js +1 -2569
  73. package/dist/C_Form2.js.map +1 -1
  74. package/dist/{C_FormSearch-DlIEoh7X.css.map → C_FormSearch-DBNtnjaL.css.map} +1 -1
  75. package/dist/C_FormSearch.cjs +1 -6
  76. package/dist/C_FormSearch.js +1 -3
  77. package/dist/C_FormSearch.js.map +1 -0
  78. package/dist/C_FormSearch2.js +1 -355
  79. package/dist/C_FormSearch2.js.map +1 -1
  80. package/dist/C_FormulaEditor.cjs +1 -13
  81. package/dist/C_FormulaEditor.js +1 -4
  82. package/dist/C_FormulaEditor.js.map +1 -0
  83. package/dist/C_FormulaEditor2.js +1 -1432
  84. package/dist/C_FormulaEditor2.js.map +1 -1
  85. package/dist/C_FullCalendar-DLUdCtqf.css.map +1 -0
  86. package/dist/C_FullCalendar.cjs +1 -9
  87. package/dist/C_FullCalendar.js +1 -3
  88. package/dist/C_FullCalendar.js.map +1 -0
  89. package/dist/C_FullCalendar2.js +1 -376
  90. package/dist/C_FullCalendar2.js.map +1 -1
  91. package/dist/C_GlobalSearch.cjs +1 -5
  92. package/dist/C_GlobalSearch.js +1 -3
  93. package/dist/C_GlobalSearch.js.map +1 -0
  94. package/dist/C_GlobalSearch2.js +1 -335
  95. package/dist/C_GlobalSearch2.js.map +1 -1
  96. package/dist/C_Guide.cjs +1 -5
  97. package/dist/C_Guide.js +1 -4
  98. package/dist/C_Guide.js.map +1 -0
  99. package/dist/C_Guide2.js +1 -60
  100. package/dist/C_Guide2.js.map +1 -1
  101. package/dist/C_Icon.cjs +1 -4
  102. package/dist/C_Icon.js +1 -3
  103. package/dist/C_Icon.js.map +1 -0
  104. package/dist/C_Icon2.js +1 -285
  105. package/dist/C_Icon2.js.map +1 -1
  106. package/dist/C_ImageCropper.cjs +1 -6
  107. package/dist/C_ImageCropper.js +1 -4
  108. package/dist/C_ImageCropper.js.map +1 -0
  109. package/dist/C_ImageCropper2.js +1 -722
  110. package/dist/C_ImageCropper2.js.map +1 -1
  111. package/dist/C_Language.cjs +1 -5
  112. package/dist/C_Language.js +1 -4
  113. package/dist/C_Language.js.map +1 -0
  114. package/dist/C_Language2.js +1 -78
  115. package/dist/C_Language2.js.map +1 -1
  116. package/dist/C_Map.cjs +1 -7
  117. package/dist/C_Map.js +1 -3
  118. package/dist/C_Map.js.map +1 -0
  119. package/dist/C_Map2.js +1 -198
  120. package/dist/C_Map2.js.map +1 -1
  121. package/dist/{C_Markdown-C2uiBVSW.css.map → C_Markdown-BbTvdFCl.css.map} +1 -1
  122. package/dist/C_Markdown.cjs +1 -4
  123. package/dist/C_Markdown.js +1 -3
  124. package/dist/C_Markdown.js.map +1 -0
  125. package/dist/C_Markdown2.js +1 -185
  126. package/dist/C_Markdown2.js.map +1 -1
  127. package/dist/C_NotificationCenter.cjs +1 -20
  128. package/dist/C_NotificationCenter.js +1 -4
  129. package/dist/C_NotificationCenter.js.map +1 -0
  130. package/dist/C_NotificationCenter2.js +1 -1383
  131. package/dist/C_NotificationCenter2.js.map +1 -1
  132. package/dist/C_Progress.cjs +1 -4
  133. package/dist/C_Progress.js +1 -3
  134. package/dist/C_Progress.js.map +1 -0
  135. package/dist/C_Progress2.js +1 -102
  136. package/dist/C_Progress2.js.map +1 -1
  137. package/dist/C_QRCode.cjs +1 -5
  138. package/dist/C_QRCode.js +1 -3
  139. package/dist/C_QRCode.js.map +1 -0
  140. package/dist/C_QRCode2.js +1 -217
  141. package/dist/C_QRCode2.js.map +1 -1
  142. package/dist/C_Signature.cjs +1 -8
  143. package/dist/C_Signature.js +1 -4
  144. package/dist/C_Signature.js.map +1 -0
  145. package/dist/C_Signature2.js +1 -617
  146. package/dist/C_Signature2.js.map +1 -1
  147. package/dist/C_SplitPane.cjs +1 -6
  148. package/dist/C_SplitPane.js +1 -4
  149. package/dist/C_SplitPane.js.map +1 -0
  150. package/dist/C_SplitPane2.js +1 -355
  151. package/dist/C_SplitPane2.js.map +1 -1
  152. package/dist/C_Steps.cjs +1 -4
  153. package/dist/C_Steps.js +1 -3
  154. package/dist/C_Steps.js.map +1 -0
  155. package/dist/C_Steps2.js +1 -81
  156. package/dist/C_Steps2.js.map +1 -1
  157. package/dist/{C_Table-C55H4kPr.css.map → C_Table-tbUx-R4H.css.map} +1 -1
  158. package/dist/C_Table.cjs +1 -20
  159. package/dist/C_Table.js +1 -6
  160. package/dist/C_Table.js.map +1 -0
  161. package/dist/C_Table2.js +1 -3023
  162. package/dist/C_Table2.js.map +1 -1
  163. package/dist/C_Theme.cjs +1 -5
  164. package/dist/C_Theme.js +1 -4
  165. package/dist/C_Theme.js.map +1 -0
  166. package/dist/C_Theme2.js +1 -63
  167. package/dist/C_Theme2.js.map +1 -1
  168. package/dist/C_Time.cjs +1 -5
  169. package/dist/C_Time.js +1 -3
  170. package/dist/C_Time.js.map +1 -0
  171. package/dist/C_Time2.js +1 -198
  172. package/dist/C_Time2.js.map +1 -1
  173. package/dist/C_Tree.cjs +1 -7
  174. package/dist/C_Tree.js +1 -4
  175. package/dist/C_Tree.js.map +1 -0
  176. package/dist/C_Tree2.js +1 -440
  177. package/dist/C_Tree2.js.map +1 -1
  178. package/dist/C_Upload.cjs +1 -12
  179. package/dist/C_Upload.js +1 -4
  180. package/dist/C_Upload.js.map +1 -0
  181. package/dist/C_Upload2.js +2 -1365
  182. package/dist/C_Upload2.js.map +1 -1
  183. package/dist/C_VideoPlayer.cjs +1 -23
  184. package/dist/C_VideoPlayer.js +1 -3
  185. package/dist/C_VideoPlayer.js.map +1 -0
  186. package/dist/C_VideoPlayer2.js +3 -1932
  187. package/dist/C_VideoPlayer2.js.map +1 -1
  188. package/dist/C_VtableGantt.cjs +1 -6
  189. package/dist/C_VtableGantt.js +1 -4
  190. package/dist/C_VtableGantt.js.map +1 -0
  191. package/dist/C_VtableGantt2.js +1 -872
  192. package/dist/C_VtableGantt2.js.map +1 -1
  193. package/dist/C_WaterFall.cjs +1 -13
  194. package/dist/C_WaterFall.js +1 -3
  195. package/dist/C_WaterFall.js.map +1 -0
  196. package/dist/C_WaterFall2.js +1 -364
  197. package/dist/C_WaterFall2.js.map +1 -1
  198. package/dist/{C_WorkFlow-CSO86Cuc.css.map → C_WorkFlow-7F6op6qN.css.map} +1 -1
  199. package/dist/C_WorkFlow.cjs +1 -8
  200. package/dist/C_WorkFlow.js +1 -4
  201. package/dist/C_WorkFlow.js.map +1 -0
  202. package/dist/C_WorkFlow2.js +1 -1983
  203. package/dist/C_WorkFlow2.js.map +1 -1
  204. package/dist/chunk.js +1 -18
  205. package/dist/city.js +1 -4816
  206. package/dist/constants.d.ts +1 -1
  207. package/dist/constants2.d.ts +2 -2
  208. package/dist/constants4.d.ts +8 -8
  209. package/dist/constants5.d.ts +2 -2
  210. package/dist/data.d.ts +2 -2
  211. package/dist/export-helper.js +1 -9
  212. package/dist/index.cjs +2 -413
  213. package/dist/index.cjs.map +1 -0
  214. package/dist/index.d.cts +1 -2
  215. package/dist/index.d.ts +1 -2
  216. package/dist/index.js +1 -231
  217. package/dist/index.js.map +1 -1
  218. package/dist/index.vue.d.ts +2 -2
  219. package/dist/index10.vue.d.ts +6 -6
  220. package/dist/index12.vue.d.ts +4 -4
  221. package/dist/index13.vue.d.ts +1 -1
  222. package/dist/index14.vue.d.ts +1 -1
  223. package/dist/index15.vue.d.ts +1 -1
  224. package/dist/index16.vue.d.ts +2 -2
  225. package/dist/index2.vue.d.ts +2 -2
  226. package/dist/index3.vue.d.ts +4 -4
  227. package/dist/index5.vue.d.ts +1 -1
  228. package/dist/index7.vue.d.ts +4 -4
  229. package/dist/index8.vue.d.ts +3 -3
  230. package/dist/index9.vue.d.ts +1 -1
  231. package/dist/resolver.cjs +2 -89
  232. package/dist/resolver.cjs.map +1 -0
  233. package/dist/resolver.js +1 -86
  234. package/dist/resolver.js.map +1 -1
  235. package/dist/storage.js +1 -30
  236. package/dist/storage.js.map +1 -1
  237. package/dist/style.css +447 -447
  238. package/dist/useCalendarEvents.d.ts +1 -1
  239. package/dist/useCollapsePanel.d.ts +2 -2
  240. package/dist/useCropperCore.d.ts +3 -3
  241. package/dist/useDraggableLayout.d.ts +9 -9
  242. package/dist/useDynamicFormState.d.ts +5 -5
  243. package/dist/useEdgeInteraction.d.ts +4 -12
  244. package/dist/useInfiniteScroll.d.ts +2 -2
  245. package/dist/useModalEdit.d.ts +45 -21
  246. package/dist/useQRCode.d.ts +3 -3
  247. package/dist/useSearchState.d.ts +2 -2
  248. package/dist/useSignatureHistory.d.ts +2 -2
  249. package/dist/useSplitResize.d.ts +6 -6
  250. package/dist/useTimeSelection.d.ts +2 -2
  251. package/dist/useTreeOperations.d.ts +6 -6
  252. package/dist/useWorkflowValidation.d.ts +3 -3
  253. package/package.json +1 -2
  254. package/dist/C_FullCalendar-BULCIlVK.css.map +0 -1
  255. package/dist/constants.d.ts.map +0 -1
  256. package/dist/constants2.d.ts.map +0 -1
  257. package/dist/constants3.d.ts.map +0 -1
  258. package/dist/constants4.d.ts.map +0 -1
  259. package/dist/constants5.d.ts.map +0 -1
  260. package/dist/data.d.ts.map +0 -1
  261. package/dist/index.d.cts.map +0 -1
  262. package/dist/index.d.ts.map +0 -1
  263. package/dist/index.vue.d.ts.map +0 -1
  264. package/dist/index10.vue.d.ts.map +0 -1
  265. package/dist/index11.vue.d.ts.map +0 -1
  266. package/dist/index12.vue.d.ts.map +0 -1
  267. package/dist/index13.vue.d.ts.map +0 -1
  268. package/dist/index14.vue.d.ts.map +0 -1
  269. package/dist/index15.vue.d.ts.map +0 -1
  270. package/dist/index16.vue.d.ts.map +0 -1
  271. package/dist/index2.vue.d.ts.map +0 -1
  272. package/dist/index3.vue.d.ts.map +0 -1
  273. package/dist/index4.vue.d.ts.map +0 -1
  274. package/dist/index5.vue.d.ts.map +0 -1
  275. package/dist/index6.vue.d.ts.map +0 -1
  276. package/dist/index7.vue.d.ts.map +0 -1
  277. package/dist/index8.vue.d.ts.map +0 -1
  278. package/dist/index9.vue.d.ts.map +0 -1
  279. package/dist/resolver.d.cts.map +0 -1
  280. package/dist/resolver.d.ts.map +0 -1
  281. package/dist/useCalendarEvents.d.ts.map +0 -1
  282. package/dist/useCollapsePanel.d.ts.map +0 -1
  283. package/dist/useCropperCore.d.ts.map +0 -1
  284. package/dist/useDraggableLayout.d.ts.map +0 -1
  285. package/dist/useDynamicFormState.d.ts.map +0 -1
  286. package/dist/useEdgeInteraction.d.ts.map +0 -1
  287. package/dist/useFullscreen.d.ts.map +0 -1
  288. package/dist/useGlobalSearch.d.ts.map +0 -1
  289. package/dist/useInfiniteScroll.d.ts.map +0 -1
  290. package/dist/useModalEdit.d.ts.map +0 -1
  291. package/dist/useQRCode.d.ts.map +0 -1
  292. package/dist/useSearchState.d.ts.map +0 -1
  293. package/dist/useSignatureHistory.d.ts.map +0 -1
  294. package/dist/useSplitResize.d.ts.map +0 -1
  295. package/dist/useTimeSelection.d.ts.map +0 -1
  296. package/dist/useTreeOperations.d.ts.map +0 -1
  297. package/dist/useWorkflowValidation.d.ts.map +0 -1
package/dist/C_AntV2.js CHANGED
@@ -1,3150 +1,5 @@
1
- import { t as C_Icon_default } from "./C_Icon2.js";
2
- import { t as export_helper_default } from "./export-helper.js";
3
- import { NAlert, NButton, NCard, NCheckbox, NDivider, NDrawer, NDrawerContent, NDropdown, NForm, NFormItem, NGi, NGrid, NInput, NRadio, NRadioGroup, NSelect, NSpace, useMessage } from "naive-ui";
4
- import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, mergeModels, mergeProps, nextTick, normalizeClass, normalizeStyle, onMounted, onUnmounted, openBlock, ref, renderList, resolveDynamicComponent, toDisplayString, unref, useModel, watch, withCtx } from "vue";
5
- import { Graph, ObjectExt } from "@antv/x6";
6
- import html2canvas from "html2canvas";
7
-
8
- //#region src/components/C_AntV/composables/useGraphBase.ts
9
- /**
10
- * 获取主题相关的颜色配置
11
- */
12
- function getThemeColors(isDark) {
13
- return {
14
- background: isDark ? "#18181c" : "#f5f5f5",
15
- gridPrimary: isDark ? "rgba(255, 255, 255, 0.08)" : "#eee",
16
- gridSecondary: isDark ? "rgba(255, 255, 255, 0.04)" : "#ddd"
17
- };
18
- }
19
- /**
20
- * 默认的图表配置选项
21
- */
22
- function getDefaultOptions(isDark = false) {
23
- const colors = getThemeColors(isDark);
24
- return {
25
- background: { color: colors.background },
26
- grid: {
27
- visible: true,
28
- type: "doubleMesh",
29
- args: [{
30
- color: colors.gridPrimary,
31
- thickness: 1
32
- }, {
33
- color: colors.gridSecondary,
34
- thickness: 1,
35
- factor: 4
36
- }]
37
- },
38
- mousewheel: {
39
- enabled: true,
40
- zoomAtMousePosition: true,
41
- modifiers: "ctrl",
42
- minScale: .5,
43
- maxScale: 2
44
- },
45
- selecting: {
46
- enabled: true,
47
- rubberband: true,
48
- movable: true,
49
- showNodeSelectionBox: true
50
- },
51
- resizing: true,
52
- rotating: true,
53
- snapline: true,
54
- keyboard: true,
55
- clipboard: true
56
- };
57
- }
58
- /**
59
- * 获取容器的尺寸
60
- */
61
- function getContainerSize(container) {
62
- if (!container) return {
63
- width: 0,
64
- height: 0
65
- };
66
- return {
67
- width: container.clientWidth || container.offsetWidth || 800,
68
- height: container.clientHeight || container.offsetHeight || 600
69
- };
70
- }
71
- /**
72
- * 创建和管理 AntV X6 图表实例的组合式 API
73
- */
74
- function useGraphBase(containerRef, isDarkRef) {
75
- const MAX_RETRY = 10;
76
- let retryCount = 0;
77
- const graph = ref(null);
78
- const loading = ref(false);
79
- /**
80
- * 初始化图表实例
81
- */
82
- const initGraph = async (options = {}) => {
83
- await nextTick();
84
- loading.value = true;
85
- try {
86
- if (!containerRef.value) return;
87
- if (graph.value) {
88
- graph.value.dispose();
89
- graph.value = null;
90
- }
91
- const { width, height } = getContainerSize(containerRef.value);
92
- if (width === 0 || height === 0) {
93
- retryCount++;
94
- if (retryCount < MAX_RETRY) setTimeout(() => initGraph(options), 100);
95
- return;
96
- }
97
- retryCount = 0;
98
- const defaultOptions = getDefaultOptions(isDarkRef?.value ?? false);
99
- graph.value = new Graph({
100
- container: containerRef.value,
101
- width,
102
- height,
103
- ...defaultOptions,
104
- ...options
105
- });
106
- } catch {} finally {
107
- loading.value = false;
108
- }
109
- };
110
- /**
111
- * 更新主题
112
- */
113
- function updateTheme(isDark) {
114
- if (!graph.value) return;
115
- const colors = getThemeColors(isDark);
116
- graph.value.drawBackground({ color: colors.background });
117
- graph.value.drawGrid({
118
- type: "doubleMesh",
119
- args: [{
120
- color: colors.gridPrimary,
121
- thickness: 1
122
- }, {
123
- color: colors.gridSecondary,
124
- thickness: 1,
125
- factor: 4
126
- }]
127
- });
128
- }
129
- if (isDarkRef) watch(isDarkRef, (isDark) => {
130
- updateTheme(isDark);
131
- });
132
- /**
133
- * 销毁当前图表实例
134
- */
135
- function destroyGraph() {
136
- if (graph.value) {
137
- graph.value.dispose();
138
- graph.value = null;
139
- }
140
- }
141
- /**
142
- * 将图表内容居中显示
143
- */
144
- function centerContent() {
145
- graph.value?.centerContent();
146
- }
147
- /**
148
- * 自适应缩放图表以适应容器
149
- */
150
- function zoomToFit() {
151
- graph.value?.zoomToFit({
152
- padding: 20,
153
- maxScale: 1
154
- });
155
- }
156
- /**
157
- * 按指定因子缩放图表
158
- */
159
- function zoom(factor) {
160
- graph.value?.zoom(factor);
161
- }
162
- /**
163
- * 调整图表尺寸以适应容器变化
164
- */
165
- function resizeGraph() {
166
- if (graph.value && containerRef.value) {
167
- const { width, height } = getContainerSize(containerRef.value);
168
- graph.value.resize(width, height);
169
- }
170
- }
171
- onUnmounted(destroyGraph);
172
- return {
173
- graph,
174
- loading,
175
- initGraph,
176
- destroyGraph,
177
- centerContent,
178
- zoomToFit,
179
- zoom,
180
- resizeGraph,
181
- updateTheme
182
- };
183
- }
184
-
185
- //#endregion
186
- //#region src/components/C_AntV/utils/exportUtils.ts
187
- /**
188
- * 下载 Blob 文件到本地
189
- * @param blob - Blob 对象
190
- * @param filename - 文件名
191
- */
192
- function downloadBlob(blob, filename) {
193
- const url = URL.createObjectURL(blob);
194
- const link = document.createElement("a");
195
- link.href = url;
196
- link.download = filename;
197
- link.style.display = "none";
198
- document.body.appendChild(link);
199
- link.click();
200
- document.body.removeChild(link);
201
- URL.revokeObjectURL(url);
202
- }
203
- /**
204
- * 导出数据为 JSON 文件
205
- * @param data - 要导出的数据
206
- * @param filename - 文件名,默认 'diagram.json'
207
- */
208
- function exportJSON(data, filename = "diagram.json") {
209
- const jsonString = JSON.stringify(data, null, 2);
210
- downloadBlob(new Blob([jsonString], { type: "application/json" }), filename);
211
- }
212
- /**
213
- * 导出图表为 PNG 图片(基于 html2canvas 截图方案)
214
- * @param graph - AntV X6 图表实例
215
- * @param filename - 文件名,默认 'diagram.png'
216
- * @param options - 导出选项
217
- */
218
- async function exportPNG(graph, filename = "diagram.png", options = {}) {
219
- const { backgroundColor = "#ffffff", scale = 2 } = options;
220
- const { container } = graph;
221
- downloadBlob(await canvasToBlob(await html2canvas(container, {
222
- backgroundColor,
223
- scale,
224
- useCORS: true,
225
- logging: false
226
- }), "image/png"), filename);
227
- }
228
- /**
229
- * 导出图表为 SVG 矢量图(从容器内 SVG 元素序列化)
230
- * @param graph - AntV X6 图表实例
231
- * @param filename - 文件名,默认 'diagram.svg'
232
- */
233
- function exportSVG(graph, filename = "diagram.svg") {
234
- const svgElement = graph.container.querySelector("svg");
235
- if (!svgElement) throw new Error("SVG导出失败: 未找到图表 SVG 元素");
236
- const cloned = svgElement.cloneNode(true);
237
- if (!cloned.getAttribute("xmlns")) cloned.setAttribute("xmlns", "http://www.w3.org/2000/svg");
238
- if (!cloned.getAttribute("xmlns:xlink")) cloned.setAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink");
239
- const svgString = new XMLSerializer().serializeToString(cloned);
240
- downloadBlob(new Blob([svgString], { type: "image/svg+xml;charset=utf-8" }), filename);
241
- }
242
- /**
243
- * 将 Canvas 转换为 Blob
244
- */
245
- function canvasToBlob(canvas, mimeType, quality = 1) {
246
- return new Promise((resolve, reject) => {
247
- canvas.toBlob((blob) => {
248
- if (blob) resolve(blob);
249
- else reject(/* @__PURE__ */ new Error("Canvas 转 Blob 失败"));
250
- }, mimeType, quality);
251
- });
252
- }
253
-
254
- //#endregion
255
- //#region src/components/C_AntV/composables/useGraphExport.ts
256
- /** 导出下拉菜单选项(三个布局共享) */
257
- const EXPORT_OPTIONS = [
258
- {
259
- label: "导出PNG",
260
- key: "png"
261
- },
262
- {
263
- label: "导出SVG",
264
- key: "svg"
265
- },
266
- {
267
- label: "导出JSON",
268
- key: "json"
269
- }
270
- ];
271
- /**
272
- * 图表导出 composable — 统一 PNG / SVG / JSON 导出逻辑
273
- * @param graph - X6 Graph 实例引用
274
- * @param filenamePrefix - 导出文件名前缀,默认 'diagram'
275
- */
276
- function useGraphExport(graph, filenamePrefix = "diagram") {
277
- const message = useMessage();
278
- /**
279
- * 处理导出操作
280
- * @param key - 导出格式 'png' | 'svg' | 'json'
281
- * @param getData - 获取当前图表数据的函数(用于 JSON 导出)
282
- */
283
- const handleExport = async (key, getData) => {
284
- if (!graph.value) return;
285
- try {
286
- switch (key) {
287
- case "png":
288
- await exportPNG(graph.value, `${filenamePrefix}.png`);
289
- break;
290
- case "svg":
291
- exportSVG(graph.value, `${filenamePrefix}.svg`);
292
- break;
293
- case "json":
294
- if (getData) exportJSON(getData(), `${filenamePrefix}.json`);
295
- break;
296
- }
297
- } catch (error) {
298
- console.error(`[useGraphExport] 导出失败 (${key}):`, error);
299
- message.error(`导出${key.toUpperCase()}失败,请重试`);
300
- }
301
- };
302
- return {
303
- exportOptions: EXPORT_OPTIONS,
304
- handleExport
305
- };
306
- }
307
-
308
- //#endregion
309
- //#region src/components/C_AntV/layout/ER/data.ts
310
- const fieldTypes = [
311
- {
312
- label: "BIGINT",
313
- value: "BIGINT"
314
- },
315
- {
316
- label: "INT",
317
- value: "INT"
318
- },
319
- {
320
- label: "SMALLINT",
321
- value: "SMALLINT"
322
- },
323
- {
324
- label: "TINYINT",
325
- value: "TINYINT"
326
- },
327
- {
328
- label: "VARCHAR(50)",
329
- value: "VARCHAR(50)"
330
- },
331
- {
332
- label: "VARCHAR(100)",
333
- value: "VARCHAR(100)"
334
- },
335
- {
336
- label: "VARCHAR(255)",
337
- value: "VARCHAR(255)"
338
- },
339
- {
340
- label: "CHAR(10)",
341
- value: "CHAR(10)"
342
- },
343
- {
344
- label: "TEXT",
345
- value: "TEXT"
346
- },
347
- {
348
- label: "LONGTEXT",
349
- value: "LONGTEXT"
350
- },
351
- {
352
- label: "DATETIME",
353
- value: "DATETIME"
354
- },
355
- {
356
- label: "TIMESTAMP",
357
- value: "TIMESTAMP"
358
- },
359
- {
360
- label: "DATE",
361
- value: "DATE"
362
- },
363
- {
364
- label: "TIME",
365
- value: "TIME"
366
- },
367
- {
368
- label: "DECIMAL(10,2)",
369
- value: "DECIMAL(10,2)"
370
- },
371
- {
372
- label: "FLOAT",
373
- value: "FLOAT"
374
- },
375
- {
376
- label: "DOUBLE",
377
- value: "DOUBLE"
378
- },
379
- {
380
- label: "BOOLEAN",
381
- value: "BOOLEAN"
382
- },
383
- {
384
- label: "JSON",
385
- value: "JSON"
386
- }
387
- ];
388
-
389
- //#endregion
390
- //#region src/components/C_AntV/layout/ER/components/ERTableEditor.vue?vue&type=script&setup=true&lang.ts
391
- const _hoisted_1$6 = {
392
- key: 0,
393
- class: "table-editor"
394
- };
395
- const _hoisted_2$5 = { class: "fields-container" };
396
- const _hoisted_3$4 = { class: "field-header" };
397
- var ERTableEditor_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
398
- __name: "ERTableEditor",
399
- props: /* @__PURE__ */ mergeModels({ show: { type: Boolean } }, {
400
- "editingTable": {},
401
- "editingTableModifiers": {}
402
- }),
403
- emits: /* @__PURE__ */ mergeModels([
404
- "update:show",
405
- "save",
406
- "add-field",
407
- "remove-field",
408
- "handle-primary-key"
409
- ], ["update:editingTable"]),
410
- setup(__props, { emit: __emit }) {
411
- const editingTable = useModel(__props, "editingTable");
412
- const emit = __emit;
413
- const handlePrimaryKey = (field, isPrimaryKey) => emit("handle-primary-key", field, isPrimaryKey);
414
- const addField = () => emit("add-field");
415
- const removeField = (index) => emit("remove-field", index);
416
- return (_ctx, _cache) => {
417
- return openBlock(), createBlock(unref(NDrawer), {
418
- show: _ctx.show,
419
- width: "600",
420
- placement: "right",
421
- "onUpdate:show": _cache[4] || (_cache[4] = ($event) => _ctx.$emit("update:show", $event))
422
- }, {
423
- default: withCtx(() => [createVNode(unref(NDrawerContent), {
424
- title: `编辑表: ${editingTable.value?.name || "新表"}`,
425
- closable: ""
426
- }, {
427
- footer: withCtx(() => [createVNode(unref(NSpace), { justify: "end" }, {
428
- default: withCtx(() => [createVNode(unref(NButton), { onClick: _cache[2] || (_cache[2] = ($event) => _ctx.$emit("update:show", false)) }, {
429
- default: withCtx(() => _cache[11] || (_cache[11] = [createTextVNode("取消", -1)])),
430
- _: 1,
431
- __: [11]
432
- }), createVNode(unref(NButton), {
433
- onClick: _cache[3] || (_cache[3] = ($event) => _ctx.$emit("save")),
434
- type: "primary"
435
- }, {
436
- default: withCtx(() => _cache[12] || (_cache[12] = [createTextVNode("保存", -1)])),
437
- _: 1,
438
- __: [12]
439
- })]),
440
- _: 1
441
- })]),
442
- default: withCtx(() => [editingTable.value ? (openBlock(), createElementBlock("div", _hoisted_1$6, [createVNode(unref(NForm), {
443
- model: editingTable.value,
444
- "label-placement": "top"
445
- }, {
446
- default: withCtx(() => [
447
- createVNode(unref(NFormItem), { label: "表名" }, {
448
- default: withCtx(() => [createVNode(unref(NInput), {
449
- value: editingTable.value.name,
450
- "onUpdate:value": _cache[0] || (_cache[0] = ($event) => editingTable.value.name = $event),
451
- placeholder: "请输入表名"
452
- }, null, 8, ["value"])]),
453
- _: 1
454
- }),
455
- createVNode(unref(NFormItem), { label: "表注释" }, {
456
- default: withCtx(() => [createVNode(unref(NInput), {
457
- value: editingTable.value.comment,
458
- "onUpdate:value": _cache[1] || (_cache[1] = ($event) => editingTable.value.comment = $event),
459
- placeholder: "表注释"
460
- }, null, 8, ["value"])]),
461
- _: 1
462
- }),
463
- createVNode(unref(NDivider), null, {
464
- default: withCtx(() => _cache[5] || (_cache[5] = [createTextVNode("字段列表", -1)])),
465
- _: 1,
466
- __: [5]
467
- }),
468
- createElementVNode("div", _hoisted_2$5, [(openBlock(true), createElementBlock(Fragment, null, renderList(editingTable.value.fields, (field, index) => {
469
- return openBlock(), createBlock(unref(NCard), {
470
- key: index,
471
- size: "small",
472
- class: "field-card"
473
- }, {
474
- header: withCtx(() => [createElementVNode("div", _hoisted_3$4, [createElementVNode("span", null, "#" + toDisplayString(index + 1) + " " + toDisplayString(field.name || "新字段"), 1), createVNode(unref(NButton), {
475
- onClick: ($event) => removeField(index),
476
- size: "tiny",
477
- type: "error",
478
- quaternary: "",
479
- disabled: editingTable.value.fields.length <= 1
480
- }, {
481
- default: withCtx(() => _cache[6] || (_cache[6] = [createTextVNode(" 删除 ", -1)])),
482
- _: 2,
483
- __: [6]
484
- }, 1032, ["onClick", "disabled"])])]),
485
- default: withCtx(() => [
486
- createVNode(unref(NGrid), {
487
- cols: 2,
488
- "x-gap": 12
489
- }, {
490
- default: withCtx(() => [createVNode(unref(NGi), null, {
491
- default: withCtx(() => [createVNode(unref(NFormItem), {
492
- label: "字段名",
493
- size: "small"
494
- }, {
495
- default: withCtx(() => [createVNode(unref(NInput), {
496
- value: field.name,
497
- "onUpdate:value": ($event) => field.name = $event,
498
- placeholder: "字段名",
499
- size: "small"
500
- }, null, 8, ["value", "onUpdate:value"])]),
501
- _: 2
502
- }, 1024)]),
503
- _: 2
504
- }, 1024), createVNode(unref(NGi), null, {
505
- default: withCtx(() => [createVNode(unref(NFormItem), {
506
- label: "类型",
507
- size: "small"
508
- }, {
509
- default: withCtx(() => [createVNode(unref(NSelect), {
510
- value: field.type,
511
- "onUpdate:value": ($event) => field.type = $event,
512
- options: unref(fieldTypes),
513
- size: "small",
514
- filterable: "",
515
- placeholder: "选择类型"
516
- }, null, 8, [
517
- "value",
518
- "onUpdate:value",
519
- "options"
520
- ])]),
521
- _: 2
522
- }, 1024)]),
523
- _: 2
524
- }, 1024)]),
525
- _: 2
526
- }, 1024),
527
- createVNode(unref(NSpace), { style: { "margin-top": "12px" } }, {
528
- default: withCtx(() => [
529
- createVNode(unref(NCheckbox), {
530
- checked: field.isPrimaryKey,
531
- "onUpdate:checked": [($event) => field.isPrimaryKey = $event, ($event) => handlePrimaryKey(field, $event)]
532
- }, {
533
- default: withCtx(() => _cache[7] || (_cache[7] = [createTextVNode(" 主键 ", -1)])),
534
- _: 2,
535
- __: [7]
536
- }, 1032, ["checked", "onUpdate:checked"]),
537
- createVNode(unref(NCheckbox), {
538
- checked: field.isRequired,
539
- "onUpdate:checked": ($event) => field.isRequired = $event
540
- }, {
541
- default: withCtx(() => _cache[8] || (_cache[8] = [createTextVNode("必填", -1)])),
542
- _: 2,
543
- __: [8]
544
- }, 1032, ["checked", "onUpdate:checked"]),
545
- createVNode(unref(NCheckbox), {
546
- checked: field.isForeignKey,
547
- "onUpdate:checked": ($event) => field.isForeignKey = $event
548
- }, {
549
- default: withCtx(() => _cache[9] || (_cache[9] = [createTextVNode("外键", -1)])),
550
- _: 2,
551
- __: [9]
552
- }, 1032, ["checked", "onUpdate:checked"])
553
- ]),
554
- _: 2
555
- }, 1024),
556
- createVNode(unref(NFormItem), {
557
- label: "注释",
558
- size: "small",
559
- style: { "margin-top": "12px" }
560
- }, {
561
- default: withCtx(() => [createVNode(unref(NInput), {
562
- value: field.comment,
563
- "onUpdate:value": ($event) => field.comment = $event,
564
- placeholder: "字段注释",
565
- size: "small"
566
- }, null, 8, ["value", "onUpdate:value"])]),
567
- _: 2
568
- }, 1024)
569
- ]),
570
- _: 2
571
- }, 1024);
572
- }), 128)), createVNode(unref(NButton), {
573
- onClick: addField,
574
- dashed: "",
575
- block: "",
576
- type: "primary",
577
- ghost: "",
578
- style: { "margin-top": "16px" }
579
- }, {
580
- icon: withCtx(() => [createVNode(C_Icon_default, {
581
- name: "mdi:plus",
582
- size: 16
583
- })]),
584
- default: withCtx(() => [_cache[10] || (_cache[10] = createTextVNode(" 添加字段 ", -1))]),
585
- _: 1,
586
- __: [10]
587
- })])
588
- ]),
589
- _: 1
590
- }, 8, ["model"])])) : createCommentVNode("v-if", true)]),
591
- _: 1
592
- }, 8, ["title"])]),
593
- _: 1
594
- }, 8, ["show"]);
595
- };
596
- }
597
- });
598
-
599
- //#endregion
600
- //#region src/components/C_AntV/layout/ER/components/ERTableEditor.vue
601
- var ERTableEditor_default = ERTableEditor_vue_vue_type_script_setup_true_lang_default;
602
-
603
- //#endregion
604
- //#region src/components/C_AntV/layout/ER/index.vue?vue&type=script&setup=true&lang.ts
605
- const _hoisted_1$5 = { class: "er-layout" };
606
- const _hoisted_2$4 = {
607
- key: 0,
608
- class: "toolbar"
609
- };
610
- const _hoisted_3$3 = {
611
- key: 0,
612
- style: { "margin-top": "8px" }
613
- };
614
- var index_vue_vue_type_script_setup_true_lang_default$3 = /* @__PURE__ */ defineComponent({
615
- __name: "index",
616
- props: {
617
- data: {},
618
- showToolbar: {
619
- type: Boolean,
620
- default: true
621
- },
622
- readonly: {
623
- type: Boolean,
624
- default: false
625
- },
626
- theme: {}
627
- },
628
- emits: ["ready", "data-change"],
629
- setup(__props, { expose: __expose, emit: __emit }) {
630
- const props = __props;
631
- const emit = __emit;
632
- const containerRef = ref();
633
- const { graph, initGraph, centerContent, zoomToFit } = useGraphBase(containerRef, computed(() => props.theme === "dark"));
634
- const { exportOptions, handleExport } = useGraphExport(graph, "er-diagram");
635
- const showEditor = ref(false);
636
- const editingTable = ref();
637
- const deleteMode = ref(false);
638
- const truncateText = (text, maxLength) => text.length > maxLength ? text.substring(0, maxLength - 1) + ".." : text;
639
- const createPortConfig = (table) => table.fields?.map((field) => {
640
- const displayName = field.isPrimaryKey ? `🔑 ${field.name}` : field.isRequired ? `* ${field.name}` : field.name;
641
- return {
642
- id: `${table.id}_${field.name}`,
643
- group: "list",
644
- attrs: {
645
- portNameLabel: {
646
- text: truncateText(displayName, 12),
647
- title: displayName
648
- },
649
- portTypeLabel: {
650
- text: truncateText(field.type, 10),
651
- title: field.type
652
- },
653
- portBody: { fill: field.isPrimaryKey ? "#FFF7E6" : "#EFF4FF" }
654
- }
655
- };
656
- }) || [];
657
- const createNodeConfig = (table) => ({
658
- id: table.id,
659
- shape: "er-rect",
660
- x: table.position.x,
661
- y: table.position.y,
662
- width: 200,
663
- height: 24 + (table.fields?.length || 0) * 24,
664
- data: table,
665
- attrs: { label: {
666
- text: truncateText(table.name, 20),
667
- refX: .5,
668
- refY: 10,
669
- textAnchor: "middle",
670
- title: table.name
671
- } },
672
- ports: createPortConfig(table)
673
- });
674
- const registerNodes = () => {
675
- if (!graph.value) return;
676
- Graph.registerPortLayout("erPortPosition", (portsPositionArgs) => portsPositionArgs.map((_, index) => ({
677
- position: {
678
- x: 0,
679
- y: (index + 1) * 24
680
- },
681
- angle: 0
682
- })), true);
683
- Graph.registerNode("er-rect", {
684
- inherit: "rect",
685
- markup: [{
686
- tagName: "rect",
687
- selector: "body"
688
- }, {
689
- tagName: "text",
690
- selector: "label"
691
- }],
692
- attrs: {
693
- rect: {
694
- strokeWidth: 1,
695
- stroke: "#5F95FF",
696
- fill: "#5F95FF"
697
- },
698
- label: {
699
- fontWeight: "bold",
700
- fill: "#ffffff",
701
- fontSize: 12
702
- }
703
- },
704
- ports: { groups: { list: {
705
- markup: [
706
- {
707
- tagName: "rect",
708
- selector: "portBody"
709
- },
710
- {
711
- tagName: "text",
712
- selector: "portNameLabel"
713
- },
714
- {
715
- tagName: "text",
716
- selector: "portTypeLabel"
717
- }
718
- ],
719
- attrs: {
720
- portBody: {
721
- width: 200,
722
- height: 24,
723
- strokeWidth: 1,
724
- stroke: "#5F95FF",
725
- fill: "#EFF4FF",
726
- magnet: true
727
- },
728
- portNameLabel: {
729
- ref: "portBody",
730
- refX: 6,
731
- refY: 6,
732
- fontSize: 9,
733
- textAnchor: "start",
734
- textOverflow: "ellipsis"
735
- },
736
- portTypeLabel: {
737
- ref: "portBody",
738
- refX: 120,
739
- refY: 6,
740
- fontSize: 9,
741
- textAnchor: "start",
742
- fill: "#666"
743
- }
744
- },
745
- position: "erPortPosition"
746
- } } }
747
- }, true);
748
- };
749
- const toggleDeleteMode = () => {
750
- deleteMode.value = !deleteMode.value;
751
- if (!deleteMode.value) resetEdgeStyles();
752
- };
753
- const resetEdgeStyles = () => {
754
- graph.value?.getEdges().forEach((edge) => {
755
- edge.attr("line/stroke", "#A2B1C3");
756
- edge.attr("line/strokeWidth", 2);
757
- });
758
- };
759
- const createTableNode = (table) => {
760
- if (!graph.value) return;
761
- const node = graph.value.createNode(createNodeConfig(table));
762
- graph.value.resetCells([node, ...graph.value.getCells()]);
763
- return node;
764
- };
765
- const findPosition = () => {
766
- const nodes = graph.value?.getNodes() || [];
767
- const spacing = 250;
768
- for (let row = 0; row < 10; row++) for (let col = 0; col < 3; col++) {
769
- const pos = {
770
- x: col * spacing + 50,
771
- y: row * spacing + 50
772
- };
773
- if (!nodes.some((node) => {
774
- const nodePos = node.getPosition();
775
- return Math.abs(nodePos.x - pos.x) < spacing * .8 && Math.abs(nodePos.y - pos.y) < spacing * .8;
776
- })) return pos;
777
- }
778
- return {
779
- x: 50,
780
- y: 50
781
- };
782
- };
783
- const addTable = () => {
784
- const newTable = {
785
- id: `table_${Date.now()}`,
786
- name: "新表",
787
- comment: "",
788
- fields: [{
789
- name: "id",
790
- type: "BIGINT",
791
- isPrimaryKey: true,
792
- isRequired: true,
793
- isForeignKey: false,
794
- comment: "主键"
795
- }, {
796
- name: "name",
797
- type: "VARCHAR(100)",
798
- isPrimaryKey: false,
799
- isRequired: true,
800
- isForeignKey: false,
801
- comment: "名称"
802
- }],
803
- position: findPosition()
804
- };
805
- createTableNode(newTable);
806
- editTable(newTable);
807
- emitDataChange();
808
- };
809
- const editTable = (table) => {
810
- editingTable.value = {
811
- ...table,
812
- fields: table.fields?.map((field) => ({ ...field })) || []
813
- };
814
- showEditor.value = true;
815
- };
816
- const saveTable = () => {
817
- if (!graph.value || !editingTable.value) return;
818
- const node = graph.value.getCellById(editingTable.value.id);
819
- if (node) {
820
- node.setData(editingTable.value);
821
- node.prop({
822
- size: {
823
- width: 200,
824
- height: 24 + editingTable.value.fields.length * 24
825
- },
826
- attrs: { label: {
827
- text: truncateText(editingTable.value.name, 20),
828
- title: editingTable.value.name
829
- } },
830
- ports: createPortConfig(editingTable.value)
831
- });
832
- }
833
- showEditor.value = false;
834
- emitDataChange();
835
- };
836
- const handlePrimaryKey = (field, isPrimaryKey) => {
837
- if (!isPrimaryKey) return;
838
- field.isRequired = true;
839
- editingTable.value?.fields.forEach((f) => {
840
- if (f !== field) f.isPrimaryKey = false;
841
- });
842
- };
843
- const addField = () => {
844
- editingTable.value?.fields.push({
845
- name: `field_${(editingTable.value?.fields.length || 0) + 1}`,
846
- type: "VARCHAR(100)",
847
- isPrimaryKey: false,
848
- isRequired: false,
849
- isForeignKey: false,
850
- comment: ""
851
- });
852
- };
853
- const removeField = (index) => {
854
- if (editingTable.value && editingTable.value.fields.length > 1) editingTable.value.fields.splice(index, 1);
855
- };
856
- const getCurrentData = () => {
857
- if (!graph.value) return {
858
- tables: [],
859
- relations: []
860
- };
861
- const tables = graph.value.getNodes().map((node) => ({
862
- ...node.getData(),
863
- position: node.getPosition()
864
- }));
865
- const relations = [];
866
- graph.value.getEdges().forEach((edge) => {
867
- const source = edge.getSourceNode();
868
- const target = edge.getTargetNode();
869
- const sourcePort = edge.getSourcePortId();
870
- const targetPort = edge.getTargetPortId();
871
- if (source && target && sourcePort && targetPort) relations.push({
872
- id: edge.id,
873
- type: "foreign-key",
874
- sourceTable: source.id,
875
- sourceField: sourcePort.split("_").slice(1).join("_"),
876
- targetTable: target.id,
877
- targetField: targetPort.split("_").slice(1).join("_"),
878
- name: `${source.getData()?.name || source.id} -> ${target.getData()?.name || target.id}`
879
- });
880
- });
881
- return {
882
- tables,
883
- relations
884
- };
885
- };
886
- const emitDataChange = () => emit("data-change", getCurrentData());
887
- watch(graph, (newGraph) => {
888
- if (!(newGraph instanceof Graph)) return;
889
- registerNodes();
890
- newGraph.on("node:dblclick", ({ node }) => {
891
- if (!props.readonly) editTable(node.getData());
892
- });
893
- newGraph.on("edge:connected", emitDataChange);
894
- newGraph.on("edge:removed", emitDataChange);
895
- let selectedEdge = null;
896
- newGraph.on("edge:click", ({ edge }) => {
897
- if (deleteMode.value) {
898
- edge.remove();
899
- emitDataChange();
900
- } else {
901
- resetEdgeStyles();
902
- edge.attr("line/stroke", "#ff4d4f");
903
- edge.attr("line/strokeWidth", 3);
904
- selectedEdge = edge;
905
- }
906
- });
907
- newGraph.on("edge:dblclick", ({ edge }) => {
908
- edge.remove();
909
- emitDataChange();
910
- });
911
- newGraph.on("blank:click", () => {
912
- selectedEdge = null;
913
- if (!deleteMode.value) resetEdgeStyles();
914
- });
915
- const handleKeyDown = (e) => {
916
- const tag = e.target?.tagName;
917
- if (tag === "INPUT" || tag === "TEXTAREA" || e.target?.isContentEditable) return;
918
- if ((e.key === "Delete" || e.key === "Backspace") && selectedEdge) {
919
- selectedEdge.remove();
920
- emitDataChange();
921
- selectedEdge = null;
922
- }
923
- };
924
- document.addEventListener("keydown", handleKeyDown);
925
- onUnmounted(() => document.removeEventListener("keydown", handleKeyDown));
926
- emit("ready", newGraph);
927
- nextTick(() => {
928
- if (props.data?.tables) {
929
- const cells = props.data.tables.map((table) => newGraph.createNode(createNodeConfig(table)));
930
- if (props.data.relations?.length) props.data.relations.forEach((relation) => {
931
- cells.push(newGraph.createEdge({
932
- source: {
933
- cell: relation.sourceTable,
934
- port: `${relation.sourceTable}_${relation.sourceField}`
935
- },
936
- target: {
937
- cell: relation.targetTable,
938
- port: `${relation.targetTable}_${relation.targetField}`
939
- },
940
- attrs: { line: {
941
- stroke: "#A2B1C3",
942
- strokeWidth: 2
943
- } }
944
- }));
945
- });
946
- newGraph.resetCells(cells);
947
- setTimeout(() => newGraph.zoomToFit({
948
- padding: 20,
949
- maxScale: 1
950
- }), 300);
951
- }
952
- });
953
- }, { immediate: true });
954
- watch(() => props.data, (newData) => {
955
- if (graph.value && newData?.tables) {
956
- const cells = newData.tables.map((table) => graph.value.createNode(createNodeConfig(table)));
957
- if (newData.relations?.length) newData.relations.forEach((relation) => {
958
- cells.push(graph.value.createEdge({
959
- source: {
960
- cell: relation.sourceTable,
961
- port: `${relation.sourceTable}_${relation.sourceField}`
962
- },
963
- target: {
964
- cell: relation.targetTable,
965
- port: `${relation.targetTable}_${relation.targetField}`
966
- },
967
- attrs: { line: {
968
- stroke: "#A2B1C3",
969
- strokeWidth: 2
970
- } }
971
- }));
972
- });
973
- graph.value.resetCells(cells);
974
- }
975
- }, { deep: true });
976
- onMounted(() => initGraph());
977
- __expose({
978
- getGraph: () => graph.value ?? void 0,
979
- getData: getCurrentData
980
- });
981
- return (_ctx, _cache) => {
982
- return openBlock(), createElementBlock("div", _hoisted_1$5, [
983
- createCommentVNode(" 工具栏 "),
984
- _ctx.showToolbar ? (openBlock(), createElementBlock("div", _hoisted_2$4, [createVNode(unref(NSpace), null, {
985
- default: withCtx(() => [
986
- createVNode(unref(NButton), {
987
- onClick: addTable,
988
- type: "primary",
989
- size: "small"
990
- }, {
991
- icon: withCtx(() => [createVNode(C_Icon_default, {
992
- name: "mdi:table-plus",
993
- size: 16
994
- })]),
995
- default: withCtx(() => [_cache[3] || (_cache[3] = createTextVNode(" 添加表 ", -1))]),
996
- _: 1,
997
- __: [3]
998
- }),
999
- createVNode(unref(NButton), {
1000
- onClick: unref(centerContent),
1001
- size: "small"
1002
- }, {
1003
- icon: withCtx(() => [createVNode(C_Icon_default, {
1004
- name: "mdi:image-filter-center-focus",
1005
- size: 16
1006
- })]),
1007
- default: withCtx(() => [_cache[4] || (_cache[4] = createTextVNode(" 居中 ", -1))]),
1008
- _: 1,
1009
- __: [4]
1010
- }, 8, ["onClick"]),
1011
- createVNode(unref(NButton), {
1012
- onClick: unref(zoomToFit),
1013
- size: "small"
1014
- }, {
1015
- icon: withCtx(() => [createVNode(C_Icon_default, {
1016
- name: "mdi:fit-to-screen",
1017
- size: 16
1018
- })]),
1019
- default: withCtx(() => [_cache[5] || (_cache[5] = createTextVNode(" 适应 ", -1))]),
1020
- _: 1,
1021
- __: [5]
1022
- }, 8, ["onClick"]),
1023
- createVNode(unref(NButton), {
1024
- onClick: toggleDeleteMode,
1025
- type: deleteMode.value ? "error" : "default",
1026
- size: "small"
1027
- }, {
1028
- icon: withCtx(() => [createVNode(C_Icon_default, {
1029
- name: "mdi:delete",
1030
- size: 16
1031
- })]),
1032
- default: withCtx(() => [createTextVNode(" " + toDisplayString(deleteMode.value ? "退出删除" : "删除连线"), 1)]),
1033
- _: 1
1034
- }, 8, ["type"]),
1035
- createVNode(unref(NDropdown), {
1036
- options: unref(exportOptions),
1037
- onSelect: _cache[0] || (_cache[0] = (key) => unref(handleExport)(key, getCurrentData))
1038
- }, {
1039
- default: withCtx(() => [createVNode(unref(NButton), { size: "small" }, {
1040
- icon: withCtx(() => [createVNode(C_Icon_default, {
1041
- name: "mdi:export",
1042
- size: 16
1043
- })]),
1044
- default: withCtx(() => [_cache[6] || (_cache[6] = createTextVNode(" 导出 ", -1))]),
1045
- _: 1,
1046
- __: [6]
1047
- })]),
1048
- _: 1
1049
- }, 8, ["options"])
1050
- ]),
1051
- _: 1
1052
- }), deleteMode.value ? (openBlock(), createElementBlock("div", _hoisted_3$3, [createVNode(unref(NAlert), {
1053
- type: "info",
1054
- size: "small",
1055
- "show-icon": false
1056
- }, {
1057
- default: withCtx(() => _cache[7] || (_cache[7] = [createTextVNode(" 删除模式:点击连接线即可删除 ", -1)])),
1058
- _: 1,
1059
- __: [7]
1060
- })])) : createCommentVNode("v-if", true)])) : createCommentVNode("v-if", true),
1061
- createCommentVNode(" 图表容器 "),
1062
- createElementVNode("div", {
1063
- ref_key: "containerRef",
1064
- ref: containerRef,
1065
- class: "graph-container"
1066
- }, null, 512),
1067
- createCommentVNode(" 表编辑器 "),
1068
- createVNode(ERTableEditor_default, {
1069
- show: showEditor.value,
1070
- "editing-table": editingTable.value,
1071
- "onUpdate:editingTable": _cache[1] || (_cache[1] = ($event) => editingTable.value = $event),
1072
- "onUpdate:show": _cache[2] || (_cache[2] = ($event) => showEditor.value = $event),
1073
- onSave: saveTable,
1074
- onAddField: addField,
1075
- onRemoveField: removeField,
1076
- onHandlePrimaryKey: handlePrimaryKey
1077
- }, null, 8, ["show", "editing-table"])
1078
- ]);
1079
- };
1080
- }
1081
- });
1082
-
1083
- //#endregion
1084
- //#region src/components/C_AntV/layout/ER/index.vue
1085
- var ER_default = /* @__PURE__ */ export_helper_default(index_vue_vue_type_script_setup_true_lang_default$3, [["__scopeId", "data-v-20072687"]]);
1086
-
1087
- //#endregion
1088
- //#region src/components/C_AntV/composables/useEdgeInteraction.ts
1089
- const DEFAULT_OPTIONS = {
1090
- defaultColor: "#A2B1C3",
1091
- highlightColor: "#ff4d4f",
1092
- strokeWidth: 2,
1093
- highlightStrokeWidth: 3,
1094
- portPositions: [],
1095
- onDataChange: () => {}
1096
- };
1097
- /**
1098
- * 图表交互 composable — 统一管理连线点击/高亮/删除 + 端口显隐
1099
- * @param graph - X6 Graph 实例引用
1100
- * @param options - 交互配置
1101
- */
1102
- function useEdgeInteraction(graph, options = {}) {
1103
- const config = {
1104
- ...DEFAULT_OPTIONS,
1105
- ...options
1106
- };
1107
- /** 重置所有连线颜色 */
1108
- const resetEdgeStyles = () => {
1109
- graph.value?.getEdges().forEach((edge) => {
1110
- edge.attr("line/stroke", config.defaultColor);
1111
- edge.attr("line/strokeWidth", config.strokeWidth);
1112
- });
1113
- };
1114
- /** 高亮指定连线 */
1115
- const highlightEdge = (edge) => {
1116
- resetEdgeStyles();
1117
- edge.attr("line/stroke", config.highlightColor);
1118
- edge.attr("line/strokeWidth", config.highlightStrokeWidth);
1119
- };
1120
- /** 切换端口可见性 */
1121
- const togglePorts = (node, opacity) => {
1122
- config.portPositions.forEach((pos) => node.attr(`port-${pos}/style/opacity`, opacity));
1123
- };
1124
- /**
1125
- * 绑定标准交互事件到 graph 实例
1126
- * - edge:click → 高亮
1127
- * - edge:dblclick → 删除
1128
- * - blank:click / node:click → 重置颜色
1129
- * - node:mouseenter / mouseleave → 端口显隐(如配置了 portPositions)
1130
- */
1131
- const bindInteractions = () => {
1132
- const g = graph.value;
1133
- if (!g) return;
1134
- g.on("edge:click", ({ edge }) => highlightEdge(edge));
1135
- g.on("edge:dblclick", ({ edge }) => {
1136
- edge.remove();
1137
- config.onDataChange();
1138
- });
1139
- g.on("blank:click", resetEdgeStyles);
1140
- g.on("node:click", resetEdgeStyles);
1141
- g.on("edge:connected", config.onDataChange);
1142
- if (config.portPositions.length > 0) {
1143
- g.on("node:mouseenter", ({ node }) => togglePorts(node, 1));
1144
- g.on("node:mouseleave", ({ node }) => togglePorts(node, 0));
1145
- }
1146
- };
1147
- return {
1148
- resetEdgeStyles,
1149
- highlightEdge,
1150
- togglePorts,
1151
- bindInteractions
1152
- };
1153
- }
1154
-
1155
- //#endregion
1156
- //#region src/components/C_AntV/layout/BPMN/data.ts
1157
- const elementTypes = {
1158
- "start-event": {
1159
- name: "开始",
1160
- title: "开始事件",
1161
- iconClass: "circle start-event"
1162
- },
1163
- activity: {
1164
- name: "任务",
1165
- title: "任务活动",
1166
- iconClass: "rect activity"
1167
- },
1168
- gateway: {
1169
- name: "网关",
1170
- title: "排他网关",
1171
- iconClass: "diamond gateway"
1172
- },
1173
- "end-event": {
1174
- name: "结束",
1175
- title: "结束事件",
1176
- iconClass: "circle end-event"
1177
- }
1178
- };
1179
- const elementTypeNames = {
1180
- event: "事件",
1181
- activity: "活动",
1182
- gateway: "网关",
1183
- "bpmn-edge": "连接线"
1184
- };
1185
- const portPositions = [
1186
- "top",
1187
- "right",
1188
- "bottom",
1189
- "left"
1190
- ];
1191
- const createPortAttrs = (positions, nodeType = "rect") => positions.reduce((acc, pos) => {
1192
- const isCircle = nodeType === "circle";
1193
- const refConfig = pos === "top" ? isCircle ? {
1194
- refCx: .5,
1195
- refCy: 0
1196
- } : {
1197
- refX: .5,
1198
- refY: 0
1199
- } : pos === "right" ? isCircle ? {
1200
- refCx: 1,
1201
- refCy: .5
1202
- } : {
1203
- refX: 1,
1204
- refY: .5
1205
- } : pos === "bottom" ? isCircle ? {
1206
- refCx: .5,
1207
- refCy: 1
1208
- } : {
1209
- refX: .5,
1210
- refY: 1
1211
- } : isCircle ? {
1212
- refCx: 0,
1213
- refCy: .5
1214
- } : {
1215
- refX: 0,
1216
- refY: .5
1217
- };
1218
- acc[`port-${pos}`] = {
1219
- ref: "body",
1220
- ...refConfig,
1221
- r: 4,
1222
- fill: "#31d0c6",
1223
- stroke: "#ffffff",
1224
- strokeWidth: 2,
1225
- magnet: true,
1226
- style: {
1227
- cursor: "crosshair",
1228
- opacity: 0,
1229
- transition: "opacity 0.2s"
1230
- }
1231
- };
1232
- return acc;
1233
- }, {});
1234
- const nodeConfigs = {
1235
- event: {
1236
- inherit: "circle",
1237
- attrs: {
1238
- body: {
1239
- strokeWidth: 2,
1240
- stroke: "#5F95FF",
1241
- fill: "#FFF",
1242
- magnet: false,
1243
- style: { cursor: "move" }
1244
- },
1245
- text: {
1246
- fontSize: 12,
1247
- fill: "#262626",
1248
- textAnchor: "middle",
1249
- textVerticalAnchor: "middle",
1250
- pointerEvents: "none"
1251
- }
1252
- }
1253
- },
1254
- activity: {
1255
- inherit: "rect",
1256
- attrs: {
1257
- body: {
1258
- rx: 6,
1259
- ry: 6,
1260
- stroke: "#5F95FF",
1261
- fill: "#EFF4FF",
1262
- strokeWidth: 1,
1263
- magnet: false,
1264
- style: { cursor: "move" }
1265
- },
1266
- text: {
1267
- fontSize: 12,
1268
- fill: "#262626",
1269
- textAnchor: "middle",
1270
- textVerticalAnchor: "middle",
1271
- pointerEvents: "none"
1272
- }
1273
- }
1274
- },
1275
- gateway: {
1276
- inherit: "polygon",
1277
- attrs: {
1278
- body: {
1279
- refPoints: "0,10 10,0 20,10 10,20",
1280
- strokeWidth: 2,
1281
- stroke: "#5F95FF",
1282
- fill: "#EFF4FF",
1283
- magnet: false,
1284
- style: { cursor: "move" }
1285
- },
1286
- text: {
1287
- fontSize: 20,
1288
- fill: "#5F95FF",
1289
- textAnchor: "middle",
1290
- textVerticalAnchor: "middle",
1291
- pointerEvents: "none"
1292
- }
1293
- }
1294
- }
1295
- };
1296
- const edgeConfig = {
1297
- inherit: "edge",
1298
- attrs: { line: {
1299
- stroke: "#A2B1C3",
1300
- strokeWidth: 2,
1301
- targetMarker: {
1302
- name: "block",
1303
- width: 8,
1304
- height: 6,
1305
- fill: "#A2B1C3"
1306
- },
1307
- cursor: "pointer"
1308
- } }
1309
- };
1310
- /**
1311
- * 获取图形配置(支持主题切换)
1312
- * @param isDark 是否为暗色主题
1313
- * @returns Graph配置对象
1314
- */
1315
- function getGraphConfig(isDark = false) {
1316
- const themeColors = {
1317
- background: isDark ? "#18181c" : "#ffffff",
1318
- gridPrimary: isDark ? "rgba(255, 255, 255, 0.08)" : "#eee",
1319
- gridSecondary: isDark ? "rgba(255, 255, 255, 0.04)" : "#ddd"
1320
- };
1321
- return {
1322
- background: { color: themeColors.background },
1323
- grid: {
1324
- visible: true,
1325
- type: "doubleMesh",
1326
- args: [{
1327
- color: themeColors.gridPrimary,
1328
- thickness: 1
1329
- }, {
1330
- color: themeColors.gridSecondary,
1331
- thickness: 1,
1332
- factor: 4
1333
- }]
1334
- },
1335
- mousewheel: {
1336
- enabled: true,
1337
- zoomAtMousePosition: true,
1338
- modifiers: "ctrl",
1339
- minScale: .5,
1340
- maxScale: 3
1341
- },
1342
- connecting: {
1343
- router: "manhattan",
1344
- connector: {
1345
- name: "rounded",
1346
- args: { radius: 8 }
1347
- },
1348
- allowBlank: false,
1349
- allowLoop: false,
1350
- allowNode: false,
1351
- snap: true,
1352
- allowEdge: false
1353
- },
1354
- highlighting: {
1355
- magnetAvailable: {
1356
- name: "stroke",
1357
- args: { attrs: {
1358
- fill: "#31d0c6",
1359
- stroke: "#31d0c6",
1360
- opacity: 1
1361
- } }
1362
- },
1363
- magnetAdsorbed: {
1364
- name: "stroke",
1365
- args: { attrs: {
1366
- fill: "#5F95FF",
1367
- stroke: "#5F95FF",
1368
- opacity: 1
1369
- } }
1370
- }
1371
- },
1372
- selecting: {
1373
- enabled: true,
1374
- rubberband: true,
1375
- showNodeSelectionBox: true
1376
- },
1377
- resizing: true,
1378
- rotating: false,
1379
- snapline: true,
1380
- keyboard: true,
1381
- clipboard: true
1382
- };
1383
- }
1384
- const graphConfig = getGraphConfig();
1385
- const addElementConfigs = {
1386
- "start-event": {
1387
- shape: "event",
1388
- width: 50,
1389
- height: 50,
1390
- label: "开始事件",
1391
- data: { type: "start" }
1392
- },
1393
- "end-event": {
1394
- shape: "event",
1395
- width: 50,
1396
- height: 50,
1397
- label: "结束事件",
1398
- data: { type: "end" }
1399
- },
1400
- activity: {
1401
- shape: "activity",
1402
- width: 120,
1403
- height: 60,
1404
- label: "新活动",
1405
- data: {
1406
- description: "",
1407
- assignee: ""
1408
- }
1409
- },
1410
- gateway: {
1411
- shape: "gateway",
1412
- width: 40,
1413
- height: 40,
1414
- label: "+",
1415
- data: { type: "exclusive" }
1416
- }
1417
- };
1418
- const sampleData = [
1419
- {
1420
- id: "start-1",
1421
- shape: "event",
1422
- x: 100,
1423
- y: 200,
1424
- width: 50,
1425
- height: 50,
1426
- label: "流程开始",
1427
- data: { type: "start" }
1428
- },
1429
- {
1430
- id: "activity-1",
1431
- shape: "activity",
1432
- x: 200,
1433
- y: 180,
1434
- width: 120,
1435
- height: 60,
1436
- label: "用户申请",
1437
- data: {
1438
- description: "用户提交申请表单",
1439
- assignee: "申请人"
1440
- }
1441
- },
1442
- {
1443
- id: "activity-2",
1444
- shape: "activity",
1445
- x: 380,
1446
- y: 180,
1447
- width: 120,
1448
- height: 60,
1449
- label: "初审",
1450
- data: {
1451
- description: "部门进行初步审核",
1452
- assignee: "部门主管"
1453
- }
1454
- },
1455
- {
1456
- id: "gateway-1",
1457
- shape: "gateway",
1458
- x: 550,
1459
- y: 200,
1460
- width: 40,
1461
- height: 40,
1462
- label: "+",
1463
- data: { type: "exclusive" }
1464
- },
1465
- {
1466
- id: "activity-3",
1467
- shape: "activity",
1468
- x: 650,
1469
- y: 120,
1470
- width: 120,
1471
- height: 60,
1472
- label: "终审",
1473
- data: {
1474
- description: "高级主管最终审核",
1475
- assignee: "总监"
1476
- }
1477
- },
1478
- {
1479
- id: "activity-4",
1480
- shape: "activity",
1481
- x: 650,
1482
- y: 260,
1483
- width: 120,
1484
- height: 60,
1485
- label: "驳回处理",
1486
- data: {
1487
- description: "处理驳回流程",
1488
- assignee: "专员"
1489
- }
1490
- },
1491
- {
1492
- id: "end-1",
1493
- shape: "event",
1494
- x: 820,
1495
- y: 140,
1496
- width: 50,
1497
- height: 50,
1498
- label: "审批通过",
1499
- data: { type: "end" }
1500
- },
1501
- {
1502
- id: "end-2",
1503
- shape: "event",
1504
- x: 820,
1505
- y: 280,
1506
- width: 50,
1507
- height: 50,
1508
- label: "审批驳回",
1509
- data: { type: "end" }
1510
- },
1511
- {
1512
- id: "edge-1",
1513
- shape: "bpmn-edge",
1514
- source: "start-1",
1515
- target: "activity-1",
1516
- x: 0,
1517
- y: 0
1518
- },
1519
- {
1520
- id: "edge-2",
1521
- shape: "bpmn-edge",
1522
- source: "activity-1",
1523
- target: "activity-2",
1524
- x: 0,
1525
- y: 0
1526
- },
1527
- {
1528
- id: "edge-3",
1529
- shape: "bpmn-edge",
1530
- source: "activity-2",
1531
- target: "gateway-1",
1532
- x: 0,
1533
- y: 0
1534
- },
1535
- {
1536
- id: "edge-4",
1537
- shape: "bpmn-edge",
1538
- source: "gateway-1",
1539
- target: "activity-3",
1540
- label: "通过",
1541
- x: 0,
1542
- y: 0
1543
- },
1544
- {
1545
- id: "edge-5",
1546
- shape: "bpmn-edge",
1547
- source: "gateway-1",
1548
- target: "activity-4",
1549
- label: "驳回",
1550
- x: 0,
1551
- y: 0
1552
- },
1553
- {
1554
- id: "edge-6",
1555
- shape: "bpmn-edge",
1556
- source: "activity-3",
1557
- target: "end-1",
1558
- x: 0,
1559
- y: 0
1560
- },
1561
- {
1562
- id: "edge-7",
1563
- shape: "bpmn-edge",
1564
- source: "activity-4",
1565
- target: "end-2",
1566
- x: 0,
1567
- y: 0
1568
- }
1569
- ];
1570
-
1571
- //#endregion
1572
- //#region src/components/C_AntV/layout/BPMN/components/BPMNPropertyEditor.vue?vue&type=script&setup=true&lang.ts
1573
- const _hoisted_1$4 = {
1574
- key: 0,
1575
- class: "property-panel"
1576
- };
1577
- const _hoisted_2$3 = { class: "property-item" };
1578
- const _hoisted_3$2 = { class: "property-item" };
1579
- const _hoisted_4$2 = {
1580
- key: 0,
1581
- class: "property-item"
1582
- };
1583
- const _hoisted_5$2 = {
1584
- key: 1,
1585
- class: "property-item"
1586
- };
1587
- const _hoisted_6$2 = { class: "form-actions" };
1588
- var BPMNPropertyEditor_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
1589
- __name: "BPMNPropertyEditor",
1590
- props: /* @__PURE__ */ mergeModels({ show: { type: Boolean } }, {
1591
- "editingElement": {},
1592
- "editingElementModifiers": {}
1593
- }),
1594
- emits: /* @__PURE__ */ mergeModels([
1595
- "update:show",
1596
- "save",
1597
- "delete"
1598
- ], ["update:editingElement"]),
1599
- setup(__props, { emit: __emit }) {
1600
- const editingElement = useModel(__props, "editingElement");
1601
- const emit = __emit;
1602
- const typeName = computed(() => elementTypeNames[editingElement.value?.shape] || editingElement.value?.shape || "");
1603
- return (_ctx, _cache) => {
1604
- return openBlock(), createBlock(unref(NDrawer), {
1605
- show: _ctx.show,
1606
- width: "300",
1607
- title: "属性设置",
1608
- "onUpdate:show": _cache[6] || (_cache[6] = ($event) => emit("update:show", $event))
1609
- }, {
1610
- default: withCtx(() => [editingElement.value ? (openBlock(), createElementBlock("div", _hoisted_1$4, [
1611
- createElementVNode("div", _hoisted_2$3, [_cache[7] || (_cache[7] = createElementVNode("div", { class: "property-label" }, "名称", -1)), createVNode(unref(NInput), {
1612
- value: editingElement.value.label,
1613
- "onUpdate:value": _cache[0] || (_cache[0] = ($event) => editingElement.value.label = $event),
1614
- placeholder: "请输入名称",
1615
- size: "small"
1616
- }, null, 8, ["value"])]),
1617
- createElementVNode("div", _hoisted_3$2, [_cache[8] || (_cache[8] = createElementVNode("div", { class: "property-label" }, "类型", -1)), createVNode(unref(NInput), {
1618
- value: typeName.value,
1619
- readonly: "",
1620
- size: "small"
1621
- }, null, 8, ["value"])]),
1622
- editingElement.value.shape === "activity" ? (openBlock(), createElementBlock("div", _hoisted_4$2, [_cache[9] || (_cache[9] = createElementVNode("div", { class: "property-label" }, "描述", -1)), createVNode(unref(NInput), {
1623
- value: editingElement.value.description,
1624
- "onUpdate:value": _cache[1] || (_cache[1] = ($event) => editingElement.value.description = $event),
1625
- type: "textarea",
1626
- rows: 3,
1627
- placeholder: "请输入活动描述",
1628
- size: "small"
1629
- }, null, 8, ["value"])])) : createCommentVNode("v-if", true),
1630
- editingElement.value.shape === "activity" ? (openBlock(), createElementBlock("div", _hoisted_5$2, [_cache[10] || (_cache[10] = createElementVNode("div", { class: "property-label" }, "执行人", -1)), createVNode(unref(NInput), {
1631
- value: editingElement.value.assignee,
1632
- "onUpdate:value": _cache[2] || (_cache[2] = ($event) => editingElement.value.assignee = $event),
1633
- placeholder: "请输入执行人",
1634
- size: "small"
1635
- }, null, 8, ["value"])])) : createCommentVNode("v-if", true),
1636
- createElementVNode("div", _hoisted_6$2, [createVNode(unref(NSpace), null, {
1637
- default: withCtx(() => [
1638
- createVNode(unref(NButton), {
1639
- onClick: _cache[3] || (_cache[3] = ($event) => emit("save")),
1640
- type: "primary",
1641
- size: "small"
1642
- }, {
1643
- default: withCtx(() => _cache[11] || (_cache[11] = [createTextVNode(" 保存 ", -1)])),
1644
- _: 1,
1645
- __: [11]
1646
- }),
1647
- createVNode(unref(NButton), {
1648
- onClick: _cache[4] || (_cache[4] = ($event) => emit("update:show", false)),
1649
- size: "small"
1650
- }, {
1651
- default: withCtx(() => _cache[12] || (_cache[12] = [createTextVNode(" 取消 ", -1)])),
1652
- _: 1,
1653
- __: [12]
1654
- }),
1655
- createVNode(unref(NButton), {
1656
- onClick: _cache[5] || (_cache[5] = ($event) => emit("delete")),
1657
- type: "error",
1658
- size: "small"
1659
- }, {
1660
- default: withCtx(() => _cache[13] || (_cache[13] = [createTextVNode(" 删除 ", -1)])),
1661
- _: 1,
1662
- __: [13]
1663
- })
1664
- ]),
1665
- _: 1
1666
- })])
1667
- ])) : createCommentVNode("v-if", true)]),
1668
- _: 1
1669
- }, 8, ["show"]);
1670
- };
1671
- }
1672
- });
1673
-
1674
- //#endregion
1675
- //#region src/components/C_AntV/layout/BPMN/components/BPMNPropertyEditor.vue
1676
- var BPMNPropertyEditor_default = BPMNPropertyEditor_vue_vue_type_script_setup_true_lang_default;
1677
-
1678
- //#endregion
1679
- //#region src/components/C_AntV/layout/BPMN/index.vue?vue&type=script&setup=true&lang.ts
1680
- const _hoisted_1$3 = { class: "bpmn-layout" };
1681
- const _hoisted_2$2 = {
1682
- key: 0,
1683
- class: "top-toolbar"
1684
- };
1685
- const _hoisted_3$1 = { class: "toolbar-section" };
1686
- const _hoisted_4$1 = { class: "toolbar-group" };
1687
- const _hoisted_5$1 = { class: "toolbar-group" };
1688
- const _hoisted_6$1 = { class: "toolbar-group" };
1689
- const _hoisted_7$1 = { class: "main-content" };
1690
- const _hoisted_8 = {
1691
- key: 0,
1692
- class: "left-panel"
1693
- };
1694
- const _hoisted_9 = { class: "element-grid" };
1695
- const _hoisted_10 = ["onClick", "title"];
1696
- const _hoisted_11 = { class: "graph-wrapper" };
1697
- var index_vue_vue_type_script_setup_true_lang_default$2 = /* @__PURE__ */ defineComponent({
1698
- __name: "index",
1699
- props: {
1700
- data: {},
1701
- showToolbar: {
1702
- type: Boolean,
1703
- default: true
1704
- },
1705
- readonly: {
1706
- type: Boolean,
1707
- default: false
1708
- },
1709
- width: { default: "100%" },
1710
- height: { default: "600px" },
1711
- theme: {}
1712
- },
1713
- emits: ["ready", "data-change"],
1714
- setup(__props, { expose: __expose, emit: __emit }) {
1715
- const props = __props;
1716
- const emit = __emit;
1717
- const containerRef = ref();
1718
- const { graph, initGraph, centerContent, zoomToFit } = useGraphBase(containerRef, computed(() => props.theme === "dark"));
1719
- const { exportOptions, handleExport } = useGraphExport(graph, "bpmn-diagram");
1720
- const { bindInteractions } = useEdgeInteraction(graph, {
1721
- portPositions,
1722
- onDataChange: () => emitDataChange()
1723
- });
1724
- const showEditor = ref(false);
1725
- const editingElement = ref();
1726
- const getLabel = (cell) => String(cell.attr("text/text") || cell.attr("label/text") || "");
1727
- const normalizeData = (data) => {
1728
- if (!data) return [];
1729
- if (Array.isArray(data)) return data;
1730
- const result = [];
1731
- Object.values(data).forEach((arr) => {
1732
- if (Array.isArray(arr)) result.push(...arr);
1733
- });
1734
- return result;
1735
- };
1736
- const registerNodes = () => {
1737
- const portMarkup = portPositions.map((pos) => ({
1738
- tagName: "circle",
1739
- selector: `port-${pos}`
1740
- }));
1741
- const nodeTypes = [
1742
- "event",
1743
- "activity",
1744
- "gateway"
1745
- ];
1746
- const bodyTags = {
1747
- event: "circle",
1748
- activity: "rect",
1749
- gateway: "polygon"
1750
- };
1751
- nodeTypes.forEach((type) => {
1752
- Graph.registerNode(type, {
1753
- ...nodeConfigs[type],
1754
- markup: [
1755
- {
1756
- tagName: bodyTags[type],
1757
- selector: "body"
1758
- },
1759
- {
1760
- tagName: "text",
1761
- selector: "text"
1762
- },
1763
- ...portMarkup
1764
- ],
1765
- attrs: {
1766
- ...nodeConfigs[type].attrs,
1767
- ...createPortAttrs(portPositions, bodyTags[type])
1768
- }
1769
- }, true);
1770
- });
1771
- Graph.registerEdge("bpmn-edge", edgeConfig, true);
1772
- };
1773
- const loadData = (data) => {
1774
- if (!graph.value || !data.length) return;
1775
- const cells = data.map((item) => {
1776
- const { data: nodeData, ...cellProps } = item;
1777
- const cell = item.shape === "bpmn-edge" ? graph.value.createEdge(cellProps) : graph.value.createNode(cellProps);
1778
- if (nodeData) cell.setData(nodeData);
1779
- return cell;
1780
- });
1781
- graph.value.resetCells(cells);
1782
- setTimeout(() => graph.value.zoomToFit({
1783
- padding: 50,
1784
- maxScale: 1
1785
- }), 200);
1786
- };
1787
- const addElement = (type) => {
1788
- if (!graph.value) return;
1789
- const config = addElementConfigs[type];
1790
- if (!config) return;
1791
- const centerX = graph.value.options.width / 2;
1792
- const centerY = graph.value.options.height / 2;
1793
- const { data: nodeData, ...nodeProps } = {
1794
- id: `${type}-${Date.now()}`,
1795
- x: centerX + Math.random() * 100 - 50,
1796
- y: centerY + Math.random() * 100 - 50,
1797
- ...config
1798
- };
1799
- const node = graph.value.createNode(nodeProps);
1800
- if (nodeData) node.setData(nodeData);
1801
- graph.value.addCell(node);
1802
- emitDataChange();
1803
- };
1804
- const clearAll = () => {
1805
- graph.value?.clearCells();
1806
- emitDataChange();
1807
- };
1808
- const editElement = (cell) => {
1809
- const cellData = cell.getData() || {};
1810
- editingElement.value = {
1811
- id: cell.id,
1812
- shape: cell.shape,
1813
- label: getLabel(cell),
1814
- description: cellData.description || "",
1815
- assignee: cellData.assignee || "",
1816
- x: 0,
1817
- y: 0
1818
- };
1819
- showEditor.value = true;
1820
- };
1821
- const saveElement = () => {
1822
- if (!graph.value || !editingElement.value) return;
1823
- const cell = graph.value.getCellById(editingElement.value.id);
1824
- if (cell) {
1825
- cell.setData({
1826
- description: editingElement.value.description,
1827
- assignee: editingElement.value.assignee
1828
- });
1829
- cell.attr("text/text", editingElement.value.label || "");
1830
- cell.attr("label/text", editingElement.value.label || "");
1831
- }
1832
- showEditor.value = false;
1833
- emitDataChange();
1834
- };
1835
- const deleteElement = () => {
1836
- if (!graph.value || !editingElement.value) return;
1837
- graph.value.getCellById(editingElement.value.id)?.remove();
1838
- showEditor.value = false;
1839
- emitDataChange();
1840
- };
1841
- const getCurrentData = () => {
1842
- if (!graph.value) return [];
1843
- return [...graph.value.getNodes().map((node) => ({
1844
- id: node.id,
1845
- shape: node.shape,
1846
- x: node.getPosition().x,
1847
- y: node.getPosition().y,
1848
- width: node.getSize().width,
1849
- height: node.getSize().height,
1850
- label: getLabel(node),
1851
- data: node.getData() || {}
1852
- })), ...graph.value.getEdges().map((edge) => ({
1853
- id: edge.id,
1854
- shape: "bpmn-edge",
1855
- source: edge.getSourceCellId() || "",
1856
- target: edge.getTargetCellId() || "",
1857
- label: getLabel(edge),
1858
- x: 0,
1859
- y: 0
1860
- }))];
1861
- };
1862
- const emitDataChange = () => emit("data-change", getCurrentData());
1863
- watch(graph, (newGraph) => {
1864
- if (!(newGraph instanceof Graph)) return;
1865
- if (!props.readonly) {
1866
- bindInteractions();
1867
- newGraph.on("node:dblclick", ({ node }) => editElement(node));
1868
- newGraph.on("node:moved", emitDataChange);
1869
- }
1870
- emit("ready", newGraph);
1871
- loadData(sampleData);
1872
- }, { immediate: true });
1873
- watch(() => props.data, (newData) => {
1874
- if (!newData || !graph.value) return;
1875
- const normalized = normalizeData(newData);
1876
- if (normalized.length > 0) loadData(normalized);
1877
- }, { deep: true });
1878
- onMounted(async () => {
1879
- registerNodes();
1880
- const bpmnConfig = getGraphConfig();
1881
- await initGraph({
1882
- ...bpmnConfig,
1883
- connecting: {
1884
- ...bpmnConfig.connecting,
1885
- createEdge: () => graph.value.createEdge({ shape: "bpmn-edge" }),
1886
- validateConnection: ({ sourceView, targetView, sourceMagnet, targetMagnet }) => sourceView !== targetView && !!sourceMagnet && !!targetMagnet && sourceMagnet.getAttribute("magnet") === "true" && targetMagnet.getAttribute("magnet") === "true"
1887
- }
1888
- });
1889
- });
1890
- __expose({
1891
- getGraph: () => graph.value,
1892
- getData: getCurrentData,
1893
- loadData
1894
- });
1895
- return (_ctx, _cache) => {
1896
- return openBlock(), createElementBlock("div", _hoisted_1$3, [
1897
- _ctx.showToolbar ? (openBlock(), createElementBlock("div", _hoisted_2$2, [createElementVNode("div", _hoisted_3$1, [
1898
- createElementVNode("div", _hoisted_4$1, [createVNode(unref(NButton), {
1899
- onClick: clearAll,
1900
- size: "small"
1901
- }, {
1902
- icon: withCtx(() => [createVNode(C_Icon_default, {
1903
- name: "mdi:delete-outline",
1904
- size: 16
1905
- })]),
1906
- default: withCtx(() => [_cache[3] || (_cache[3] = createTextVNode(" 清空 ", -1))]),
1907
- _: 1,
1908
- __: [3]
1909
- })]),
1910
- createElementVNode("div", _hoisted_5$1, [createVNode(unref(NButton), {
1911
- onClick: unref(centerContent),
1912
- size: "small"
1913
- }, {
1914
- icon: withCtx(() => [createVNode(C_Icon_default, {
1915
- name: "mdi:image-filter-center-focus",
1916
- size: 16
1917
- })]),
1918
- default: withCtx(() => [_cache[4] || (_cache[4] = createTextVNode(" 居中 ", -1))]),
1919
- _: 1,
1920
- __: [4]
1921
- }, 8, ["onClick"]), createVNode(unref(NButton), {
1922
- onClick: unref(zoomToFit),
1923
- size: "small"
1924
- }, {
1925
- icon: withCtx(() => [createVNode(C_Icon_default, {
1926
- name: "mdi:fit-to-screen",
1927
- size: 16
1928
- })]),
1929
- default: withCtx(() => [_cache[5] || (_cache[5] = createTextVNode(" 适应 ", -1))]),
1930
- _: 1,
1931
- __: [5]
1932
- }, 8, ["onClick"])]),
1933
- createElementVNode("div", _hoisted_6$1, [createVNode(unref(NDropdown), {
1934
- options: unref(exportOptions),
1935
- onSelect: _cache[0] || (_cache[0] = (key) => unref(handleExport)(key, getCurrentData))
1936
- }, {
1937
- default: withCtx(() => [createVNode(unref(NButton), { size: "small" }, {
1938
- icon: withCtx(() => [createVNode(C_Icon_default, {
1939
- name: "mdi:export",
1940
- size: 16
1941
- })]),
1942
- default: withCtx(() => [_cache[6] || (_cache[6] = createTextVNode(" 导出 ", -1))]),
1943
- _: 1,
1944
- __: [6]
1945
- })]),
1946
- _: 1
1947
- }, 8, ["options"])])
1948
- ])])) : createCommentVNode("v-if", true),
1949
- createElementVNode("div", _hoisted_7$1, [_ctx.showToolbar ? (openBlock(), createElementBlock("div", _hoisted_8, [_cache[7] || (_cache[7] = createElementVNode("div", { class: "panel-title" }, "组件", -1)), createElementVNode("div", _hoisted_9, [(openBlock(true), createElementBlock(Fragment, null, renderList(unref(elementTypes), (item, key) => {
1950
- return openBlock(), createElementBlock("div", {
1951
- key,
1952
- class: "element-item",
1953
- onClick: ($event) => addElement(key),
1954
- title: item.title
1955
- }, [createElementVNode("div", { class: normalizeClass(["element-icon", item.iconClass]) }, null, 2), createElementVNode("span", null, toDisplayString(item.name), 1)], 8, _hoisted_10);
1956
- }), 128))])])) : createCommentVNode("v-if", true), createElementVNode("div", _hoisted_11, [createElementVNode("div", {
1957
- ref_key: "containerRef",
1958
- ref: containerRef,
1959
- class: "graph-container"
1960
- }, null, 512)])]),
1961
- createVNode(BPMNPropertyEditor_default, {
1962
- show: showEditor.value,
1963
- "editing-element": editingElement.value,
1964
- "onUpdate:editingElement": _cache[1] || (_cache[1] = ($event) => editingElement.value = $event),
1965
- "onUpdate:show": _cache[2] || (_cache[2] = ($event) => showEditor.value = $event),
1966
- onSave: saveElement,
1967
- onDelete: deleteElement
1968
- }, null, 8, ["show", "editing-element"])
1969
- ]);
1970
- };
1971
- }
1972
- });
1973
-
1974
- //#endregion
1975
- //#region src/components/C_AntV/layout/BPMN/index.vue
1976
- var BPMN_default = /* @__PURE__ */ export_helper_default(index_vue_vue_type_script_setup_true_lang_default$2, [["__scopeId", "data-v-6bf4e129"]]);
1977
-
1978
- //#endregion
1979
- //#region src/components/C_AntV/layout/UML/components/UMLClassEditor.vue?vue&type=script&setup=true&lang.ts
1980
- const _hoisted_1$2 = {
1981
- key: 0,
1982
- class: "class-editor"
1983
- };
1984
- const _hoisted_2$1 = { class: "section" };
1985
- const _hoisted_3 = { class: "section-header" };
1986
- const _hoisted_4 = { style: { "font-size": "13px" } };
1987
- const _hoisted_5 = { class: "section" };
1988
- const _hoisted_6 = { class: "section-header" };
1989
- const _hoisted_7 = { style: { "font-size": "13px" } };
1990
- var UMLClassEditor_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
1991
- __name: "UMLClassEditor",
1992
- props: /* @__PURE__ */ mergeModels({ show: { type: Boolean } }, {
1993
- "editingClass": {},
1994
- "editingClassModifiers": {}
1995
- }),
1996
- emits: /* @__PURE__ */ mergeModels([
1997
- "update:show",
1998
- "save",
1999
- "delete"
2000
- ], ["update:editingClass"]),
2001
- setup(__props, { emit: __emit }) {
2002
- const editingClass = useModel(__props, "editingClass");
2003
- const emit = __emit;
2004
- return (_ctx, _cache) => {
2005
- return openBlock(), createBlock(unref(NDrawer), {
2006
- show: _ctx.show,
2007
- width: "450",
2008
- title: "编辑类",
2009
- "onUpdate:show": _cache[6] || (_cache[6] = ($event) => emit("update:show", $event))
2010
- }, {
2011
- default: withCtx(() => [editingClass.value ? (openBlock(), createElementBlock("div", _hoisted_1$2, [createVNode(unref(NForm), { "label-placement": "top" }, {
2012
- default: withCtx(() => [
2013
- createVNode(unref(NFormItem), { label: "类名" }, {
2014
- default: withCtx(() => [createVNode(unref(NInput), {
2015
- value: editingClass.value.name,
2016
- "onUpdate:value": _cache[0] || (_cache[0] = ($event) => editingClass.value.name = $event),
2017
- placeholder: "请输入类名"
2018
- }, null, 8, ["value"])]),
2019
- _: 1
2020
- }),
2021
- createVNode(unref(NDivider), { style: { "margin": "20px 0" } }, {
2022
- default: withCtx(() => _cache[7] || (_cache[7] = [createTextVNode("属性", -1)])),
2023
- _: 1,
2024
- __: [7]
2025
- }),
2026
- createElementVNode("div", _hoisted_2$1, [(openBlock(true), createElementBlock(Fragment, null, renderList(editingClass.value.attributes, (attr, index) => {
2027
- return openBlock(), createElementBlock("div", {
2028
- key: index,
2029
- class: "item"
2030
- }, [createVNode(unref(NCard), {
2031
- size: "small",
2032
- style: { "margin-bottom": "12px" }
2033
- }, {
2034
- header: withCtx(() => [createElementVNode("div", _hoisted_3, [createElementVNode("span", _hoisted_4, "#" + toDisplayString(index + 1) + " " + toDisplayString(attr.name || "新属性"), 1), createVNode(unref(NButton), {
2035
- onClick: ($event) => editingClass.value.attributes.splice(index, 1),
2036
- size: "tiny",
2037
- type: "error",
2038
- quaternary: "",
2039
- style: { "margin-left": "auto" }
2040
- }, {
2041
- default: withCtx(() => _cache[8] || (_cache[8] = [createTextVNode(" 删除 ", -1)])),
2042
- _: 2,
2043
- __: [8]
2044
- }, 1032, ["onClick"])])]),
2045
- default: withCtx(() => [createVNode(unref(NSpace), {
2046
- vertical: "",
2047
- size: "small"
2048
- }, {
2049
- default: withCtx(() => [createVNode(unref(NSpace), null, {
2050
- default: withCtx(() => [createVNode(unref(NFormItem), {
2051
- label: "属性名",
2052
- style: {
2053
- "margin": "0",
2054
- "flex": "1"
2055
- }
2056
- }, {
2057
- default: withCtx(() => [createVNode(unref(NInput), {
2058
- value: attr.name,
2059
- "onUpdate:value": ($event) => attr.name = $event,
2060
- placeholder: "属性名",
2061
- size: "small"
2062
- }, null, 8, ["value", "onUpdate:value"])]),
2063
- _: 2
2064
- }, 1024), createVNode(unref(NFormItem), {
2065
- label: "类型",
2066
- style: {
2067
- "margin": "0",
2068
- "flex": "1"
2069
- }
2070
- }, {
2071
- default: withCtx(() => [createVNode(unref(NInput), {
2072
- value: attr.type,
2073
- "onUpdate:value": ($event) => attr.type = $event,
2074
- placeholder: "类型",
2075
- size: "small"
2076
- }, null, 8, ["value", "onUpdate:value"])]),
2077
- _: 2
2078
- }, 1024)]),
2079
- _: 2
2080
- }, 1024), createVNode(unref(NFormItem), {
2081
- label: "可见性",
2082
- style: { "margin": "0" }
2083
- }, {
2084
- default: withCtx(() => [createVNode(unref(NRadioGroup), {
2085
- value: attr.visibility,
2086
- "onUpdate:value": ($event) => attr.visibility = $event,
2087
- size: "small"
2088
- }, {
2089
- default: withCtx(() => [
2090
- createVNode(unref(NRadio), { value: "public" }, {
2091
- default: withCtx(() => _cache[9] || (_cache[9] = [createTextVNode("+ public", -1)])),
2092
- _: 1,
2093
- __: [9]
2094
- }),
2095
- createVNode(unref(NRadio), { value: "private" }, {
2096
- default: withCtx(() => _cache[10] || (_cache[10] = [createTextVNode("- private", -1)])),
2097
- _: 1,
2098
- __: [10]
2099
- }),
2100
- createVNode(unref(NRadio), { value: "protected" }, {
2101
- default: withCtx(() => _cache[11] || (_cache[11] = [createTextVNode("# protected", -1)])),
2102
- _: 1,
2103
- __: [11]
2104
- })
2105
- ]),
2106
- _: 2
2107
- }, 1032, ["value", "onUpdate:value"])]),
2108
- _: 2
2109
- }, 1024)]),
2110
- _: 2
2111
- }, 1024)]),
2112
- _: 2
2113
- }, 1024)]);
2114
- }), 128)), createVNode(unref(NButton), {
2115
- onClick: _cache[1] || (_cache[1] = ($event) => editingClass.value.attributes.push({
2116
- name: "newAttribute",
2117
- type: "string",
2118
- visibility: "private"
2119
- })),
2120
- dashed: "",
2121
- block: "",
2122
- type: "primary",
2123
- ghost: "",
2124
- size: "small"
2125
- }, {
2126
- icon: withCtx(() => [createVNode(C_Icon_default, {
2127
- name: "mdi:plus",
2128
- size: 16
2129
- })]),
2130
- default: withCtx(() => [_cache[12] || (_cache[12] = createTextVNode(" 添加属性 ", -1))]),
2131
- _: 1,
2132
- __: [12]
2133
- })]),
2134
- createVNode(unref(NDivider), { style: { "margin": "20px 0" } }, {
2135
- default: withCtx(() => _cache[13] || (_cache[13] = [createTextVNode("方法", -1)])),
2136
- _: 1,
2137
- __: [13]
2138
- }),
2139
- createElementVNode("div", _hoisted_5, [(openBlock(true), createElementBlock(Fragment, null, renderList(editingClass.value.methods, (method, index) => {
2140
- return openBlock(), createElementBlock("div", {
2141
- key: index,
2142
- class: "item"
2143
- }, [createVNode(unref(NCard), {
2144
- size: "small",
2145
- style: { "margin-bottom": "12px" }
2146
- }, {
2147
- header: withCtx(() => [createElementVNode("div", _hoisted_6, [createElementVNode("span", _hoisted_7, "#" + toDisplayString(index + 1) + " " + toDisplayString(method.name || "新方法"), 1), createVNode(unref(NButton), {
2148
- onClick: ($event) => editingClass.value.methods.splice(index, 1),
2149
- size: "tiny",
2150
- type: "error",
2151
- quaternary: "",
2152
- style: { "margin-left": "auto" }
2153
- }, {
2154
- default: withCtx(() => _cache[14] || (_cache[14] = [createTextVNode(" 删除 ", -1)])),
2155
- _: 2,
2156
- __: [14]
2157
- }, 1032, ["onClick"])])]),
2158
- default: withCtx(() => [createVNode(unref(NSpace), {
2159
- vertical: "",
2160
- size: "small"
2161
- }, {
2162
- default: withCtx(() => [createVNode(unref(NSpace), null, {
2163
- default: withCtx(() => [createVNode(unref(NFormItem), {
2164
- label: "方法名",
2165
- style: {
2166
- "margin": "0",
2167
- "flex": "1"
2168
- }
2169
- }, {
2170
- default: withCtx(() => [createVNode(unref(NInput), {
2171
- value: method.name,
2172
- "onUpdate:value": ($event) => method.name = $event,
2173
- placeholder: "方法名",
2174
- size: "small"
2175
- }, null, 8, ["value", "onUpdate:value"])]),
2176
- _: 2
2177
- }, 1024), createVNode(unref(NFormItem), {
2178
- label: "返回类型",
2179
- style: {
2180
- "margin": "0",
2181
- "flex": "1"
2182
- }
2183
- }, {
2184
- default: withCtx(() => [createVNode(unref(NInput), {
2185
- value: method.returnType,
2186
- "onUpdate:value": ($event) => method.returnType = $event,
2187
- placeholder: "返回类型",
2188
- size: "small"
2189
- }, null, 8, ["value", "onUpdate:value"])]),
2190
- _: 2
2191
- }, 1024)]),
2192
- _: 2
2193
- }, 1024), createVNode(unref(NFormItem), {
2194
- label: "可见性",
2195
- style: { "margin": "0" }
2196
- }, {
2197
- default: withCtx(() => [createVNode(unref(NRadioGroup), {
2198
- value: method.visibility,
2199
- "onUpdate:value": ($event) => method.visibility = $event,
2200
- size: "small"
2201
- }, {
2202
- default: withCtx(() => [
2203
- createVNode(unref(NRadio), { value: "public" }, {
2204
- default: withCtx(() => _cache[15] || (_cache[15] = [createTextVNode("+ public", -1)])),
2205
- _: 1,
2206
- __: [15]
2207
- }),
2208
- createVNode(unref(NRadio), { value: "private" }, {
2209
- default: withCtx(() => _cache[16] || (_cache[16] = [createTextVNode("- private", -1)])),
2210
- _: 1,
2211
- __: [16]
2212
- }),
2213
- createVNode(unref(NRadio), { value: "protected" }, {
2214
- default: withCtx(() => _cache[17] || (_cache[17] = [createTextVNode("# protected", -1)])),
2215
- _: 1,
2216
- __: [17]
2217
- })
2218
- ]),
2219
- _: 2
2220
- }, 1032, ["value", "onUpdate:value"])]),
2221
- _: 2
2222
- }, 1024)]),
2223
- _: 2
2224
- }, 1024)]),
2225
- _: 2
2226
- }, 1024)]);
2227
- }), 128)), createVNode(unref(NButton), {
2228
- onClick: _cache[2] || (_cache[2] = ($event) => editingClass.value.methods.push({
2229
- name: "newMethod",
2230
- returnType: "void",
2231
- visibility: "public"
2232
- })),
2233
- dashed: "",
2234
- block: "",
2235
- type: "primary",
2236
- ghost: "",
2237
- size: "small"
2238
- }, {
2239
- icon: withCtx(() => [createVNode(C_Icon_default, {
2240
- name: "mdi:plus",
2241
- size: 16
2242
- })]),
2243
- default: withCtx(() => [_cache[18] || (_cache[18] = createTextVNode(" 添加方法 ", -1))]),
2244
- _: 1,
2245
- __: [18]
2246
- })]),
2247
- createVNode(unref(NDivider), { style: { "margin": "20px 0" } }),
2248
- createVNode(unref(NSpace), { justify: "space-between" }, {
2249
- default: withCtx(() => [createVNode(unref(NButton), {
2250
- onClick: _cache[3] || (_cache[3] = ($event) => emit("delete")),
2251
- type: "error",
2252
- ghost: ""
2253
- }, {
2254
- icon: withCtx(() => [createVNode(C_Icon_default, {
2255
- name: "mdi:delete",
2256
- size: 16
2257
- })]),
2258
- default: withCtx(() => [_cache[19] || (_cache[19] = createTextVNode(" 删除类 ", -1))]),
2259
- _: 1,
2260
- __: [19]
2261
- }), createVNode(unref(NSpace), null, {
2262
- default: withCtx(() => [createVNode(unref(NButton), { onClick: _cache[4] || (_cache[4] = ($event) => emit("update:show", false)) }, {
2263
- default: withCtx(() => _cache[20] || (_cache[20] = [createTextVNode("取消", -1)])),
2264
- _: 1,
2265
- __: [20]
2266
- }), createVNode(unref(NButton), {
2267
- onClick: _cache[5] || (_cache[5] = ($event) => emit("save")),
2268
- type: "primary"
2269
- }, {
2270
- default: withCtx(() => _cache[21] || (_cache[21] = [createTextVNode(" 保存 ", -1)])),
2271
- _: 1,
2272
- __: [21]
2273
- })]),
2274
- _: 1
2275
- })]),
2276
- _: 1
2277
- })
2278
- ]),
2279
- _: 1
2280
- })])) : createCommentVNode("v-if", true)]),
2281
- _: 1
2282
- }, 8, ["show"]);
2283
- };
2284
- }
2285
- });
2286
-
2287
- //#endregion
2288
- //#region src/components/C_AntV/layout/UML/components/UMLClassEditor.vue
2289
- var UMLClassEditor_default = /* @__PURE__ */ export_helper_default(UMLClassEditor_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-6067ee94"]]);
2290
-
2291
- //#endregion
2292
- //#region src/components/C_AntV/layout/UML/data.ts
2293
- const visibilityMap = {
2294
- public: "+",
2295
- private: "-",
2296
- protected: "#"
2297
- };
2298
- const edgeTypes = {
2299
- extends: {
2300
- strokeDasharray: 0,
2301
- targetMarker: {
2302
- name: "block",
2303
- width: 10,
2304
- height: 8,
2305
- fill: "white",
2306
- stroke: "#722ed1",
2307
- strokeWidth: 2
2308
- }
2309
- },
2310
- implement: {
2311
- strokeDasharray: "8,4",
2312
- targetMarker: {
2313
- name: "block",
2314
- width: 10,
2315
- height: 8,
2316
- fill: "white",
2317
- stroke: "#722ed1",
2318
- strokeWidth: 2
2319
- }
2320
- },
2321
- composition: {
2322
- strokeDasharray: 0,
2323
- sourceMarker: {
2324
- name: "diamond",
2325
- width: 12,
2326
- height: 8,
2327
- fill: "#722ed1",
2328
- stroke: "#722ed1"
2329
- }
2330
- },
2331
- aggregation: {
2332
- strokeDasharray: 0,
2333
- sourceMarker: {
2334
- name: "diamond",
2335
- width: 12,
2336
- height: 8,
2337
- fill: "white",
2338
- stroke: "#722ed1",
2339
- strokeWidth: 2
2340
- }
2341
- },
2342
- association: {
2343
- strokeDasharray: 0,
2344
- targetMarker: {
2345
- name: "classic",
2346
- size: 8,
2347
- fill: "#722ed1"
2348
- }
2349
- }
2350
- };
2351
- const portConfig = [
2352
- "top",
2353
- "right",
2354
- "bottom",
2355
- "left"
2356
- ].reduce((acc, pos) => {
2357
- const refConfig = pos === "top" ? {
2358
- refX: .5,
2359
- refY: 0
2360
- } : pos === "right" ? {
2361
- refX: 1,
2362
- refY: .5
2363
- } : pos === "bottom" ? {
2364
- refX: .5,
2365
- refY: 1
2366
- } : {
2367
- refX: 0,
2368
- refY: .5
2369
- };
2370
- acc[`port-${pos}`] = {
2371
- ref: "body",
2372
- ...refConfig,
2373
- r: 4,
2374
- fill: "#31d0c6",
2375
- stroke: "#ffffff",
2376
- strokeWidth: 2,
2377
- magnet: true,
2378
- style: {
2379
- cursor: "crosshair",
2380
- opacity: 0,
2381
- transition: "opacity 0.2s"
2382
- }
2383
- };
2384
- return acc;
2385
- }, {});
2386
- const classNodeConfig = {
2387
- inherit: "rect",
2388
- markup: [
2389
- {
2390
- tagName: "rect",
2391
- selector: "body"
2392
- },
2393
- {
2394
- tagName: "rect",
2395
- selector: "name-rect"
2396
- },
2397
- {
2398
- tagName: "rect",
2399
- selector: "attrs-rect"
2400
- },
2401
- {
2402
- tagName: "rect",
2403
- selector: "methods-rect"
2404
- },
2405
- {
2406
- tagName: "text",
2407
- selector: "name-text"
2408
- },
2409
- {
2410
- tagName: "text",
2411
- selector: "attrs-text"
2412
- },
2413
- {
2414
- tagName: "text",
2415
- selector: "methods-text"
2416
- },
2417
- {
2418
- tagName: "circle",
2419
- selector: "port-top"
2420
- },
2421
- {
2422
- tagName: "circle",
2423
- selector: "port-right"
2424
- },
2425
- {
2426
- tagName: "circle",
2427
- selector: "port-bottom"
2428
- },
2429
- {
2430
- tagName: "circle",
2431
- selector: "port-left"
2432
- }
2433
- ],
2434
- attrs: {
2435
- rect: { width: 160 },
2436
- body: {
2437
- stroke: "#5f95ff",
2438
- strokeWidth: 1,
2439
- fill: "#fff",
2440
- magnet: false,
2441
- style: { cursor: "move" }
2442
- },
2443
- "name-rect": {
2444
- fill: "#5f95ff",
2445
- stroke: "#fff",
2446
- strokeWidth: .5,
2447
- magnet: false,
2448
- style: { cursor: "move" }
2449
- },
2450
- "attrs-rect": {
2451
- fill: "#eff4ff",
2452
- stroke: "#fff",
2453
- strokeWidth: .5,
2454
- magnet: false,
2455
- style: { cursor: "move" }
2456
- },
2457
- "methods-rect": {
2458
- fill: "#eff4ff",
2459
- stroke: "#fff",
2460
- strokeWidth: .5,
2461
- magnet: false,
2462
- style: { cursor: "move" }
2463
- },
2464
- "name-text": {
2465
- ref: "name-rect",
2466
- refY: .5,
2467
- refX: .5,
2468
- textAnchor: "middle",
2469
- fontWeight: "bold",
2470
- fill: "#fff",
2471
- fontSize: 12,
2472
- pointerEvents: "none"
2473
- },
2474
- "attrs-text": {
2475
- ref: "attrs-rect",
2476
- refY: .5,
2477
- refX: 5,
2478
- textAnchor: "left",
2479
- fill: "black",
2480
- fontSize: 10,
2481
- pointerEvents: "none"
2482
- },
2483
- "methods-text": {
2484
- ref: "methods-rect",
2485
- refY: .5,
2486
- refX: 5,
2487
- textAnchor: "left",
2488
- fill: "black",
2489
- fontSize: 10,
2490
- pointerEvents: "none"
2491
- },
2492
- ...portConfig
2493
- }
2494
- };
2495
- const connectingConfig = {
2496
- router: "manhattan",
2497
- connector: {
2498
- name: "rounded",
2499
- args: { radius: 8 }
2500
- },
2501
- allowBlank: false,
2502
- allowLoop: false,
2503
- allowNode: false,
2504
- snap: true,
2505
- allowEdge: false
2506
- };
2507
- const highlightingConfig = {
2508
- magnetAvailable: {
2509
- name: "stroke",
2510
- args: { attrs: {
2511
- fill: "#31d0c6",
2512
- stroke: "#31d0c6",
2513
- opacity: 1
2514
- } }
2515
- },
2516
- magnetAdsorbed: {
2517
- name: "stroke",
2518
- args: { attrs: {
2519
- fill: "#5F95FF",
2520
- stroke: "#5F95FF",
2521
- opacity: 1
2522
- } }
2523
- }
2524
- };
2525
- const defaultEdgeConfig = {
2526
- shape: "extends",
2527
- attrs: { line: {
2528
- stroke: "#722ed1",
2529
- strokeWidth: 2,
2530
- targetMarker: {
2531
- name: "block",
2532
- width: 8,
2533
- height: 6,
2534
- fill: "#722ed1"
2535
- }
2536
- } }
2537
- };
2538
- const sampleClasses = [
2539
- {
2540
- id: "animal",
2541
- name: "<<Abstract>>\n动物",
2542
- x: 342,
2543
- y: 98,
2544
- attributes: [{
2545
- name: "名字",
2546
- type: "string",
2547
- visibility: "public"
2548
- }],
2549
- methods: [{
2550
- name: "新陈代谢",
2551
- returnType: "void",
2552
- visibility: "public"
2553
- }, {
2554
- name: "繁殖",
2555
- returnType: "void",
2556
- visibility: "public"
2557
- }]
2558
- },
2559
- {
2560
- id: "bird",
2561
- name: "鸟",
2562
- x: 575,
2563
- y: 280,
2564
- attributes: [{
2565
- name: "羽毛",
2566
- type: "string",
2567
- visibility: "public"
2568
- }, {
2569
- name: "下蛋",
2570
- type: "boolean",
2571
- visibility: "public"
2572
- }],
2573
- methods: []
2574
- },
2575
- {
2576
- id: "mammal",
2577
- name: "哺乳动物",
2578
- x: 844,
2579
- y: 319,
2580
- attributes: [{
2581
- name: "翅膀",
2582
- type: "boolean",
2583
- visibility: "public"
2584
- }],
2585
- methods: []
2586
- },
2587
- {
2588
- id: "dog",
2589
- name: "狗",
2590
- x: 656,
2591
- y: 456,
2592
- attributes: [{
2593
- name: "下蛋",
2594
- type: "boolean",
2595
- visibility: "public"
2596
- }],
2597
- methods: []
2598
- },
2599
- {
2600
- id: "enterprise",
2601
- name: "企鹅",
2602
- x: 984,
2603
- y: 456,
2604
- attributes: [{
2605
- name: "下蛋",
2606
- type: "boolean",
2607
- visibility: "public"
2608
- }],
2609
- methods: []
2610
- },
2611
- {
2612
- id: "sparrow",
2613
- name: "麻雀",
2614
- x: 531,
2615
- y: 608,
2616
- attributes: [{
2617
- name: "学飞",
2618
- type: "boolean",
2619
- visibility: "public"
2620
- }],
2621
- methods: []
2622
- },
2623
- {
2624
- id: "interface-flying",
2625
- name: "<<interface>>\n飞翔",
2626
- x: 762,
2627
- y: 608,
2628
- attributes: [{
2629
- name: "下蛋",
2630
- type: "boolean",
2631
- visibility: "public"
2632
- }],
2633
- methods: []
2634
- },
2635
- {
2636
- id: "qemu",
2637
- name: "气球",
2638
- x: 981,
2639
- y: 608,
2640
- attributes: [],
2641
- methods: []
2642
- }
2643
- ];
2644
- const sampleConnections = [
2645
- {
2646
- id: "edge-1",
2647
- shape: "extends",
2648
- source: "bird",
2649
- target: "animal"
2650
- },
2651
- {
2652
- id: "edge-2",
2653
- shape: "extends",
2654
- source: "mammal",
2655
- target: "animal"
2656
- },
2657
- {
2658
- id: "edge-3",
2659
- shape: "extends",
2660
- source: "dog",
2661
- target: "mammal"
2662
- },
2663
- {
2664
- id: "edge-4",
2665
- shape: "extends",
2666
- source: "enterprise",
2667
- target: "mammal"
2668
- },
2669
- {
2670
- id: "edge-5",
2671
- shape: "extends",
2672
- source: "sparrow",
2673
- target: "bird"
2674
- },
2675
- {
2676
- id: "edge-6",
2677
- shape: "implement",
2678
- source: "sparrow",
2679
- target: "interface-flying"
2680
- },
2681
- {
2682
- id: "edge-7",
2683
- shape: "implement",
2684
- source: "enterprise",
2685
- target: "interface-flying"
2686
- },
2687
- {
2688
- id: "edge-8",
2689
- shape: "association",
2690
- source: "bird",
2691
- target: "mammal",
2692
- label: "1:2"
2693
- }
2694
- ];
2695
- const getVisibilitySymbol = (visibility) => visibilityMap[visibility] || "+";
2696
- const newClassTemplate = {
2697
- name: "新类",
2698
- attributes: [{
2699
- name: "attribute",
2700
- type: "string",
2701
- visibility: "private"
2702
- }],
2703
- methods: [{
2704
- name: "method",
2705
- returnType: "void",
2706
- visibility: "public"
2707
- }],
2708
- position: {
2709
- x: 100,
2710
- y: 100
2711
- }
2712
- };
2713
-
2714
- //#endregion
2715
- //#region src/components/C_AntV/layout/UML/index.vue?vue&type=script&setup=true&lang.ts
2716
- const _hoisted_1$1 = { class: "uml-layout" };
2717
- const _hoisted_2 = {
2718
- key: 0,
2719
- class: "toolbar"
2720
- };
2721
- var index_vue_vue_type_script_setup_true_lang_default$1 = /* @__PURE__ */ defineComponent({
2722
- __name: "index",
2723
- props: {
2724
- data: {},
2725
- showToolbar: {
2726
- type: Boolean,
2727
- default: true
2728
- },
2729
- readonly: {
2730
- type: Boolean,
2731
- default: false
2732
- },
2733
- width: { default: "100%" },
2734
- height: { default: "600px" },
2735
- theme: {}
2736
- },
2737
- emits: ["ready", "data-change"],
2738
- setup(__props, { expose: __expose, emit: __emit }) {
2739
- const props = __props;
2740
- const emit = __emit;
2741
- const containerRef = ref();
2742
- const { graph, initGraph, centerContent, zoomToFit } = useGraphBase(containerRef, computed(() => props.theme === "dark"));
2743
- const { exportOptions, handleExport } = useGraphExport(graph, "uml-diagram");
2744
- const { bindInteractions } = useEdgeInteraction(graph, {
2745
- defaultColor: "#722ed1",
2746
- portPositions: [
2747
- "top",
2748
- "right",
2749
- "bottom",
2750
- "left"
2751
- ],
2752
- onDataChange: () => emitDataChange()
2753
- });
2754
- const showEditor = ref(false);
2755
- const editingClass = ref();
2756
- const registerNodes = () => {
2757
- Graph.registerNode("class", {
2758
- ...classNodeConfig,
2759
- propHooks(meta) {
2760
- const { name, attributes, methods, ...others } = meta;
2761
- if (!(name && attributes && methods)) return meta;
2762
- let offsetY = 0;
2763
- [
2764
- {
2765
- type: "name",
2766
- text: name
2767
- },
2768
- {
2769
- type: "attrs",
2770
- text: attributes
2771
- },
2772
- {
2773
- type: "methods",
2774
- text: methods
2775
- }
2776
- ].forEach((rect) => {
2777
- const height = Array.isArray(rect.text) ? rect.text.length * 12 + 16 : 32;
2778
- ObjectExt.setByPath(others, `attrs/${rect.type}-text/text`, Array.isArray(rect.text) ? rect.text.join("\n") : rect.text);
2779
- ObjectExt.setByPath(others, `attrs/${rect.type}-rect/height`, height);
2780
- ObjectExt.setByPath(others, `attrs/${rect.type}-rect/transform`, `translate(0,${offsetY})`);
2781
- offsetY += height;
2782
- });
2783
- others.size = {
2784
- width: 160,
2785
- height: offsetY
2786
- };
2787
- return others;
2788
- }
2789
- }, true);
2790
- Object.entries(edgeTypes).forEach(([type, config]) => {
2791
- Graph.registerEdge(type, {
2792
- inherit: "edge",
2793
- attrs: { line: {
2794
- strokeWidth: 2,
2795
- stroke: "#722ed1",
2796
- ...config
2797
- } }
2798
- }, true);
2799
- });
2800
- };
2801
- const loadData = (data) => {
2802
- if (!graph.value || !data.length) return;
2803
- const edgeShapes = [
2804
- "extends",
2805
- "composition",
2806
- "implement",
2807
- "aggregation",
2808
- "association"
2809
- ];
2810
- const cells = [];
2811
- data.forEach((item) => {
2812
- if (edgeShapes.includes(item.shape)) cells.push(graph.value.createEdge(item));
2813
- else {
2814
- const { data: nodeData, ...displayProps } = item;
2815
- const node = graph.value.createNode(displayProps);
2816
- if (nodeData) node.setData(nodeData);
2817
- cells.push(node);
2818
- }
2819
- });
2820
- graph.value.resetCells(cells);
2821
- setTimeout(() => graph.value.zoomToFit({
2822
- padding: 10,
2823
- maxScale: 1
2824
- }), 200);
2825
- };
2826
- const formatClassDisplay = (cls) => ({
2827
- name: cls.name,
2828
- attributes: cls.attributes.map((attr) => `${getVisibilitySymbol(attr.visibility)} ${attr.name}: ${attr.type}`),
2829
- methods: cls.methods.map((method) => `${getVisibilitySymbol(method.visibility)} ${method.name}(): ${method.returnType}`)
2830
- });
2831
- const addClass = () => {
2832
- if (!graph.value) return;
2833
- const newClass = {
2834
- id: `class_${Date.now()}`,
2835
- ...newClassTemplate
2836
- };
2837
- const nodeData = {
2838
- id: newClass.id,
2839
- shape: "class",
2840
- x: newClass.position.x,
2841
- y: newClass.position.y,
2842
- ...formatClassDisplay(newClass),
2843
- data: newClass
2844
- };
2845
- graph.value.addCell(graph.value.createNode(nodeData));
2846
- emitDataChange();
2847
- };
2848
- const editClass = (umlClass) => {
2849
- editingClass.value = {
2850
- ...umlClass,
2851
- attributes: [...umlClass.attributes || []],
2852
- methods: [...umlClass.methods || []]
2853
- };
2854
- showEditor.value = true;
2855
- };
2856
- const saveClass = () => {
2857
- if (!graph.value || !editingClass.value) return;
2858
- const node = graph.value.getCellById(editingClass.value.id);
2859
- if (node) {
2860
- node.setData(editingClass.value);
2861
- node.prop(formatClassDisplay(editingClass.value));
2862
- }
2863
- showEditor.value = false;
2864
- emitDataChange();
2865
- };
2866
- const deleteClass = () => {
2867
- if (!graph.value || !editingClass.value) return;
2868
- graph.value.getCellById(editingClass.value.id)?.remove();
2869
- showEditor.value = false;
2870
- emitDataChange();
2871
- };
2872
- const getCurrentData = () => ({
2873
- classes: graph.value?.getNodes().map((node) => ({
2874
- ...node.getData(),
2875
- position: node.getPosition()
2876
- })) || [],
2877
- relations: graph.value?.getEdges().map((edge) => ({
2878
- id: edge.id,
2879
- type: edge.shape,
2880
- source: edge.getSourceCellId() || "",
2881
- target: edge.getTargetCellId() || ""
2882
- })) || []
2883
- });
2884
- const emitDataChange = () => emit("data-change", getCurrentData());
2885
- watch(graph, (newGraph) => {
2886
- if (!(newGraph instanceof Graph)) return;
2887
- registerNodes();
2888
- bindInteractions();
2889
- newGraph.on("node:dblclick", ({ node }) => {
2890
- if (!props.readonly && node.getData()) editClass(node.getData());
2891
- });
2892
- emit("ready", newGraph);
2893
- loadData([...sampleClasses.map((cls) => ({
2894
- id: cls.id,
2895
- shape: "class",
2896
- x: cls.x,
2897
- y: cls.y,
2898
- ...formatClassDisplay(cls),
2899
- data: {
2900
- id: cls.id,
2901
- name: cls.name,
2902
- attributes: cls.attributes,
2903
- methods: cls.methods,
2904
- position: {
2905
- x: cls.x,
2906
- y: cls.y
2907
- }
2908
- }
2909
- })), ...sampleConnections]);
2910
- }, { immediate: true });
2911
- watch(() => props.data, (newData) => {
2912
- if (graph.value && newData?.classes) {
2913
- const edgeShapes = [
2914
- "extends",
2915
- "composition",
2916
- "implement",
2917
- "aggregation",
2918
- "association"
2919
- ];
2920
- loadData([...newData.classes.map((cls) => ({
2921
- id: cls.id,
2922
- shape: "class",
2923
- x: cls.position?.x ?? 50,
2924
- y: cls.position?.y ?? 50,
2925
- ...formatClassDisplay(cls),
2926
- data: cls
2927
- })), ...(newData.relations || []).filter((r) => edgeShapes.includes(r.type)).map((r) => ({
2928
- shape: r.type,
2929
- source: r.source,
2930
- target: r.target
2931
- }))]);
2932
- }
2933
- }, { deep: true });
2934
- onMounted(() => {
2935
- initGraph({
2936
- interacting: true,
2937
- connecting: {
2938
- ...connectingConfig,
2939
- createEdge: () => graph.value.createEdge(defaultEdgeConfig),
2940
- validateConnection: ({ sourceView, targetView, sourceMagnet, targetMagnet }) => sourceView !== targetView && !!sourceMagnet && !!targetMagnet && sourceMagnet.getAttribute("magnet") === "true" && targetMagnet.getAttribute("magnet") === "true"
2941
- },
2942
- highlighting: highlightingConfig
2943
- });
2944
- });
2945
- __expose({
2946
- getGraph: () => graph.value,
2947
- getData: getCurrentData,
2948
- addClass,
2949
- centerContent,
2950
- zoomToFit
2951
- });
2952
- return (_ctx, _cache) => {
2953
- return openBlock(), createElementBlock("div", _hoisted_1$1, [
2954
- _ctx.showToolbar ? (openBlock(), createElementBlock("div", _hoisted_2, [createVNode(unref(NSpace), null, {
2955
- default: withCtx(() => [
2956
- createVNode(unref(NButton), {
2957
- onClick: addClass,
2958
- type: "primary",
2959
- size: "small"
2960
- }, {
2961
- icon: withCtx(() => [createVNode(C_Icon_default, {
2962
- name: "mdi:plus-box",
2963
- size: 16
2964
- })]),
2965
- default: withCtx(() => [_cache[3] || (_cache[3] = createTextVNode(" 添加类 ", -1))]),
2966
- _: 1,
2967
- __: [3]
2968
- }),
2969
- createVNode(unref(NButton), {
2970
- onClick: unref(centerContent),
2971
- size: "small"
2972
- }, {
2973
- icon: withCtx(() => [createVNode(C_Icon_default, {
2974
- name: "mdi:image-filter-center-focus",
2975
- size: 16
2976
- })]),
2977
- default: withCtx(() => [_cache[4] || (_cache[4] = createTextVNode(" 居中 ", -1))]),
2978
- _: 1,
2979
- __: [4]
2980
- }, 8, ["onClick"]),
2981
- createVNode(unref(NButton), {
2982
- onClick: unref(zoomToFit),
2983
- size: "small"
2984
- }, {
2985
- icon: withCtx(() => [createVNode(C_Icon_default, {
2986
- name: "mdi:fit-to-screen",
2987
- size: 16
2988
- })]),
2989
- default: withCtx(() => [_cache[5] || (_cache[5] = createTextVNode(" 适应 ", -1))]),
2990
- _: 1,
2991
- __: [5]
2992
- }, 8, ["onClick"]),
2993
- createVNode(unref(NDropdown), {
2994
- options: unref(exportOptions),
2995
- onSelect: _cache[0] || (_cache[0] = (key) => unref(handleExport)(key, getCurrentData))
2996
- }, {
2997
- default: withCtx(() => [createVNode(unref(NButton), { size: "small" }, {
2998
- icon: withCtx(() => [createVNode(C_Icon_default, {
2999
- name: "mdi:export",
3000
- size: 16
3001
- })]),
3002
- default: withCtx(() => [_cache[6] || (_cache[6] = createTextVNode(" 导出 ", -1))]),
3003
- _: 1,
3004
- __: [6]
3005
- })]),
3006
- _: 1
3007
- }, 8, ["options"])
3008
- ]),
3009
- _: 1
3010
- })])) : createCommentVNode("v-if", true),
3011
- createElementVNode("div", {
3012
- ref_key: "containerRef",
3013
- ref: containerRef,
3014
- class: "graph-container",
3015
- style: normalizeStyle({
3016
- width: props.width,
3017
- height: props.height
3018
- })
3019
- }, null, 4),
3020
- createVNode(UMLClassEditor_default, {
3021
- show: showEditor.value,
3022
- "editing-class": editingClass.value,
3023
- "onUpdate:editingClass": _cache[1] || (_cache[1] = ($event) => editingClass.value = $event),
3024
- "onUpdate:show": _cache[2] || (_cache[2] = ($event) => showEditor.value = $event),
3025
- onSave: saveClass,
3026
- onDelete: deleteClass
3027
- }, null, 8, ["show", "editing-class"])
3028
- ]);
3029
- };
3030
- }
3031
- });
3032
-
3033
- //#endregion
3034
- //#region src/components/C_AntV/layout/UML/index.vue
3035
- var UML_default = /* @__PURE__ */ export_helper_default(index_vue_vue_type_script_setup_true_lang_default$1, [["__scopeId", "data-v-1092fbdb"]]);
3036
-
3037
- //#endregion
3038
- //#region src/components/C_AntV/index.vue?vue&type=script&setup=true&lang.ts
3039
- const _hoisted_1 = { class: "c-antv-container" };
3040
- var index_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
3041
- name: "C_AntV",
3042
- __name: "index",
3043
- props: {
3044
- type: {},
3045
- data: {},
3046
- width: { default: "100%" },
3047
- height: { default: "600px" },
3048
- readonly: {
3049
- type: Boolean,
3050
- default: false
3051
- },
3052
- showToolbar: {
3053
- type: Boolean,
3054
- default: true
3055
- },
3056
- theme: { default: "light" }
3057
- },
3058
- emits: ["ready", "data-change"],
3059
- setup(__props, { expose: __expose, emit: __emit }) {
3060
- const props = __props;
3061
- const emit = __emit;
3062
- const layoutRef = ref();
3063
- const components = {
3064
- er: ER_default,
3065
- bpmn: BPMN_default,
3066
- uml: UML_default
3067
- };
3068
- const currentComponent = computed(() => components[props.type]);
3069
- const componentProps = computed(() => {
3070
- const baseProps = {
3071
- width: props.width,
3072
- height: props.height,
3073
- readonly: props.readonly,
3074
- showToolbar: props.showToolbar,
3075
- theme: props.theme
3076
- };
3077
- let adaptedData = props.data;
3078
- if (props.type === "bpmn" && props.data) {
3079
- const bpmnData = props.data;
3080
- if (bpmnData && typeof bpmnData === "object" && "nodes" in bpmnData && "edges" in bpmnData) adaptedData = [...(bpmnData.nodes || []).map((node) => ({
3081
- ...node,
3082
- shape: node.type || node.shape || "rect",
3083
- x: node.x ?? 0,
3084
- y: node.y ?? 0
3085
- })), ...(bpmnData.edges || []).map((edge) => ({
3086
- ...edge,
3087
- shape: "edge",
3088
- x: 0,
3089
- y: 0
3090
- }))];
3091
- }
3092
- return {
3093
- ...baseProps,
3094
- data: adaptedData
3095
- };
3096
- });
3097
- const handleReady = (graph) => {
3098
- emit("ready", graph);
3099
- };
3100
- const handleDataChange = (data) => {
3101
- let convertedData;
3102
- if (props.type === "bpmn" && Array.isArray(data)) convertedData = {
3103
- nodes: data.filter((item) => item.shape !== "edge").map((item) => {
3104
- const { shape, x, y, ...node } = item;
3105
- return {
3106
- ...node,
3107
- type: shape === "rect" ? "task" : shape,
3108
- x: x || 0,
3109
- y: y || 0
3110
- };
3111
- }),
3112
- edges: data.filter((item) => item.shape === "edge").map((item) => {
3113
- const { shape, x, y, ...edge } = item;
3114
- return edge;
3115
- }),
3116
- flows: []
3117
- };
3118
- else convertedData = data;
3119
- emit("data-change", convertedData);
3120
- };
3121
- __expose({
3122
- getGraph: () => layoutRef.value?.getGraph?.(),
3123
- getData: () => {
3124
- const rawData = layoutRef.value?.getData?.();
3125
- if (props.type === "bpmn" && Array.isArray(rawData)) return {
3126
- nodes: rawData.filter((item) => item.shape !== "edge"),
3127
- edges: rawData.filter((item) => item.shape === "edge"),
3128
- flows: []
3129
- };
3130
- return rawData;
3131
- }
3132
- });
3133
- return (_ctx, _cache) => {
3134
- return openBlock(), createElementBlock("div", _hoisted_1, [(openBlock(), createBlock(resolveDynamicComponent(currentComponent.value), mergeProps(componentProps.value, {
3135
- onReady: handleReady,
3136
- onDataChange: handleDataChange,
3137
- ref_key: "layoutRef",
3138
- ref: layoutRef
3139
- }), null, 16))]);
3140
- };
3141
- }
3142
- });
3143
-
3144
- //#endregion
3145
- //#region src/components/C_AntV/index.vue
3146
- var C_AntV_default = /* @__PURE__ */ export_helper_default(index_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-f1ab77ea"]]);
3147
-
3148
- //#endregion
3149
- export { useGraphBase as i, useEdgeInteraction as n, useGraphExport as r, C_AntV_default as t };
1
+ import{t as e}from"./C_Icon2.js";import{t}from"./export-helper.js";import{NAlert as n,NButton as r,NCard as i,NCheckbox as a,NDivider as o,NDrawer as s,NDrawerContent as c,NDropdown as l,NForm as u,NFormItem as d,NGi as f,NGrid as p,NInput as m,NRadio as h,NRadioGroup as g,NSelect as _,NSpace as v,useMessage as y}from"naive-ui";import{Fragment as b,computed as x,createBlock as S,createCommentVNode as C,createElementBlock as w,createElementVNode as T,createTextVNode as E,createVNode as D,defineComponent as O,mergeModels as k,mergeProps as A,nextTick as j,normalizeClass as M,normalizeStyle as N,onMounted as P,onUnmounted as F,openBlock as I,ref as L,renderList as R,resolveDynamicComponent as z,toDisplayString as B,unref as V,useModel as H,watch as U,withCtx as W}from"vue";import{Graph as G,ObjectExt as K}from"@antv/x6";import ee from"html2canvas";function q(e){return{background:e?`#18181c`:`#f5f5f5`,gridPrimary:e?`rgba(255, 255, 255, 0.08)`:`#eee`,gridSecondary:e?`rgba(255, 255, 255, 0.04)`:`#ddd`}}function te(e=!1){let t=q(e);return{background:{color:t.background},grid:{visible:!0,type:`doubleMesh`,args:[{color:t.gridPrimary,thickness:1},{color:t.gridSecondary,thickness:1,factor:4}]},mousewheel:{enabled:!0,zoomAtMousePosition:!0,modifiers:`ctrl`,minScale:.5,maxScale:2},selecting:{enabled:!0,rubberband:!0,movable:!0,showNodeSelectionBox:!0},resizing:!0,rotating:!0,snapline:!0,keyboard:!0,clipboard:!0}}function J(e){return e?{width:e.clientWidth||e.offsetWidth||800,height:e.clientHeight||e.offsetHeight||600}:{width:0,height:0}}function Y(e,t){let n=0,r=L(null),i=L(!1),a=async(o={})=>{await j(),i.value=!0;try{if(!e.value)return;r.value&&=(r.value.dispose(),null);let{width:i,height:s}=J(e.value);if(i===0||s===0){n++,n<10&&setTimeout(()=>a(o),100);return}n=0;let c=te(t?.value??!1);r.value=new G({container:e.value,width:i,height:s,...c,...o})}catch{}finally{i.value=!1}};function o(e){if(!r.value)return;let t=q(e);r.value.drawBackground({color:t.background}),r.value.drawGrid({type:`doubleMesh`,args:[{color:t.gridPrimary,thickness:1},{color:t.gridSecondary,thickness:1,factor:4}]})}t&&U(t,e=>{o(e)});function s(){r.value&&=(r.value.dispose(),null)}function c(){r.value?.centerContent()}function l(){r.value?.zoomToFit({padding:20,maxScale:1})}function u(e){r.value?.zoom(e)}function d(){if(r.value&&e.value){let{width:t,height:n}=J(e.value);r.value.resize(t,n)}}return F(s),{graph:r,loading:i,initGraph:a,destroyGraph:s,centerContent:c,zoomToFit:l,zoom:u,resizeGraph:d,updateTheme:o}}function X(e,t){let n=URL.createObjectURL(e),r=document.createElement(`a`);r.href=n,r.download=t,r.style.display=`none`,document.body.appendChild(r),r.click(),document.body.removeChild(r),URL.revokeObjectURL(n)}function ne(e,t=`diagram.json`){let n=JSON.stringify(e,null,2);X(new Blob([n],{type:`application/json`}),t)}async function re(e,t=`diagram.png`,n={}){let{backgroundColor:r=`#ffffff`,scale:i=2}=n,{container:a}=e;X(await ae(await ee(a,{backgroundColor:r,scale:i,useCORS:!0,logging:!1}),`image/png`),t)}function ie(e,t=`diagram.svg`){let n=e.container.querySelector(`svg`);if(!n)throw Error(`SVG导出失败: 未找到图表 SVG 元素`);let r=n.cloneNode(!0);r.getAttribute(`xmlns`)||r.setAttribute(`xmlns`,`http://www.w3.org/2000/svg`),r.getAttribute(`xmlns:xlink`)||r.setAttribute(`xmlns:xlink`,`http://www.w3.org/1999/xlink`);let i=new XMLSerializer().serializeToString(r);X(new Blob([i],{type:`image/svg+xml;charset=utf-8`}),t)}function ae(e,t,n=1){return new Promise((r,i)=>{e.toBlob(e=>{e?r(e):i(Error(`Canvas 转 Blob 失败`))},t,n)})}const oe=[{label:`导出PNG`,key:`png`},{label:`导出SVG`,key:`svg`},{label:`导出JSON`,key:`json`}];function Z(e,t=`diagram`){let n=y();return{exportOptions:oe,handleExport:async(r,i)=>{if(e.value)try{switch(r){case`png`:await re(e.value,`${t}.png`);break;case`svg`:ie(e.value,`${t}.svg`);break;case`json`:i&&ne(i(),`${t}.json`);break}}catch(e){console.error(`[useGraphExport] 导出失败 (${r}):`,e),n.error(`导出${r.toUpperCase()}失败,请重试`)}}}}const se=[{label:`BIGINT`,value:`BIGINT`},{label:`INT`,value:`INT`},{label:`SMALLINT`,value:`SMALLINT`},{label:`TINYINT`,value:`TINYINT`},{label:`VARCHAR(50)`,value:`VARCHAR(50)`},{label:`VARCHAR(100)`,value:`VARCHAR(100)`},{label:`VARCHAR(255)`,value:`VARCHAR(255)`},{label:`CHAR(10)`,value:`CHAR(10)`},{label:`TEXT`,value:`TEXT`},{label:`LONGTEXT`,value:`LONGTEXT`},{label:`DATETIME`,value:`DATETIME`},{label:`TIMESTAMP`,value:`TIMESTAMP`},{label:`DATE`,value:`DATE`},{label:`TIME`,value:`TIME`},{label:`DECIMAL(10,2)`,value:`DECIMAL(10,2)`},{label:`FLOAT`,value:`FLOAT`},{label:`DOUBLE`,value:`DOUBLE`},{label:`BOOLEAN`,value:`BOOLEAN`},{label:`JSON`,value:`JSON`}],ce={key:0,class:`table-editor`},le={class:`fields-container`},ue={class:`field-header`};var de=O({__name:`ERTableEditor`,props:k({show:{type:Boolean}},{editingTable:{},editingTableModifiers:{}}),emits:k([`update:show`,`save`,`add-field`,`remove-field`,`handle-primary-key`],[`update:editingTable`]),setup(t,{emit:n}){let l=H(t,`editingTable`),h=n,g=(e,t)=>h(`handle-primary-key`,e,t),y=()=>h(`add-field`),x=e=>h(`remove-field`,e);return(t,n)=>(I(),S(V(s),{show:t.show,width:`600`,placement:`right`,"onUpdate:show":n[4]||=e=>t.$emit(`update:show`,e)},{default:W(()=>[D(V(c),{title:`编辑表: ${l.value?.name||`新表`}`,closable:``},{footer:W(()=>[D(V(v),{justify:`end`},{default:W(()=>[D(V(r),{onClick:n[2]||=e=>t.$emit(`update:show`,!1)},{default:W(()=>n[11]||=[E(`取消`,-1)]),_:1,__:[11]}),D(V(r),{onClick:n[3]||=e=>t.$emit(`save`),type:`primary`},{default:W(()=>n[12]||=[E(`保存`,-1)]),_:1,__:[12]})]),_:1})]),default:W(()=>[l.value?(I(),w(`div`,ce,[D(V(u),{model:l.value,"label-placement":`top`},{default:W(()=>[D(V(d),{label:`表名`},{default:W(()=>[D(V(m),{value:l.value.name,"onUpdate:value":n[0]||=e=>l.value.name=e,placeholder:`请输入表名`},null,8,[`value`])]),_:1}),D(V(d),{label:`表注释`},{default:W(()=>[D(V(m),{value:l.value.comment,"onUpdate:value":n[1]||=e=>l.value.comment=e,placeholder:`表注释`},null,8,[`value`])]),_:1}),D(V(o),null,{default:W(()=>n[5]||=[E(`字段列表`,-1)]),_:1,__:[5]}),T(`div`,le,[(I(!0),w(b,null,R(l.value.fields,(e,t)=>(I(),S(V(i),{key:t,size:`small`,class:`field-card`},{header:W(()=>[T(`div`,ue,[T(`span`,null,`#`+B(t+1)+` `+B(e.name||`新字段`),1),D(V(r),{onClick:e=>x(t),size:`tiny`,type:`error`,quaternary:``,disabled:l.value.fields.length<=1},{default:W(()=>n[6]||=[E(` 删除 `,-1)]),_:2,__:[6]},1032,[`onClick`,`disabled`])])]),default:W(()=>[D(V(p),{cols:2,"x-gap":12},{default:W(()=>[D(V(f),null,{default:W(()=>[D(V(d),{label:`字段名`,size:`small`},{default:W(()=>[D(V(m),{value:e.name,"onUpdate:value":t=>e.name=t,placeholder:`字段名`,size:`small`},null,8,[`value`,`onUpdate:value`])]),_:2},1024)]),_:2},1024),D(V(f),null,{default:W(()=>[D(V(d),{label:`类型`,size:`small`},{default:W(()=>[D(V(_),{value:e.type,"onUpdate:value":t=>e.type=t,options:V(se),size:`small`,filterable:``,placeholder:`选择类型`},null,8,[`value`,`onUpdate:value`,`options`])]),_:2},1024)]),_:2},1024)]),_:2},1024),D(V(v),{style:{"margin-top":`12px`}},{default:W(()=>[D(V(a),{checked:e.isPrimaryKey,"onUpdate:checked":[t=>e.isPrimaryKey=t,t=>g(e,t)]},{default:W(()=>n[7]||=[E(` 主键 `,-1)]),_:2,__:[7]},1032,[`checked`,`onUpdate:checked`]),D(V(a),{checked:e.isRequired,"onUpdate:checked":t=>e.isRequired=t},{default:W(()=>n[8]||=[E(`必填`,-1)]),_:2,__:[8]},1032,[`checked`,`onUpdate:checked`]),D(V(a),{checked:e.isForeignKey,"onUpdate:checked":t=>e.isForeignKey=t},{default:W(()=>n[9]||=[E(`外键`,-1)]),_:2,__:[9]},1032,[`checked`,`onUpdate:checked`])]),_:2},1024),D(V(d),{label:`注释`,size:`small`,style:{"margin-top":`12px`}},{default:W(()=>[D(V(m),{value:e.comment,"onUpdate:value":t=>e.comment=t,placeholder:`字段注释`,size:`small`},null,8,[`value`,`onUpdate:value`])]),_:2},1024)]),_:2},1024))),128)),D(V(r),{onClick:y,dashed:``,block:``,type:`primary`,ghost:``,style:{"margin-top":`16px`}},{icon:W(()=>[D(e,{name:`mdi:plus`,size:16})]),default:W(()=>[n[10]||=E(` 添加字段 `,-1)]),_:1,__:[10]})])]),_:1},8,[`model`])])):C(`v-if`,!0)]),_:1},8,[`title`])]),_:1},8,[`show`]))}});const fe={class:`er-layout`},pe={key:0,class:`toolbar`},me={key:0,style:{"margin-top":`8px`}};var he=t(O({__name:`index`,props:{data:{},showToolbar:{type:Boolean,default:!0},readonly:{type:Boolean,default:!1},theme:{}},emits:[`ready`,`data-change`],setup(t,{expose:i,emit:a}){let o=t,s=a,c=L(),{graph:u,initGraph:d,centerContent:f,zoomToFit:p}=Y(c,x(()=>o.theme===`dark`)),{exportOptions:m,handleExport:h}=Z(u,`er-diagram`),g=L(!1),_=L(),y=L(!1),b=(e,t)=>e.length>t?e.substring(0,t-1)+`..`:e,S=e=>e.fields?.map(t=>{let n=t.isPrimaryKey?`🔑 ${t.name}`:t.isRequired?`* ${t.name}`:t.name;return{id:`${e.id}_${t.name}`,group:`list`,attrs:{portNameLabel:{text:b(n,12),title:n},portTypeLabel:{text:b(t.type,10),title:t.type},portBody:{fill:t.isPrimaryKey?`#FFF7E6`:`#EFF4FF`}}}})||[],O=e=>({id:e.id,shape:`er-rect`,x:e.position.x,y:e.position.y,width:200,height:24+(e.fields?.length||0)*24,data:e,attrs:{label:{text:b(e.name,20),refX:.5,refY:10,textAnchor:`middle`,title:e.name}},ports:S(e)}),k=()=>{u.value&&(G.registerPortLayout(`erPortPosition`,e=>e.map((e,t)=>({position:{x:0,y:(t+1)*24},angle:0})),!0),G.registerNode(`er-rect`,{inherit:`rect`,markup:[{tagName:`rect`,selector:`body`},{tagName:`text`,selector:`label`}],attrs:{rect:{strokeWidth:1,stroke:`#5F95FF`,fill:`#5F95FF`},label:{fontWeight:`bold`,fill:`#ffffff`,fontSize:12}},ports:{groups:{list:{markup:[{tagName:`rect`,selector:`portBody`},{tagName:`text`,selector:`portNameLabel`},{tagName:`text`,selector:`portTypeLabel`}],attrs:{portBody:{width:200,height:24,strokeWidth:1,stroke:`#5F95FF`,fill:`#EFF4FF`,magnet:!0},portNameLabel:{ref:`portBody`,refX:6,refY:6,fontSize:9,textAnchor:`start`,textOverflow:`ellipsis`},portTypeLabel:{ref:`portBody`,refX:120,refY:6,fontSize:9,textAnchor:`start`,fill:`#666`}},position:`erPortPosition`}}}},!0))},A=()=>{y.value=!y.value,y.value||M()},M=()=>{u.value?.getEdges().forEach(e=>{e.attr(`line/stroke`,`#A2B1C3`),e.attr(`line/strokeWidth`,2)})},N=e=>{if(!u.value)return;let t=u.value.createNode(O(e));return u.value.resetCells([t,...u.value.getCells()]),t},R=()=>{let e=u.value?.getNodes()||[];for(let t=0;t<10;t++)for(let n=0;n<3;n++){let r={x:n*250+50,y:t*250+50};if(!e.some(e=>{let t=e.getPosition();return Math.abs(t.x-r.x)<250*.8&&Math.abs(t.y-r.y)<250*.8}))return r}return{x:50,y:50}},z=()=>{let e={id:`table_${Date.now()}`,name:`新表`,comment:``,fields:[{name:`id`,type:`BIGINT`,isPrimaryKey:!0,isRequired:!0,isForeignKey:!1,comment:`主键`},{name:`name`,type:`VARCHAR(100)`,isPrimaryKey:!1,isRequired:!0,isForeignKey:!1,comment:`名称`}],position:R()};N(e),H(e),X()},H=e=>{_.value={...e,fields:e.fields?.map(e=>({...e}))||[]},g.value=!0},K=()=>{if(!u.value||!_.value)return;let e=u.value.getCellById(_.value.id);e&&(e.setData(_.value),e.prop({size:{width:200,height:24+_.value.fields.length*24},attrs:{label:{text:b(_.value.name,20),title:_.value.name}},ports:S(_.value)})),g.value=!1,X()},ee=(e,t)=>{t&&(e.isRequired=!0,_.value?.fields.forEach(t=>{t!==e&&(t.isPrimaryKey=!1)}))},q=()=>{_.value?.fields.push({name:`field_${(_.value?.fields.length||0)+1}`,type:`VARCHAR(100)`,isPrimaryKey:!1,isRequired:!1,isForeignKey:!1,comment:``})},te=e=>{_.value&&_.value.fields.length>1&&_.value.fields.splice(e,1)},J=()=>{if(!u.value)return{tables:[],relations:[]};let e=u.value.getNodes().map(e=>({...e.getData(),position:e.getPosition()})),t=[];return u.value.getEdges().forEach(e=>{let n=e.getSourceNode(),r=e.getTargetNode(),i=e.getSourcePortId(),a=e.getTargetPortId();n&&r&&i&&a&&t.push({id:e.id,type:`foreign-key`,sourceTable:n.id,sourceField:i.split(`_`).slice(1).join(`_`),targetTable:r.id,targetField:a.split(`_`).slice(1).join(`_`),name:`${n.getData()?.name||n.id} -> ${r.getData()?.name||r.id}`})}),{tables:e,relations:t}},X=()=>s(`data-change`,J());return U(u,e=>{if(!(e instanceof G))return;k(),e.on(`node:dblclick`,({node:e})=>{o.readonly||H(e.getData())}),e.on(`edge:connected`,X),e.on(`edge:removed`,X);let t=null;e.on(`edge:click`,({edge:e})=>{y.value?(e.remove(),X()):(M(),e.attr(`line/stroke`,`#ff4d4f`),e.attr(`line/strokeWidth`,3),t=e)}),e.on(`edge:dblclick`,({edge:e})=>{e.remove(),X()}),e.on(`blank:click`,()=>{t=null,y.value||M()});let n=e=>{let n=e.target?.tagName;n===`INPUT`||n===`TEXTAREA`||e.target?.isContentEditable||(e.key===`Delete`||e.key===`Backspace`)&&t&&(t.remove(),X(),t=null)};document.addEventListener(`keydown`,n),F(()=>document.removeEventListener(`keydown`,n)),s(`ready`,e),j(()=>{if(o.data?.tables){let t=o.data.tables.map(t=>e.createNode(O(t)));o.data.relations?.length&&o.data.relations.forEach(n=>{t.push(e.createEdge({source:{cell:n.sourceTable,port:`${n.sourceTable}_${n.sourceField}`},target:{cell:n.targetTable,port:`${n.targetTable}_${n.targetField}`},attrs:{line:{stroke:`#A2B1C3`,strokeWidth:2}}}))}),e.resetCells(t),setTimeout(()=>e.zoomToFit({padding:20,maxScale:1}),300)}})},{immediate:!0}),U(()=>o.data,e=>{if(u.value&&e?.tables){let t=e.tables.map(e=>u.value.createNode(O(e)));e.relations?.length&&e.relations.forEach(e=>{t.push(u.value.createEdge({source:{cell:e.sourceTable,port:`${e.sourceTable}_${e.sourceField}`},target:{cell:e.targetTable,port:`${e.targetTable}_${e.targetField}`},attrs:{line:{stroke:`#A2B1C3`,strokeWidth:2}}}))}),u.value.resetCells(t)}},{deep:!0}),P(()=>d()),i({getGraph:()=>u.value??void 0,getData:J}),(t,i)=>(I(),w(`div`,fe,[C(` 工具栏 `),t.showToolbar?(I(),w(`div`,pe,[D(V(v),null,{default:W(()=>[D(V(r),{onClick:z,type:`primary`,size:`small`},{icon:W(()=>[D(e,{name:`mdi:table-plus`,size:16})]),default:W(()=>[i[3]||=E(` 添加表 `,-1)]),_:1,__:[3]}),D(V(r),{onClick:V(f),size:`small`},{icon:W(()=>[D(e,{name:`mdi:image-filter-center-focus`,size:16})]),default:W(()=>[i[4]||=E(` 居中 `,-1)]),_:1,__:[4]},8,[`onClick`]),D(V(r),{onClick:V(p),size:`small`},{icon:W(()=>[D(e,{name:`mdi:fit-to-screen`,size:16})]),default:W(()=>[i[5]||=E(` 适应 `,-1)]),_:1,__:[5]},8,[`onClick`]),D(V(r),{onClick:A,type:y.value?`error`:`default`,size:`small`},{icon:W(()=>[D(e,{name:`mdi:delete`,size:16})]),default:W(()=>[E(` `+B(y.value?`退出删除`:`删除连线`),1)]),_:1},8,[`type`]),D(V(l),{options:V(m),onSelect:i[0]||=e=>V(h)(e,J)},{default:W(()=>[D(V(r),{size:`small`},{icon:W(()=>[D(e,{name:`mdi:export`,size:16})]),default:W(()=>[i[6]||=E(` 导出 `,-1)]),_:1,__:[6]})]),_:1},8,[`options`])]),_:1}),y.value?(I(),w(`div`,me,[D(V(n),{type:`info`,size:`small`,"show-icon":!1},{default:W(()=>i[7]||=[E(` 删除模式:点击连接线即可删除 `,-1)]),_:1,__:[7]})])):C(`v-if`,!0)])):C(`v-if`,!0),C(` 图表容器 `),T(`div`,{ref_key:`containerRef`,ref:c,class:`graph-container`},null,512),C(` 表编辑器 `),D(de,{show:g.value,"editing-table":_.value,"onUpdate:editingTable":i[1]||=e=>_.value=e,"onUpdate:show":i[2]||=e=>g.value=e,onSave:K,onAddField:q,onRemoveField:te,onHandlePrimaryKey:ee},null,8,[`show`,`editing-table`])]))}}),[[`__scopeId`,`data-v-beb83641`]]);const ge={defaultColor:`#A2B1C3`,highlightColor:`#ff4d4f`,strokeWidth:2,highlightStrokeWidth:3,portPositions:[],onDataChange:()=>{}};function Q(e,t={}){let n={...ge,...t},r=()=>{e.value?.getEdges().forEach(e=>{e.attr(`line/stroke`,n.defaultColor),e.attr(`line/strokeWidth`,n.strokeWidth)})},i=e=>{r(),e.attr(`line/stroke`,n.highlightColor),e.attr(`line/strokeWidth`,n.highlightStrokeWidth)},a=(e,t)=>{n.portPositions.forEach(n=>e.attr(`port-${n}/style/opacity`,t))};return{resetEdgeStyles:r,highlightEdge:i,togglePorts:a,bindInteractions:()=>{let t=e.value;t&&(t.on(`edge:click`,({edge:e})=>i(e)),t.on(`edge:dblclick`,({edge:e})=>{e.remove(),n.onDataChange()}),t.on(`blank:click`,r),t.on(`node:click`,r),t.on(`edge:connected`,n.onDataChange),n.portPositions.length>0&&(t.on(`node:mouseenter`,({node:e})=>a(e,1)),t.on(`node:mouseleave`,({node:e})=>a(e,0))))}}}const _e={"start-event":{name:`开始`,title:`开始事件`,iconClass:`circle start-event`},activity:{name:`任务`,title:`任务活动`,iconClass:`rect activity`},gateway:{name:`网关`,title:`排他网关`,iconClass:`diamond gateway`},"end-event":{name:`结束`,title:`结束事件`,iconClass:`circle end-event`}},ve={event:`事件`,activity:`活动`,gateway:`网关`,"bpmn-edge":`连接线`},$=[`top`,`right`,`bottom`,`left`],ye=(e,t=`rect`)=>e.reduce((e,n)=>{let r=t===`circle`,i=n===`top`?r?{refCx:.5,refCy:0}:{refX:.5,refY:0}:n===`right`?r?{refCx:1,refCy:.5}:{refX:1,refY:.5}:n===`bottom`?r?{refCx:.5,refCy:1}:{refX:.5,refY:1}:r?{refCx:0,refCy:.5}:{refX:0,refY:.5};return e[`port-${n}`]={ref:`body`,...i,r:4,fill:`#31d0c6`,stroke:`#ffffff`,strokeWidth:2,magnet:!0,style:{cursor:`crosshair`,opacity:0,transition:`opacity 0.2s`}},e},{}),be={event:{inherit:`circle`,attrs:{body:{strokeWidth:2,stroke:`#5F95FF`,fill:`#FFF`,magnet:!1,style:{cursor:`move`}},text:{fontSize:12,fill:`#262626`,textAnchor:`middle`,textVerticalAnchor:`middle`,pointerEvents:`none`}}},activity:{inherit:`rect`,attrs:{body:{rx:6,ry:6,stroke:`#5F95FF`,fill:`#EFF4FF`,strokeWidth:1,magnet:!1,style:{cursor:`move`}},text:{fontSize:12,fill:`#262626`,textAnchor:`middle`,textVerticalAnchor:`middle`,pointerEvents:`none`}}},gateway:{inherit:`polygon`,attrs:{body:{refPoints:`0,10 10,0 20,10 10,20`,strokeWidth:2,stroke:`#5F95FF`,fill:`#EFF4FF`,magnet:!1,style:{cursor:`move`}},text:{fontSize:20,fill:`#5F95FF`,textAnchor:`middle`,textVerticalAnchor:`middle`,pointerEvents:`none`}}}},xe={inherit:`edge`,attrs:{line:{stroke:`#A2B1C3`,strokeWidth:2,targetMarker:{name:`block`,width:8,height:6,fill:`#A2B1C3`},cursor:`pointer`}}};function Se(e=!1){let t={background:e?`#18181c`:`#ffffff`,gridPrimary:e?`rgba(255, 255, 255, 0.08)`:`#eee`,gridSecondary:e?`rgba(255, 255, 255, 0.04)`:`#ddd`};return{background:{color:t.background},grid:{visible:!0,type:`doubleMesh`,args:[{color:t.gridPrimary,thickness:1},{color:t.gridSecondary,thickness:1,factor:4}]},mousewheel:{enabled:!0,zoomAtMousePosition:!0,modifiers:`ctrl`,minScale:.5,maxScale:3},connecting:{router:`manhattan`,connector:{name:`rounded`,args:{radius:8}},allowBlank:!1,allowLoop:!1,allowNode:!1,snap:!0,allowEdge:!1},highlighting:{magnetAvailable:{name:`stroke`,args:{attrs:{fill:`#31d0c6`,stroke:`#31d0c6`,opacity:1}}},magnetAdsorbed:{name:`stroke`,args:{attrs:{fill:`#5F95FF`,stroke:`#5F95FF`,opacity:1}}}},selecting:{enabled:!0,rubberband:!0,showNodeSelectionBox:!0},resizing:!0,rotating:!1,snapline:!0,keyboard:!0,clipboard:!0}}Se();const Ce={"start-event":{shape:`event`,width:50,height:50,label:`开始事件`,data:{type:`start`}},"end-event":{shape:`event`,width:50,height:50,label:`结束事件`,data:{type:`end`}},activity:{shape:`activity`,width:120,height:60,label:`新活动`,data:{description:``,assignee:``}},gateway:{shape:`gateway`,width:40,height:40,label:`+`,data:{type:`exclusive`}}},we=[{id:`start-1`,shape:`event`,x:100,y:200,width:50,height:50,label:`流程开始`,data:{type:`start`}},{id:`activity-1`,shape:`activity`,x:200,y:180,width:120,height:60,label:`用户申请`,data:{description:`用户提交申请表单`,assignee:`申请人`}},{id:`activity-2`,shape:`activity`,x:380,y:180,width:120,height:60,label:`初审`,data:{description:`部门进行初步审核`,assignee:`部门主管`}},{id:`gateway-1`,shape:`gateway`,x:550,y:200,width:40,height:40,label:`+`,data:{type:`exclusive`}},{id:`activity-3`,shape:`activity`,x:650,y:120,width:120,height:60,label:`终审`,data:{description:`高级主管最终审核`,assignee:`总监`}},{id:`activity-4`,shape:`activity`,x:650,y:260,width:120,height:60,label:`驳回处理`,data:{description:`处理驳回流程`,assignee:`专员`}},{id:`end-1`,shape:`event`,x:820,y:140,width:50,height:50,label:`审批通过`,data:{type:`end`}},{id:`end-2`,shape:`event`,x:820,y:280,width:50,height:50,label:`审批驳回`,data:{type:`end`}},{id:`edge-1`,shape:`bpmn-edge`,source:`start-1`,target:`activity-1`,x:0,y:0},{id:`edge-2`,shape:`bpmn-edge`,source:`activity-1`,target:`activity-2`,x:0,y:0},{id:`edge-3`,shape:`bpmn-edge`,source:`activity-2`,target:`gateway-1`,x:0,y:0},{id:`edge-4`,shape:`bpmn-edge`,source:`gateway-1`,target:`activity-3`,label:`通过`,x:0,y:0},{id:`edge-5`,shape:`bpmn-edge`,source:`gateway-1`,target:`activity-4`,label:`驳回`,x:0,y:0},{id:`edge-6`,shape:`bpmn-edge`,source:`activity-3`,target:`end-1`,x:0,y:0},{id:`edge-7`,shape:`bpmn-edge`,source:`activity-4`,target:`end-2`,x:0,y:0}],Te={key:0,class:`property-panel`},Ee={class:`property-item`},De={class:`property-item`},Oe={key:0,class:`property-item`},ke={key:1,class:`property-item`},Ae={class:`form-actions`};var je=O({__name:`BPMNPropertyEditor`,props:k({show:{type:Boolean}},{editingElement:{},editingElementModifiers:{}}),emits:k([`update:show`,`save`,`delete`],[`update:editingElement`]),setup(e,{emit:t}){let n=H(e,`editingElement`),i=t,a=x(()=>ve[n.value?.shape]||n.value?.shape||``);return(e,t)=>(I(),S(V(s),{show:e.show,width:`300`,title:`属性设置`,"onUpdate:show":t[6]||=e=>i(`update:show`,e)},{default:W(()=>[n.value?(I(),w(`div`,Te,[T(`div`,Ee,[t[7]||=T(`div`,{class:`property-label`},`名称`,-1),D(V(m),{value:n.value.label,"onUpdate:value":t[0]||=e=>n.value.label=e,placeholder:`请输入名称`,size:`small`},null,8,[`value`])]),T(`div`,De,[t[8]||=T(`div`,{class:`property-label`},`类型`,-1),D(V(m),{value:a.value,readonly:``,size:`small`},null,8,[`value`])]),n.value.shape===`activity`?(I(),w(`div`,Oe,[t[9]||=T(`div`,{class:`property-label`},`描述`,-1),D(V(m),{value:n.value.description,"onUpdate:value":t[1]||=e=>n.value.description=e,type:`textarea`,rows:3,placeholder:`请输入活动描述`,size:`small`},null,8,[`value`])])):C(`v-if`,!0),n.value.shape===`activity`?(I(),w(`div`,ke,[t[10]||=T(`div`,{class:`property-label`},`执行人`,-1),D(V(m),{value:n.value.assignee,"onUpdate:value":t[2]||=e=>n.value.assignee=e,placeholder:`请输入执行人`,size:`small`},null,8,[`value`])])):C(`v-if`,!0),T(`div`,Ae,[D(V(v),null,{default:W(()=>[D(V(r),{onClick:t[3]||=e=>i(`save`),type:`primary`,size:`small`},{default:W(()=>t[11]||=[E(` 保存 `,-1)]),_:1,__:[11]}),D(V(r),{onClick:t[4]||=e=>i(`update:show`,!1),size:`small`},{default:W(()=>t[12]||=[E(` 取消 `,-1)]),_:1,__:[12]}),D(V(r),{onClick:t[5]||=e=>i(`delete`),type:`error`,size:`small`},{default:W(()=>t[13]||=[E(` 删除 `,-1)]),_:1,__:[13]})]),_:1})])])):C(`v-if`,!0)]),_:1},8,[`show`]))}});const Me={class:`bpmn-layout`},Ne={key:0,class:`top-toolbar`},Pe={class:`toolbar-section`},Fe={class:`toolbar-group`},Ie={class:`toolbar-group`},Le={class:`toolbar-group`},Re={class:`main-content`},ze={key:0,class:`left-panel`},Be={class:`element-grid`},Ve=[`onClick`,`title`],He={class:`graph-wrapper`};var Ue=t(O({__name:`index`,props:{data:{},showToolbar:{type:Boolean,default:!0},readonly:{type:Boolean,default:!1},width:{default:`100%`},height:{default:`600px`},theme:{}},emits:[`ready`,`data-change`],setup(t,{expose:n,emit:i}){let a=t,o=i,s=L(),{graph:c,initGraph:u,centerContent:d,zoomToFit:f}=Y(s,x(()=>a.theme===`dark`)),{exportOptions:p,handleExport:m}=Z(c,`bpmn-diagram`),{bindInteractions:h}=Q(c,{portPositions:$,onDataChange:()=>H()}),g=L(!1),_=L(),v=e=>String(e.attr(`text/text`)||e.attr(`label/text`)||``),y=e=>{if(!e)return[];if(Array.isArray(e))return e;let t=[];return Object.values(e).forEach(e=>{Array.isArray(e)&&t.push(...e)}),t},S=()=>{let e=$.map(e=>({tagName:`circle`,selector:`port-${e}`})),t=[`event`,`activity`,`gateway`],n={event:`circle`,activity:`rect`,gateway:`polygon`};t.forEach(t=>{G.registerNode(t,{...be[t],markup:[{tagName:n[t],selector:`body`},{tagName:`text`,selector:`text`},...e],attrs:{...be[t].attrs,...ye($,n[t])}},!0)}),G.registerEdge(`bpmn-edge`,xe,!0)},O=e=>{if(!c.value||!e.length)return;let t=e.map(e=>{let{data:t,...n}=e,r=e.shape===`bpmn-edge`?c.value.createEdge(n):c.value.createNode(n);return t&&r.setData(t),r});c.value.resetCells(t),setTimeout(()=>c.value.zoomToFit({padding:50,maxScale:1}),200)},k=e=>{if(!c.value)return;let t=Ce[e];if(!t)return;let n=c.value.options.width/2,r=c.value.options.height/2,{data:i,...a}={id:`${e}-${Date.now()}`,x:n+Math.random()*100-50,y:r+Math.random()*100-50,...t},o=c.value.createNode(a);i&&o.setData(i),c.value.addCell(o),H()},A=()=>{c.value?.clearCells(),H()},j=e=>{let t=e.getData()||{};_.value={id:e.id,shape:e.shape,label:v(e),description:t.description||``,assignee:t.assignee||``,x:0,y:0},g.value=!0},N=()=>{if(!c.value||!_.value)return;let e=c.value.getCellById(_.value.id);e&&(e.setData({description:_.value.description,assignee:_.value.assignee}),e.attr(`text/text`,_.value.label||``),e.attr(`label/text`,_.value.label||``)),g.value=!1,H()},F=()=>{!c.value||!_.value||(c.value.getCellById(_.value.id)?.remove(),g.value=!1,H())},z=()=>c.value?[...c.value.getNodes().map(e=>({id:e.id,shape:e.shape,x:e.getPosition().x,y:e.getPosition().y,width:e.getSize().width,height:e.getSize().height,label:v(e),data:e.getData()||{}})),...c.value.getEdges().map(e=>({id:e.id,shape:`bpmn-edge`,source:e.getSourceCellId()||``,target:e.getTargetCellId()||``,label:v(e),x:0,y:0}))]:[],H=()=>o(`data-change`,z());return U(c,e=>{e instanceof G&&(a.readonly||(h(),e.on(`node:dblclick`,({node:e})=>j(e)),e.on(`node:moved`,H)),o(`ready`,e),O(we))},{immediate:!0}),U(()=>a.data,e=>{if(!e||!c.value)return;let t=y(e);t.length>0&&O(t)},{deep:!0}),P(async()=>{S();let e=Se();await u({...e,connecting:{...e.connecting,createEdge:()=>c.value.createEdge({shape:`bpmn-edge`}),validateConnection:({sourceView:e,targetView:t,sourceMagnet:n,targetMagnet:r})=>e!==t&&!!n&&!!r&&n.getAttribute(`magnet`)===`true`&&r.getAttribute(`magnet`)===`true`}})}),n({getGraph:()=>c.value,getData:z,loadData:O}),(t,n)=>(I(),w(`div`,Me,[t.showToolbar?(I(),w(`div`,Ne,[T(`div`,Pe,[T(`div`,Fe,[D(V(r),{onClick:A,size:`small`},{icon:W(()=>[D(e,{name:`mdi:delete-outline`,size:16})]),default:W(()=>[n[3]||=E(` 清空 `,-1)]),_:1,__:[3]})]),T(`div`,Ie,[D(V(r),{onClick:V(d),size:`small`},{icon:W(()=>[D(e,{name:`mdi:image-filter-center-focus`,size:16})]),default:W(()=>[n[4]||=E(` 居中 `,-1)]),_:1,__:[4]},8,[`onClick`]),D(V(r),{onClick:V(f),size:`small`},{icon:W(()=>[D(e,{name:`mdi:fit-to-screen`,size:16})]),default:W(()=>[n[5]||=E(` 适应 `,-1)]),_:1,__:[5]},8,[`onClick`])]),T(`div`,Le,[D(V(l),{options:V(p),onSelect:n[0]||=e=>V(m)(e,z)},{default:W(()=>[D(V(r),{size:`small`},{icon:W(()=>[D(e,{name:`mdi:export`,size:16})]),default:W(()=>[n[6]||=E(` 导出 `,-1)]),_:1,__:[6]})]),_:1},8,[`options`])])])])):C(`v-if`,!0),T(`div`,Re,[t.showToolbar?(I(),w(`div`,ze,[n[7]||=T(`div`,{class:`panel-title`},`组件`,-1),T(`div`,Be,[(I(!0),w(b,null,R(V(_e),(e,t)=>(I(),w(`div`,{key:t,class:`element-item`,onClick:e=>k(t),title:e.title},[T(`div`,{class:M([`element-icon`,e.iconClass])},null,2),T(`span`,null,B(e.name),1)],8,Ve))),128))])])):C(`v-if`,!0),T(`div`,He,[T(`div`,{ref_key:`containerRef`,ref:s,class:`graph-container`},null,512)])]),D(je,{show:g.value,"editing-element":_.value,"onUpdate:editingElement":n[1]||=e=>_.value=e,"onUpdate:show":n[2]||=e=>g.value=e,onSave:N,onDelete:F},null,8,[`show`,`editing-element`])]))}}),[[`__scopeId`,`data-v-c27dede7`]]);const We={key:0,class:`class-editor`},Ge={class:`section`},Ke={class:`section-header`},qe={style:{"font-size":`13px`}},Je={class:`section`},Ye={class:`section-header`},Xe={style:{"font-size":`13px`}};var Ze=t(O({__name:`UMLClassEditor`,props:k({show:{type:Boolean}},{editingClass:{},editingClassModifiers:{}}),emits:k([`update:show`,`save`,`delete`],[`update:editingClass`]),setup(t,{emit:n}){let a=H(t,`editingClass`),c=n;return(t,n)=>(I(),S(V(s),{show:t.show,width:`450`,title:`编辑类`,"onUpdate:show":n[6]||=e=>c(`update:show`,e)},{default:W(()=>[a.value?(I(),w(`div`,We,[D(V(u),{"label-placement":`top`},{default:W(()=>[D(V(d),{label:`类名`},{default:W(()=>[D(V(m),{value:a.value.name,"onUpdate:value":n[0]||=e=>a.value.name=e,placeholder:`请输入类名`},null,8,[`value`])]),_:1}),D(V(o),{style:{margin:`20px 0`}},{default:W(()=>n[7]||=[E(`属性`,-1)]),_:1,__:[7]}),T(`div`,Ge,[(I(!0),w(b,null,R(a.value.attributes,(e,t)=>(I(),w(`div`,{key:t,class:`item`},[D(V(i),{size:`small`,style:{"margin-bottom":`12px`}},{header:W(()=>[T(`div`,Ke,[T(`span`,qe,`#`+B(t+1)+` `+B(e.name||`新属性`),1),D(V(r),{onClick:e=>a.value.attributes.splice(t,1),size:`tiny`,type:`error`,quaternary:``,style:{"margin-left":`auto`}},{default:W(()=>n[8]||=[E(` 删除 `,-1)]),_:2,__:[8]},1032,[`onClick`])])]),default:W(()=>[D(V(v),{vertical:``,size:`small`},{default:W(()=>[D(V(v),null,{default:W(()=>[D(V(d),{label:`属性名`,style:{margin:`0`,flex:`1`}},{default:W(()=>[D(V(m),{value:e.name,"onUpdate:value":t=>e.name=t,placeholder:`属性名`,size:`small`},null,8,[`value`,`onUpdate:value`])]),_:2},1024),D(V(d),{label:`类型`,style:{margin:`0`,flex:`1`}},{default:W(()=>[D(V(m),{value:e.type,"onUpdate:value":t=>e.type=t,placeholder:`类型`,size:`small`},null,8,[`value`,`onUpdate:value`])]),_:2},1024)]),_:2},1024),D(V(d),{label:`可见性`,style:{margin:`0`}},{default:W(()=>[D(V(g),{value:e.visibility,"onUpdate:value":t=>e.visibility=t,size:`small`},{default:W(()=>[D(V(h),{value:`public`},{default:W(()=>n[9]||=[E(`+ public`,-1)]),_:1,__:[9]}),D(V(h),{value:`private`},{default:W(()=>n[10]||=[E(`- private`,-1)]),_:1,__:[10]}),D(V(h),{value:`protected`},{default:W(()=>n[11]||=[E(`# protected`,-1)]),_:1,__:[11]})]),_:2},1032,[`value`,`onUpdate:value`])]),_:2},1024)]),_:2},1024)]),_:2},1024)]))),128)),D(V(r),{onClick:n[1]||=e=>a.value.attributes.push({name:`newAttribute`,type:`string`,visibility:`private`}),dashed:``,block:``,type:`primary`,ghost:``,size:`small`},{icon:W(()=>[D(e,{name:`mdi:plus`,size:16})]),default:W(()=>[n[12]||=E(` 添加属性 `,-1)]),_:1,__:[12]})]),D(V(o),{style:{margin:`20px 0`}},{default:W(()=>n[13]||=[E(`方法`,-1)]),_:1,__:[13]}),T(`div`,Je,[(I(!0),w(b,null,R(a.value.methods,(e,t)=>(I(),w(`div`,{key:t,class:`item`},[D(V(i),{size:`small`,style:{"margin-bottom":`12px`}},{header:W(()=>[T(`div`,Ye,[T(`span`,Xe,`#`+B(t+1)+` `+B(e.name||`新方法`),1),D(V(r),{onClick:e=>a.value.methods.splice(t,1),size:`tiny`,type:`error`,quaternary:``,style:{"margin-left":`auto`}},{default:W(()=>n[14]||=[E(` 删除 `,-1)]),_:2,__:[14]},1032,[`onClick`])])]),default:W(()=>[D(V(v),{vertical:``,size:`small`},{default:W(()=>[D(V(v),null,{default:W(()=>[D(V(d),{label:`方法名`,style:{margin:`0`,flex:`1`}},{default:W(()=>[D(V(m),{value:e.name,"onUpdate:value":t=>e.name=t,placeholder:`方法名`,size:`small`},null,8,[`value`,`onUpdate:value`])]),_:2},1024),D(V(d),{label:`返回类型`,style:{margin:`0`,flex:`1`}},{default:W(()=>[D(V(m),{value:e.returnType,"onUpdate:value":t=>e.returnType=t,placeholder:`返回类型`,size:`small`},null,8,[`value`,`onUpdate:value`])]),_:2},1024)]),_:2},1024),D(V(d),{label:`可见性`,style:{margin:`0`}},{default:W(()=>[D(V(g),{value:e.visibility,"onUpdate:value":t=>e.visibility=t,size:`small`},{default:W(()=>[D(V(h),{value:`public`},{default:W(()=>n[15]||=[E(`+ public`,-1)]),_:1,__:[15]}),D(V(h),{value:`private`},{default:W(()=>n[16]||=[E(`- private`,-1)]),_:1,__:[16]}),D(V(h),{value:`protected`},{default:W(()=>n[17]||=[E(`# protected`,-1)]),_:1,__:[17]})]),_:2},1032,[`value`,`onUpdate:value`])]),_:2},1024)]),_:2},1024)]),_:2},1024)]))),128)),D(V(r),{onClick:n[2]||=e=>a.value.methods.push({name:`newMethod`,returnType:`void`,visibility:`public`}),dashed:``,block:``,type:`primary`,ghost:``,size:`small`},{icon:W(()=>[D(e,{name:`mdi:plus`,size:16})]),default:W(()=>[n[18]||=E(` 添加方法 `,-1)]),_:1,__:[18]})]),D(V(o),{style:{margin:`20px 0`}}),D(V(v),{justify:`space-between`},{default:W(()=>[D(V(r),{onClick:n[3]||=e=>c(`delete`),type:`error`,ghost:``},{icon:W(()=>[D(e,{name:`mdi:delete`,size:16})]),default:W(()=>[n[19]||=E(` 删除类 `,-1)]),_:1,__:[19]}),D(V(v),null,{default:W(()=>[D(V(r),{onClick:n[4]||=e=>c(`update:show`,!1)},{default:W(()=>n[20]||=[E(`取消`,-1)]),_:1,__:[20]}),D(V(r),{onClick:n[5]||=e=>c(`save`),type:`primary`},{default:W(()=>n[21]||=[E(` 保存 `,-1)]),_:1,__:[21]})]),_:1})]),_:1})]),_:1})])):C(`v-if`,!0)]),_:1},8,[`show`]))}}),[[`__scopeId`,`data-v-e47033f6`]]);const Qe={public:`+`,private:`-`,protected:`#`},$e={extends:{strokeDasharray:0,targetMarker:{name:`block`,width:10,height:8,fill:`white`,stroke:`#722ed1`,strokeWidth:2}},implement:{strokeDasharray:`8,4`,targetMarker:{name:`block`,width:10,height:8,fill:`white`,stroke:`#722ed1`,strokeWidth:2}},composition:{strokeDasharray:0,sourceMarker:{name:`diamond`,width:12,height:8,fill:`#722ed1`,stroke:`#722ed1`}},aggregation:{strokeDasharray:0,sourceMarker:{name:`diamond`,width:12,height:8,fill:`white`,stroke:`#722ed1`,strokeWidth:2}},association:{strokeDasharray:0,targetMarker:{name:`classic`,size:8,fill:`#722ed1`}}},et=[`top`,`right`,`bottom`,`left`].reduce((e,t)=>{let n=t===`top`?{refX:.5,refY:0}:t===`right`?{refX:1,refY:.5}:t===`bottom`?{refX:.5,refY:1}:{refX:0,refY:.5};return e[`port-${t}`]={ref:`body`,...n,r:4,fill:`#31d0c6`,stroke:`#ffffff`,strokeWidth:2,magnet:!0,style:{cursor:`crosshair`,opacity:0,transition:`opacity 0.2s`}},e},{}),tt={inherit:`rect`,markup:[{tagName:`rect`,selector:`body`},{tagName:`rect`,selector:`name-rect`},{tagName:`rect`,selector:`attrs-rect`},{tagName:`rect`,selector:`methods-rect`},{tagName:`text`,selector:`name-text`},{tagName:`text`,selector:`attrs-text`},{tagName:`text`,selector:`methods-text`},{tagName:`circle`,selector:`port-top`},{tagName:`circle`,selector:`port-right`},{tagName:`circle`,selector:`port-bottom`},{tagName:`circle`,selector:`port-left`}],attrs:{rect:{width:160},body:{stroke:`#5f95ff`,strokeWidth:1,fill:`#fff`,magnet:!1,style:{cursor:`move`}},"name-rect":{fill:`#5f95ff`,stroke:`#fff`,strokeWidth:.5,magnet:!1,style:{cursor:`move`}},"attrs-rect":{fill:`#eff4ff`,stroke:`#fff`,strokeWidth:.5,magnet:!1,style:{cursor:`move`}},"methods-rect":{fill:`#eff4ff`,stroke:`#fff`,strokeWidth:.5,magnet:!1,style:{cursor:`move`}},"name-text":{ref:`name-rect`,refY:.5,refX:.5,textAnchor:`middle`,fontWeight:`bold`,fill:`#fff`,fontSize:12,pointerEvents:`none`},"attrs-text":{ref:`attrs-rect`,refY:.5,refX:5,textAnchor:`left`,fill:`black`,fontSize:10,pointerEvents:`none`},"methods-text":{ref:`methods-rect`,refY:.5,refX:5,textAnchor:`left`,fill:`black`,fontSize:10,pointerEvents:`none`},...et}},nt={router:`manhattan`,connector:{name:`rounded`,args:{radius:8}},allowBlank:!1,allowLoop:!1,allowNode:!1,snap:!0,allowEdge:!1},rt={magnetAvailable:{name:`stroke`,args:{attrs:{fill:`#31d0c6`,stroke:`#31d0c6`,opacity:1}}},magnetAdsorbed:{name:`stroke`,args:{attrs:{fill:`#5F95FF`,stroke:`#5F95FF`,opacity:1}}}},it={shape:`extends`,attrs:{line:{stroke:`#722ed1`,strokeWidth:2,targetMarker:{name:`block`,width:8,height:6,fill:`#722ed1`}}}},at=[{id:`animal`,name:`<<Abstract>>
2
+ 动物`,x:342,y:98,attributes:[{name:`名字`,type:`string`,visibility:`public`}],methods:[{name:`新陈代谢`,returnType:`void`,visibility:`public`},{name:`繁殖`,returnType:`void`,visibility:`public`}]},{id:`bird`,name:`鸟`,x:575,y:280,attributes:[{name:`羽毛`,type:`string`,visibility:`public`},{name:`下蛋`,type:`boolean`,visibility:`public`}],methods:[]},{id:`mammal`,name:`哺乳动物`,x:844,y:319,attributes:[{name:`翅膀`,type:`boolean`,visibility:`public`}],methods:[]},{id:`dog`,name:`狗`,x:656,y:456,attributes:[{name:`下蛋`,type:`boolean`,visibility:`public`}],methods:[]},{id:`enterprise`,name:`企鹅`,x:984,y:456,attributes:[{name:`下蛋`,type:`boolean`,visibility:`public`}],methods:[]},{id:`sparrow`,name:`麻雀`,x:531,y:608,attributes:[{name:`学飞`,type:`boolean`,visibility:`public`}],methods:[]},{id:`interface-flying`,name:`<<interface>>
3
+ 飞翔`,x:762,y:608,attributes:[{name:`下蛋`,type:`boolean`,visibility:`public`}],methods:[]},{id:`qemu`,name:`气球`,x:981,y:608,attributes:[],methods:[]}],ot=[{id:`edge-1`,shape:`extends`,source:`bird`,target:`animal`},{id:`edge-2`,shape:`extends`,source:`mammal`,target:`animal`},{id:`edge-3`,shape:`extends`,source:`dog`,target:`mammal`},{id:`edge-4`,shape:`extends`,source:`enterprise`,target:`mammal`},{id:`edge-5`,shape:`extends`,source:`sparrow`,target:`bird`},{id:`edge-6`,shape:`implement`,source:`sparrow`,target:`interface-flying`},{id:`edge-7`,shape:`implement`,source:`enterprise`,target:`interface-flying`},{id:`edge-8`,shape:`association`,source:`bird`,target:`mammal`,label:`1:2`}],st=e=>Qe[e]||`+`,ct={name:`新类`,attributes:[{name:`attribute`,type:`string`,visibility:`private`}],methods:[{name:`method`,returnType:`void`,visibility:`public`}],position:{x:100,y:100}},lt={class:`uml-layout`},ut={key:0,class:`toolbar`};var dt=t(O({__name:`index`,props:{data:{},showToolbar:{type:Boolean,default:!0},readonly:{type:Boolean,default:!1},width:{default:`100%`},height:{default:`600px`},theme:{}},emits:[`ready`,`data-change`],setup(t,{expose:n,emit:i}){let a=t,o=i,s=L(),{graph:c,initGraph:u,centerContent:d,zoomToFit:f}=Y(s,x(()=>a.theme===`dark`)),{exportOptions:p,handleExport:m}=Z(c,`uml-diagram`),{bindInteractions:h}=Q(c,{defaultColor:`#722ed1`,portPositions:[`top`,`right`,`bottom`,`left`],onDataChange:()=>F()}),g=L(!1),_=L(),y=()=>{G.registerNode(`class`,{...tt,propHooks(e){let{name:t,attributes:n,methods:r,...i}=e;if(!(t&&n&&r))return e;let a=0;return[{type:`name`,text:t},{type:`attrs`,text:n},{type:`methods`,text:r}].forEach(e=>{let t=Array.isArray(e.text)?e.text.length*12+16:32;K.setByPath(i,`attrs/${e.type}-text/text`,Array.isArray(e.text)?e.text.join(`
4
+ `):e.text),K.setByPath(i,`attrs/${e.type}-rect/height`,t),K.setByPath(i,`attrs/${e.type}-rect/transform`,`translate(0,${a})`),a+=t}),i.size={width:160,height:a},i}},!0),Object.entries($e).forEach(([e,t])=>{G.registerEdge(e,{inherit:`edge`,attrs:{line:{strokeWidth:2,stroke:`#722ed1`,...t}}},!0)})},b=e=>{if(!c.value||!e.length)return;let t=[`extends`,`composition`,`implement`,`aggregation`,`association`],n=[];e.forEach(e=>{if(t.includes(e.shape))n.push(c.value.createEdge(e));else{let{data:t,...r}=e,i=c.value.createNode(r);t&&i.setData(t),n.push(i)}}),c.value.resetCells(n),setTimeout(()=>c.value.zoomToFit({padding:10,maxScale:1}),200)},S=e=>({name:e.name,attributes:e.attributes.map(e=>`${st(e.visibility)} ${e.name}: ${e.type}`),methods:e.methods.map(e=>`${st(e.visibility)} ${e.name}(): ${e.returnType}`)}),O=()=>{if(!c.value)return;let e={id:`class_${Date.now()}`,...ct},t={id:e.id,shape:`class`,x:e.position.x,y:e.position.y,...S(e),data:e};c.value.addCell(c.value.createNode(t)),F()},k=e=>{_.value={...e,attributes:[...e.attributes||[]],methods:[...e.methods||[]]},g.value=!0},A=()=>{if(!c.value||!_.value)return;let e=c.value.getCellById(_.value.id);e&&(e.setData(_.value),e.prop(S(_.value))),g.value=!1,F()},j=()=>{!c.value||!_.value||(c.value.getCellById(_.value.id)?.remove(),g.value=!1,F())},M=()=>({classes:c.value?.getNodes().map(e=>({...e.getData(),position:e.getPosition()}))||[],relations:c.value?.getEdges().map(e=>({id:e.id,type:e.shape,source:e.getSourceCellId()||``,target:e.getTargetCellId()||``}))||[]}),F=()=>o(`data-change`,M());return U(c,e=>{e instanceof G&&(y(),h(),e.on(`node:dblclick`,({node:e})=>{!a.readonly&&e.getData()&&k(e.getData())}),o(`ready`,e),b([...at.map(e=>({id:e.id,shape:`class`,x:e.x,y:e.y,...S(e),data:{id:e.id,name:e.name,attributes:e.attributes,methods:e.methods,position:{x:e.x,y:e.y}}})),...ot]))},{immediate:!0}),U(()=>a.data,e=>{if(c.value&&e?.classes){let t=[`extends`,`composition`,`implement`,`aggregation`,`association`];b([...e.classes.map(e=>({id:e.id,shape:`class`,x:e.position?.x??50,y:e.position?.y??50,...S(e),data:e})),...(e.relations||[]).filter(e=>t.includes(e.type)).map(e=>({shape:e.type,source:e.source,target:e.target}))])}},{deep:!0}),P(()=>{u({interacting:!0,connecting:{...nt,createEdge:()=>c.value.createEdge(it),validateConnection:({sourceView:e,targetView:t,sourceMagnet:n,targetMagnet:r})=>e!==t&&!!n&&!!r&&n.getAttribute(`magnet`)===`true`&&r.getAttribute(`magnet`)===`true`},highlighting:rt})}),n({getGraph:()=>c.value,getData:M,addClass:O,centerContent:d,zoomToFit:f}),(t,n)=>(I(),w(`div`,lt,[t.showToolbar?(I(),w(`div`,ut,[D(V(v),null,{default:W(()=>[D(V(r),{onClick:O,type:`primary`,size:`small`},{icon:W(()=>[D(e,{name:`mdi:plus-box`,size:16})]),default:W(()=>[n[3]||=E(` 添加类 `,-1)]),_:1,__:[3]}),D(V(r),{onClick:V(d),size:`small`},{icon:W(()=>[D(e,{name:`mdi:image-filter-center-focus`,size:16})]),default:W(()=>[n[4]||=E(` 居中 `,-1)]),_:1,__:[4]},8,[`onClick`]),D(V(r),{onClick:V(f),size:`small`},{icon:W(()=>[D(e,{name:`mdi:fit-to-screen`,size:16})]),default:W(()=>[n[5]||=E(` 适应 `,-1)]),_:1,__:[5]},8,[`onClick`]),D(V(l),{options:V(p),onSelect:n[0]||=e=>V(m)(e,M)},{default:W(()=>[D(V(r),{size:`small`},{icon:W(()=>[D(e,{name:`mdi:export`,size:16})]),default:W(()=>[n[6]||=E(` 导出 `,-1)]),_:1,__:[6]})]),_:1},8,[`options`])]),_:1})])):C(`v-if`,!0),T(`div`,{ref_key:`containerRef`,ref:s,class:`graph-container`,style:N({width:a.width,height:a.height})},null,4),D(Ze,{show:g.value,"editing-class":_.value,"onUpdate:editingClass":n[1]||=e=>_.value=e,"onUpdate:show":n[2]||=e=>g.value=e,onSave:A,onDelete:j},null,8,[`show`,`editing-class`])]))}}),[[`__scopeId`,`data-v-1092fbdb`]]);const ft={class:`c-antv-container`};var pt=t(O({name:`C_AntV`,__name:`index`,props:{type:{},data:{},width:{default:`100%`},height:{default:`600px`},readonly:{type:Boolean,default:!1},showToolbar:{type:Boolean,default:!0},theme:{default:`light`}},emits:[`ready`,`data-change`],setup(e,{expose:t,emit:n}){let r=e,i=n,a=L(),o={er:he,bpmn:Ue,uml:dt},s=x(()=>o[r.type]),c=x(()=>{let e={width:r.width,height:r.height,readonly:r.readonly,showToolbar:r.showToolbar,theme:r.theme},t=r.data;if(r.type===`bpmn`&&r.data){let e=r.data;e&&typeof e==`object`&&`nodes`in e&&`edges`in e&&(t=[...(e.nodes||[]).map(e=>({...e,shape:e.type||e.shape||`rect`,x:e.x??0,y:e.y??0})),...(e.edges||[]).map(e=>({...e,shape:`edge`,x:0,y:0}))])}return{...e,data:t}}),l=e=>{i(`ready`,e)},u=e=>{let t;t=r.type===`bpmn`&&Array.isArray(e)?{nodes:e.filter(e=>e.shape!==`edge`).map(e=>{let{shape:t,x:n,y:r,...i}=e;return{...i,type:t===`rect`?`task`:t,x:n||0,y:r||0}}),edges:e.filter(e=>e.shape===`edge`).map(e=>{let{shape:t,x:n,y:r,...i}=e;return i}),flows:[]}:e,i(`data-change`,t)};return t({getGraph:()=>a.value?.getGraph?.(),getData:()=>{let e=a.value?.getData?.();return r.type===`bpmn`&&Array.isArray(e)?{nodes:e.filter(e=>e.shape!==`edge`),edges:e.filter(e=>e.shape===`edge`),flows:[]}:e}}),(e,t)=>(I(),w(`div`,ft,[(I(),S(z(s.value),A(c.value,{onReady:l,onDataChange:u,ref_key:`layoutRef`,ref:a}),null,16))]))}}),[[`__scopeId`,`data-v-f1ab77ea`]]);export{Y as i,Q as n,Z as r,pt as t};
3150
5
  //# sourceMappingURL=C_AntV2.js.map