@robot-admin/naive-ui-components 0.3.0

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 (352) hide show
  1. package/README.md +257 -0
  2. package/dist/C_ActionBar-DWN-woTc.css.map +1 -0
  3. package/dist/C_ActionBar.cjs +5 -0
  4. package/dist/C_ActionBar.d.cts +2 -0
  5. package/dist/C_ActionBar.d.ts +2 -0
  6. package/dist/C_ActionBar.js +4 -0
  7. package/dist/C_ActionBar2.js +196 -0
  8. package/dist/C_ActionBar2.js.map +1 -0
  9. package/dist/C_AntV-AFKyK6hH.css.map +1 -0
  10. package/dist/C_AntV.cjs +8 -0
  11. package/dist/C_AntV.d.cts +2 -0
  12. package/dist/C_AntV.d.ts +2 -0
  13. package/dist/C_AntV.js +4 -0
  14. package/dist/C_AntV2.js +3150 -0
  15. package/dist/C_AntV2.js.map +1 -0
  16. package/dist/C_Barcode-P_EFj8dC.css.map +1 -0
  17. package/dist/C_Barcode.cjs +4 -0
  18. package/dist/C_Barcode.d.cts +2 -0
  19. package/dist/C_Barcode.d.ts +2 -0
  20. package/dist/C_Barcode.js +3 -0
  21. package/dist/C_Barcode2.js +68 -0
  22. package/dist/C_Barcode2.js.map +1 -0
  23. package/dist/C_Captcha-C-ef41xw.css.map +1 -0
  24. package/dist/C_Captcha.cjs +4 -0
  25. package/dist/C_Captcha.d.cts +2 -0
  26. package/dist/C_Captcha.d.ts +2 -0
  27. package/dist/C_Captcha.js +3 -0
  28. package/dist/C_Captcha2.js +155 -0
  29. package/dist/C_Captcha2.js.map +1 -0
  30. package/dist/C_Cascade-D9kNsjsV.css.map +1 -0
  31. package/dist/C_Cascade.cjs +4 -0
  32. package/dist/C_Cascade.d.cts +2 -0
  33. package/dist/C_Cascade.d.ts +2 -0
  34. package/dist/C_Cascade.js +3 -0
  35. package/dist/C_Cascade2.js +103 -0
  36. package/dist/C_Cascade2.js.map +1 -0
  37. package/dist/C_City-BCQ4ipiK.css.map +1 -0
  38. package/dist/C_City.cjs +4 -0
  39. package/dist/C_City.d.cts +2 -0
  40. package/dist/C_City.d.ts +2 -0
  41. package/dist/C_City.js +3 -0
  42. package/dist/C_City2.js +841 -0
  43. package/dist/C_City2.js.map +1 -0
  44. package/dist/C_Code-C9kvvEmO.css.map +1 -0
  45. package/dist/C_Code.cjs +5 -0
  46. package/dist/C_Code.d.cts +2 -0
  47. package/dist/C_Code.d.ts +2 -0
  48. package/dist/C_Code.js +4 -0
  49. package/dist/C_Code2.js +346 -0
  50. package/dist/C_Code2.js.map +1 -0
  51. package/dist/C_CollapsePanel-BUJHuYcU.css.map +1 -0
  52. package/dist/C_CollapsePanel.cjs +6 -0
  53. package/dist/C_CollapsePanel.d.cts +2 -0
  54. package/dist/C_CollapsePanel.d.ts +2 -0
  55. package/dist/C_CollapsePanel.js +4 -0
  56. package/dist/C_CollapsePanel2.js +319 -0
  57. package/dist/C_CollapsePanel2.js.map +1 -0
  58. package/dist/C_Cron-yx2Ob4Jl.css.map +1 -0
  59. package/dist/C_Cron.cjs +15 -0
  60. package/dist/C_Cron.d.cts +2 -0
  61. package/dist/C_Cron.d.ts +2 -0
  62. package/dist/C_Cron.js +4 -0
  63. package/dist/C_Cron2.js +1209 -0
  64. package/dist/C_Cron2.js.map +1 -0
  65. package/dist/C_Date.cjs +4 -0
  66. package/dist/C_Date.d.cts +2 -0
  67. package/dist/C_Date.d.ts +2 -0
  68. package/dist/C_Date.js +3 -0
  69. package/dist/C_Date2.js +219 -0
  70. package/dist/C_Date2.js.map +1 -0
  71. package/dist/C_Draggable-C483syRC.css.map +1 -0
  72. package/dist/C_Draggable.cjs +5 -0
  73. package/dist/C_Draggable.d.cts +2 -0
  74. package/dist/C_Draggable.d.ts +2 -0
  75. package/dist/C_Draggable.js +3 -0
  76. package/dist/C_Draggable2.js +295 -0
  77. package/dist/C_Draggable2.js.map +1 -0
  78. package/dist/C_Editor-Bp0SyIEw.css.map +1 -0
  79. package/dist/C_Editor.cjs +4 -0
  80. package/dist/C_Editor.d.cts +2 -0
  81. package/dist/C_Editor.d.ts +2 -0
  82. package/dist/C_Editor.js +3 -0
  83. package/dist/C_Editor2.js +160 -0
  84. package/dist/C_Editor2.js.map +1 -0
  85. package/dist/C_FilePreview-CPqvhoCy.css.map +1 -0
  86. package/dist/C_FilePreview.cjs +6 -0
  87. package/dist/C_FilePreview.d.cts +2 -0
  88. package/dist/C_FilePreview.d.ts +2 -0
  89. package/dist/C_FilePreview.js +3 -0
  90. package/dist/C_FilePreview2.js +1031 -0
  91. package/dist/C_FilePreview2.js.map +1 -0
  92. package/dist/C_Form-Jx7PY3sT.css.map +1 -0
  93. package/dist/C_Form.cjs +15 -0
  94. package/dist/C_Form.d.cts +2 -0
  95. package/dist/C_Form.d.ts +2 -0
  96. package/dist/C_Form.js +4 -0
  97. package/dist/C_Form2.js +2510 -0
  98. package/dist/C_Form2.js.map +1 -0
  99. package/dist/C_FormSearch-DvRgxlRn.css.map +1 -0
  100. package/dist/C_FormSearch.cjs +6 -0
  101. package/dist/C_FormSearch.d.cts +2 -0
  102. package/dist/C_FormSearch.d.ts +2 -0
  103. package/dist/C_FormSearch.js +3 -0
  104. package/dist/C_FormSearch2.js +356 -0
  105. package/dist/C_FormSearch2.js.map +1 -0
  106. package/dist/C_FormulaEditor-DtGkt4T_.css.map +1 -0
  107. package/dist/C_FormulaEditor.cjs +13 -0
  108. package/dist/C_FormulaEditor.d.cts +2 -0
  109. package/dist/C_FormulaEditor.d.ts +2 -0
  110. package/dist/C_FormulaEditor.js +4 -0
  111. package/dist/C_FormulaEditor2.js +1433 -0
  112. package/dist/C_FormulaEditor2.js.map +1 -0
  113. package/dist/C_FullCalendar-BF7H0YIx.css.map +1 -0
  114. package/dist/C_FullCalendar.cjs +9 -0
  115. package/dist/C_FullCalendar.d.cts +2 -0
  116. package/dist/C_FullCalendar.d.ts +2 -0
  117. package/dist/C_FullCalendar.js +3 -0
  118. package/dist/C_FullCalendar2.js +377 -0
  119. package/dist/C_FullCalendar2.js.map +1 -0
  120. package/dist/C_Guide.cjs +4 -0
  121. package/dist/C_Guide.d.cts +2 -0
  122. package/dist/C_Guide.d.ts +2 -0
  123. package/dist/C_Guide.js +3 -0
  124. package/dist/C_Guide2.js +58 -0
  125. package/dist/C_Guide2.js.map +1 -0
  126. package/dist/C_Icon.cjs +4 -0
  127. package/dist/C_Icon.d.cts +2 -0
  128. package/dist/C_Icon.d.ts +2 -0
  129. package/dist/C_Icon.js +3 -0
  130. package/dist/C_Icon2.js +286 -0
  131. package/dist/C_Icon2.js.map +1 -0
  132. package/dist/C_ImageCropper-BVJfUufl.css.map +1 -0
  133. package/dist/C_ImageCropper.cjs +6 -0
  134. package/dist/C_ImageCropper.d.cts +2 -0
  135. package/dist/C_ImageCropper.d.ts +2 -0
  136. package/dist/C_ImageCropper.js +4 -0
  137. package/dist/C_ImageCropper2.js +723 -0
  138. package/dist/C_ImageCropper2.js.map +1 -0
  139. package/dist/C_Language.cjs +4 -0
  140. package/dist/C_Language.d.cts +2 -0
  141. package/dist/C_Language.d.ts +2 -0
  142. package/dist/C_Language.js +3 -0
  143. package/dist/C_Language2.js +72 -0
  144. package/dist/C_Language2.js.map +1 -0
  145. package/dist/C_Map-DpzeuWdX.css.map +1 -0
  146. package/dist/C_Map.cjs +7 -0
  147. package/dist/C_Map.d.cts +2 -0
  148. package/dist/C_Map.d.ts +2 -0
  149. package/dist/C_Map.js +3 -0
  150. package/dist/C_Map2.js +199 -0
  151. package/dist/C_Map2.js.map +1 -0
  152. package/dist/C_Markdown-BEjxknqd.css.map +1 -0
  153. package/dist/C_Markdown.cjs +4 -0
  154. package/dist/C_Markdown.d.cts +2 -0
  155. package/dist/C_Markdown.d.ts +2 -0
  156. package/dist/C_Markdown.js +3 -0
  157. package/dist/C_Markdown2.js +186 -0
  158. package/dist/C_Markdown2.js.map +1 -0
  159. package/dist/C_NotificationCenter-0l3TY2Gn.css.map +1 -0
  160. package/dist/C_NotificationCenter.cjs +20 -0
  161. package/dist/C_NotificationCenter.d.cts +2 -0
  162. package/dist/C_NotificationCenter.d.ts +2 -0
  163. package/dist/C_NotificationCenter.js +4 -0
  164. package/dist/C_NotificationCenter2.js +1383 -0
  165. package/dist/C_NotificationCenter2.js.map +1 -0
  166. package/dist/C_Progress.cjs +4 -0
  167. package/dist/C_Progress.d.cts +2 -0
  168. package/dist/C_Progress.d.ts +2 -0
  169. package/dist/C_Progress.js +3 -0
  170. package/dist/C_Progress2.js +103 -0
  171. package/dist/C_Progress2.js.map +1 -0
  172. package/dist/C_QRCode-DbdiAIPg.css.map +1 -0
  173. package/dist/C_QRCode.cjs +5 -0
  174. package/dist/C_QRCode.d.cts +2 -0
  175. package/dist/C_QRCode.d.ts +2 -0
  176. package/dist/C_QRCode.js +3 -0
  177. package/dist/C_QRCode2.js +218 -0
  178. package/dist/C_QRCode2.js.map +1 -0
  179. package/dist/C_Signature-zhHCbra9.css.map +1 -0
  180. package/dist/C_Signature.cjs +8 -0
  181. package/dist/C_Signature.d.cts +2 -0
  182. package/dist/C_Signature.d.ts +2 -0
  183. package/dist/C_Signature.js +4 -0
  184. package/dist/C_Signature2.js +618 -0
  185. package/dist/C_Signature2.js.map +1 -0
  186. package/dist/C_SplitPane-C6sBsfKY.css.map +1 -0
  187. package/dist/C_SplitPane.cjs +6 -0
  188. package/dist/C_SplitPane.d.cts +2 -0
  189. package/dist/C_SplitPane.d.ts +2 -0
  190. package/dist/C_SplitPane.js +4 -0
  191. package/dist/C_SplitPane2.js +356 -0
  192. package/dist/C_SplitPane2.js.map +1 -0
  193. package/dist/C_Steps-CODHN5Hs.css.map +1 -0
  194. package/dist/C_Steps.cjs +4 -0
  195. package/dist/C_Steps.d.cts +2 -0
  196. package/dist/C_Steps.d.ts +2 -0
  197. package/dist/C_Steps.js +3 -0
  198. package/dist/C_Steps2.js +82 -0
  199. package/dist/C_Steps2.js.map +1 -0
  200. package/dist/C_Table-DSNsntmT.css.map +1 -0
  201. package/dist/C_Table.cjs +19 -0
  202. package/dist/C_Table.d.cts +2 -0
  203. package/dist/C_Table.d.ts +2 -0
  204. package/dist/C_Table.js +5 -0
  205. package/dist/C_Table2.js +3009 -0
  206. package/dist/C_Table2.js.map +1 -0
  207. package/dist/C_Theme.cjs +4 -0
  208. package/dist/C_Theme.d.cts +2 -0
  209. package/dist/C_Theme.d.ts +2 -0
  210. package/dist/C_Theme.js +3 -0
  211. package/dist/C_Theme2.js +60 -0
  212. package/dist/C_Theme2.js.map +1 -0
  213. package/dist/C_Time-BvZLYraL.css.map +1 -0
  214. package/dist/C_Time.cjs +5 -0
  215. package/dist/C_Time.d.cts +2 -0
  216. package/dist/C_Time.d.ts +2 -0
  217. package/dist/C_Time.js +3 -0
  218. package/dist/C_Time2.js +199 -0
  219. package/dist/C_Time2.js.map +1 -0
  220. package/dist/C_Tree-0GDv--jX.css.map +1 -0
  221. package/dist/C_Tree.cjs +7 -0
  222. package/dist/C_Tree.d.cts +2 -0
  223. package/dist/C_Tree.d.ts +2 -0
  224. package/dist/C_Tree.js +4 -0
  225. package/dist/C_Tree2.js +441 -0
  226. package/dist/C_Tree2.js.map +1 -0
  227. package/dist/C_Upload-BXd3YYLx.css.map +1 -0
  228. package/dist/C_Upload.cjs +12 -0
  229. package/dist/C_Upload.d.cts +2 -0
  230. package/dist/C_Upload.d.ts +2 -0
  231. package/dist/C_Upload.js +4 -0
  232. package/dist/C_Upload2.js +1388 -0
  233. package/dist/C_Upload2.js.map +1 -0
  234. package/dist/C_VideoPlayer-DYG3RL0Q.css.map +1 -0
  235. package/dist/C_VideoPlayer.cjs +23 -0
  236. package/dist/C_VideoPlayer.d.cts +2 -0
  237. package/dist/C_VideoPlayer.d.ts +2 -0
  238. package/dist/C_VideoPlayer.js +3 -0
  239. package/dist/C_VideoPlayer2.js +1932 -0
  240. package/dist/C_VideoPlayer2.js.map +1 -0
  241. package/dist/C_VtableGantt-fhItIiHE.css.map +1 -0
  242. package/dist/C_VtableGantt.cjs +6 -0
  243. package/dist/C_VtableGantt.d.cts +2 -0
  244. package/dist/C_VtableGantt.d.ts +2 -0
  245. package/dist/C_VtableGantt.js +4 -0
  246. package/dist/C_VtableGantt2.js +873 -0
  247. package/dist/C_VtableGantt2.js.map +1 -0
  248. package/dist/C_WaterFall-8sQDFXKg.css.map +1 -0
  249. package/dist/C_WaterFall.cjs +13 -0
  250. package/dist/C_WaterFall.d.cts +2 -0
  251. package/dist/C_WaterFall.d.ts +2 -0
  252. package/dist/C_WaterFall.js +3 -0
  253. package/dist/C_WaterFall2.js +365 -0
  254. package/dist/C_WaterFall2.js.map +1 -0
  255. package/dist/C_WorkFlow-J-dyIuh9.css.map +1 -0
  256. package/dist/C_WorkFlow.cjs +8 -0
  257. package/dist/C_WorkFlow.d.cts +2 -0
  258. package/dist/C_WorkFlow.d.ts +2 -0
  259. package/dist/C_WorkFlow.js +4 -0
  260. package/dist/C_WorkFlow2.js +1984 -0
  261. package/dist/C_WorkFlow2.js.map +1 -0
  262. package/dist/chunk.js +22 -0
  263. package/dist/city.js +4817 -0
  264. package/dist/city.js.map +1 -0
  265. package/dist/constants.d.ts +273 -0
  266. package/dist/constants.d.ts.map +1 -0
  267. package/dist/constants2.d.ts +178 -0
  268. package/dist/constants2.d.ts.map +1 -0
  269. package/dist/constants3.d.ts +475 -0
  270. package/dist/constants3.d.ts.map +1 -0
  271. package/dist/constants4.d.ts +430 -0
  272. package/dist/constants4.d.ts.map +1 -0
  273. package/dist/constants5.d.ts +4283 -0
  274. package/dist/constants5.d.ts.map +1 -0
  275. package/dist/data.d.ts +67 -0
  276. package/dist/data.d.ts.map +1 -0
  277. package/dist/export-helper.js +9 -0
  278. package/dist/index.cjs +409 -0
  279. package/dist/index.d.cts +96 -0
  280. package/dist/index.d.cts.map +1 -0
  281. package/dist/index.d.ts +103 -0
  282. package/dist/index.d.ts.map +1 -0
  283. package/dist/index.js +230 -0
  284. package/dist/index.js.map +1 -0
  285. package/dist/index.vue.d.ts +80 -0
  286. package/dist/index.vue.d.ts.map +1 -0
  287. package/dist/index10.vue.d.ts +72 -0
  288. package/dist/index10.vue.d.ts.map +1 -0
  289. package/dist/index11.vue.d.ts +26 -0
  290. package/dist/index11.vue.d.ts.map +1 -0
  291. package/dist/index12.vue.d.ts +81 -0
  292. package/dist/index12.vue.d.ts.map +1 -0
  293. package/dist/index13.vue.d.ts +55 -0
  294. package/dist/index13.vue.d.ts.map +1 -0
  295. package/dist/index14.vue.d.ts +33 -0
  296. package/dist/index14.vue.d.ts.map +1 -0
  297. package/dist/index15.vue.d.ts +18 -0
  298. package/dist/index15.vue.d.ts.map +1 -0
  299. package/dist/index16.vue.d.ts +662 -0
  300. package/dist/index16.vue.d.ts.map +1 -0
  301. package/dist/index2.vue.d.ts +38 -0
  302. package/dist/index2.vue.d.ts.map +1 -0
  303. package/dist/index3.vue.d.ts +45 -0
  304. package/dist/index3.vue.d.ts.map +1 -0
  305. package/dist/index4.vue.d.ts +31 -0
  306. package/dist/index4.vue.d.ts.map +1 -0
  307. package/dist/index5.vue.d.ts +35 -0
  308. package/dist/index5.vue.d.ts.map +1 -0
  309. package/dist/index6.vue.d.ts +48 -0
  310. package/dist/index6.vue.d.ts.map +1 -0
  311. package/dist/index7.vue.d.ts +56 -0
  312. package/dist/index7.vue.d.ts.map +1 -0
  313. package/dist/index8.vue.d.ts +41 -0
  314. package/dist/index8.vue.d.ts.map +1 -0
  315. package/dist/index9.vue.d.ts +30 -0
  316. package/dist/index9.vue.d.ts.map +1 -0
  317. package/dist/storage.js +31 -0
  318. package/dist/storage.js.map +1 -0
  319. package/dist/style.css +7725 -0
  320. package/dist/useCalendarEvents.d.ts +148 -0
  321. package/dist/useCalendarEvents.d.ts.map +1 -0
  322. package/dist/useCollapsePanel.d.ts +132 -0
  323. package/dist/useCollapsePanel.d.ts.map +1 -0
  324. package/dist/useCropperCore.d.ts +102 -0
  325. package/dist/useCropperCore.d.ts.map +1 -0
  326. package/dist/useDraggableLayout.d.ts +194 -0
  327. package/dist/useDraggableLayout.d.ts.map +1 -0
  328. package/dist/useDynamicFormState.d.ts +4248 -0
  329. package/dist/useDynamicFormState.d.ts.map +1 -0
  330. package/dist/useEdgeInteraction.d.ts +7614 -0
  331. package/dist/useEdgeInteraction.d.ts.map +1 -0
  332. package/dist/useFullscreen.d.ts +166 -0
  333. package/dist/useFullscreen.d.ts.map +1 -0
  334. package/dist/useInfiniteScroll.d.ts +169 -0
  335. package/dist/useInfiniteScroll.d.ts.map +1 -0
  336. package/dist/useModalEdit.d.ts +960 -0
  337. package/dist/useModalEdit.d.ts.map +1 -0
  338. package/dist/useQRCode.d.ts +87 -0
  339. package/dist/useQRCode.d.ts.map +1 -0
  340. package/dist/useSearchState.d.ts +180 -0
  341. package/dist/useSearchState.d.ts.map +1 -0
  342. package/dist/useSignatureHistory.d.ts +189 -0
  343. package/dist/useSignatureHistory.d.ts.map +1 -0
  344. package/dist/useSplitResize.d.ts +158 -0
  345. package/dist/useSplitResize.d.ts.map +1 -0
  346. package/dist/useTimeSelection.d.ts +105 -0
  347. package/dist/useTimeSelection.d.ts.map +1 -0
  348. package/dist/useTreeOperations.d.ts +183 -0
  349. package/dist/useTreeOperations.d.ts.map +1 -0
  350. package/dist/useWorkflowValidation.d.ts +1052 -0
  351. package/dist/useWorkflowValidation.d.ts.map +1 -0
  352. package/package.json +342 -0
@@ -0,0 +1,3150 @@
1
+ import { t as C_Icon_default } from "./C_Icon2.js";
2
+ import { t as export_helper_default } from "./export-helper.js";
3
+ 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";
4
+ import { NAlert, NButton, NCard, NCheckbox, NDivider, NDrawer, NDrawerContent, NDropdown, NForm, NFormItem, NGi, NGrid, NInput, NRadio, NRadioGroup, NSelect, NSpace, useMessage } from "naive-ui";
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-c459e320"]]);
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-7e956ab3"]]);
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-e4ff5cc2"]]);
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-793e1533"]]);
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-b03826d0"]]);
3147
+
3148
+ //#endregion
3149
+ export { useGraphBase as i, useEdgeInteraction as n, useGraphExport as r, C_AntV_default as t };
3150
+ //# sourceMappingURL=C_AntV2.js.map