eoss 0.1.0-alpha.24 → 0.1.0-alpha.26

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 (309) hide show
  1. package/lib/0.js +1 -1
  2. package/lib/1.js +1 -1
  3. package/lib/10.js +1 -1
  4. package/lib/11.js +1 -1
  5. package/lib/12.js +1 -1
  6. package/lib/13.js +1 -1
  7. package/lib/14.js +1 -1
  8. package/lib/15.js +1 -1
  9. package/lib/16.js +1 -1
  10. package/lib/17.js +1 -1
  11. package/lib/18.js +1 -1
  12. package/lib/19.js +1 -1
  13. package/lib/20.js +1 -1
  14. package/lib/21.js +1 -1
  15. package/lib/22.js +1 -1
  16. package/lib/23.js +1 -1
  17. package/lib/24.js +1 -1
  18. package/lib/25.js +1 -1
  19. package/lib/26.js +1 -1
  20. package/lib/27.js +1 -1
  21. package/lib/28.js +1 -1
  22. package/lib/29.js +1 -1
  23. package/lib/3.js +1 -1
  24. package/lib/30.js +1 -1
  25. package/lib/31.js +1 -1
  26. package/lib/32.js +1 -1
  27. package/lib/33.js +1 -1
  28. package/lib/34.js +1 -1
  29. package/lib/35.js +1 -1
  30. package/lib/36.js +1 -1
  31. package/lib/37.js +1 -1
  32. package/lib/38.js +1 -1
  33. package/lib/39.js +1 -1
  34. package/lib/4.js +1 -1
  35. package/lib/40.js +1 -1
  36. package/lib/41.js +1 -1
  37. package/lib/42.js +1 -1
  38. package/lib/43.js +1 -1
  39. package/lib/44.js +1 -1
  40. package/lib/45.js +1 -1
  41. package/lib/46.js +1 -1
  42. package/lib/47.js +1 -1
  43. package/lib/48.js +1 -1
  44. package/lib/49.js +1 -1
  45. package/lib/5.js +1 -1
  46. package/lib/50.js +1 -1
  47. package/lib/51.js +1 -1
  48. package/lib/52.js +1 -1
  49. package/lib/53.js +1 -1
  50. package/lib/54.js +1 -1
  51. package/lib/55.js +1 -1
  52. package/lib/56.js +1 -1
  53. package/lib/57.js +1 -1
  54. package/lib/58.js +1 -1
  55. package/lib/59.js +1 -1
  56. package/lib/6.js +1 -1
  57. package/lib/60.js +1 -1
  58. package/lib/61.js +1 -1
  59. package/lib/62.js +1 -1
  60. package/lib/63.js +1 -1
  61. package/lib/64.js +1 -1
  62. package/lib/65.js +1 -1
  63. package/lib/66.js +1 -1
  64. package/lib/67.js +1 -1
  65. package/lib/68.js +1 -1
  66. package/lib/69.js +1 -1
  67. package/lib/7.js +1 -1
  68. package/lib/70.js +1 -1
  69. package/lib/71.js +1 -1
  70. package/lib/72.js +1 -1
  71. package/lib/73.js +1 -1
  72. package/lib/74.js +1 -1
  73. package/lib/75.js +1 -1
  74. package/lib/76.js +1 -1
  75. package/lib/77.js +1 -1
  76. package/lib/78.js +1 -1
  77. package/lib/79.js +1 -1
  78. package/lib/8.js +1 -1
  79. package/lib/80.js +1 -1
  80. package/lib/81.js +1 -1
  81. package/lib/9.js +1 -1
  82. package/lib/account-login.js +1554 -1437
  83. package/lib/alert.js +2 -2
  84. package/lib/aside.js +2 -2
  85. package/lib/audit-trajectory.js +928 -0
  86. package/lib/autocomplete.js +1506 -1506
  87. package/lib/avatar.js +2 -2
  88. package/lib/backtop.js +2 -2
  89. package/lib/badge.js +2 -2
  90. package/lib/breadcrumb-item.js +4 -4
  91. package/lib/breadcrumb.js +4 -4
  92. package/lib/button-group.js +9 -9
  93. package/lib/button.js +2 -2
  94. package/lib/ca-login.js +1290 -1290
  95. package/lib/calendar.js +999 -999
  96. package/lib/card.js +2 -2
  97. package/lib/carousel-item.js +1275 -1275
  98. package/lib/carousel.js +515 -515
  99. package/lib/cascader-panel.js +1302 -1302
  100. package/lib/cascader.js +1561 -1561
  101. package/lib/checkbox-button.js +2 -2
  102. package/lib/checkbox-group.js +1694 -1610
  103. package/lib/checkbox.js +9 -42
  104. package/lib/col.js +2 -2
  105. package/lib/collapse-item.js +1117 -1054
  106. package/lib/collapse.js +1122 -1054
  107. package/lib/color-picker.js +11 -11
  108. package/lib/config/api.js +80 -1
  109. package/lib/container.js +2 -2
  110. package/lib/cron.js +2 -2
  111. package/lib/data-table.js +1446 -1319
  112. package/lib/date-picker.js +1515 -1515
  113. package/lib/dialog.js +1796 -1794
  114. package/lib/divider.js +2 -2
  115. package/lib/drawer.js +4 -4
  116. package/lib/dropdown-item.js +4 -4
  117. package/lib/dropdown-menu.js +6 -6
  118. package/lib/dropdown.js +1477 -1477
  119. package/lib/email-login.js +1544 -1427
  120. package/lib/empty.js +2 -2
  121. package/lib/eoss.common.js +52567 -41727
  122. package/lib/flip.js +2 -2
  123. package/lib/flow-group.js +1278 -1278
  124. package/lib/flow.js +1716 -1599
  125. package/lib/flows.js +1561 -1444
  126. package/lib/footer.js +2 -2
  127. package/lib/form-item.js +1285 -1285
  128. package/lib/form.js +1144 -1067
  129. package/lib/guide.js +620 -0
  130. package/lib/header.js +2 -2
  131. package/lib/icon.js +1505 -1388
  132. package/lib/icons.js +2 -2
  133. package/lib/image-viewer.js +1376 -1376
  134. package/lib/image.js +73 -73
  135. package/lib/index.js +1 -1
  136. package/lib/infinite-scroll.js +71 -71
  137. package/lib/input-number.js +6 -6
  138. package/lib/input.js +1284 -1284
  139. package/lib/link.js +2 -2
  140. package/lib/loading.js +5 -5
  141. package/lib/login.js +1749 -1619
  142. package/lib/lowcode.js +12381 -5094
  143. package/lib/main.js +4049 -3653
  144. package/lib/marquee.js +1279 -1279
  145. package/lib/menu-item-group.js +2 -2
  146. package/lib/menu-item.js +2 -2
  147. package/lib/menu.js +1796 -1796
  148. package/lib/message-box.js +2993 -2993
  149. package/lib/message.js +1389 -1389
  150. package/lib/notification.js +1487 -1487
  151. package/lib/option-group.js +2 -2
  152. package/lib/option.js +1392 -1392
  153. package/lib/page-header.js +2 -2
  154. package/lib/pagination.js +1301 -1301
  155. package/lib/phone-login.js +1529 -1412
  156. package/lib/popconfirm.js +6 -6
  157. package/lib/popover.js +1425 -1425
  158. package/lib/process-config.js +7674 -0
  159. package/lib/process-module.js +7080 -0
  160. package/lib/process-rule.js +8246 -0
  161. package/lib/progress.js +5 -5
  162. package/lib/qr-code.js +7 -7
  163. package/lib/qrcode-login.js +1609 -1492
  164. package/lib/radio-button.js +10 -21
  165. package/lib/radio-group.js +1714 -1626
  166. package/lib/radio.js +10 -25
  167. package/lib/rate.js +1387 -1387
  168. package/lib/row.js +2 -2
  169. package/lib/scrollbar.js +1374 -1374
  170. package/lib/select.js +2376 -2257
  171. package/lib/selector-panel.js +1706 -1651
  172. package/lib/selector.js +1241 -1134
  173. package/lib/slider.js +2 -2
  174. package/lib/step.js +1119 -1051
  175. package/lib/steps.js +1276 -1276
  176. package/lib/submenu.js +530 -530
  177. package/lib/switch.js +1277 -1277
  178. package/lib/tab-pane.js +2 -2
  179. package/lib/table-column.js +1278 -1278
  180. package/lib/table.js +1953 -1836
  181. package/lib/tabs.js +1283 -1283
  182. package/lib/tag.js +2 -2
  183. package/lib/theme-chalk/audit-trajectory.css +0 -0
  184. package/lib/theme-chalk/base.css +1 -1
  185. package/lib/theme-chalk/button-group.css +1 -1
  186. package/lib/theme-chalk/calendar.css +1 -1
  187. package/lib/theme-chalk/guide.css +1 -0
  188. package/lib/theme-chalk/icon.css +1 -1
  189. package/lib/theme-chalk/icons.css +1 -1
  190. package/lib/theme-chalk/index.css +1 -1
  191. package/lib/theme-chalk/lowcode-view.css +1 -0
  192. package/lib/theme-chalk/lowcode.css +1 -1
  193. package/lib/theme-chalk/main.css +1 -1
  194. package/lib/theme-chalk/pagination.css +1 -1
  195. package/lib/theme-chalk/process-config.css +0 -0
  196. package/lib/theme-chalk/process-module.css +0 -0
  197. package/lib/theme-chalk/process-rule.css +1 -0
  198. package/lib/theme-chalk/select-dropdown.css +1 -1
  199. package/lib/theme-chalk/select.css +1 -1
  200. package/lib/theme-chalk/tree.css +1 -1
  201. package/lib/theme-chalk/update-history.css +0 -0
  202. package/lib/theme-chalk/wujie.css +1 -0
  203. package/lib/time-picker.js +1302 -1302
  204. package/lib/time-select.js +1298 -1298
  205. package/lib/timeline-item.js +2 -2
  206. package/lib/timeline.js +2 -2
  207. package/lib/tips.js +1613 -1496
  208. package/lib/toolbar.js +6 -6
  209. package/lib/tooltip.js +1363 -1363
  210. package/lib/transfer.js +1293 -1293
  211. package/lib/tree-group.js +1505 -1388
  212. package/lib/tree.js +1637 -1520
  213. package/lib/update-history.js +883 -0
  214. package/lib/upload.js +1689 -1572
  215. package/lib/utils/ajax.js +3 -5
  216. package/lib/utils/frame.js +133 -0
  217. package/lib/wujie.js +5037 -0
  218. package/package.json +3 -2
  219. package/packages/audit-trajectory/index.js +5 -0
  220. package/packages/audit-trajectory/src/main.vue +99 -0
  221. package/packages/button/src/button-group.vue +1 -1
  222. package/packages/cascader/src/cascader.vue +1 -1
  223. package/packages/checkbox/src/checkbox.vue +9 -14
  224. package/packages/data-table/src/data-table.vue +13 -4
  225. package/packages/date-picker/src/picker.vue +1 -1
  226. package/packages/dialog/src/dialog.vue +2 -0
  227. package/packages/form/src/form-item-render.vue +14 -6
  228. package/packages/form/src/form.vue +2 -2
  229. package/packages/guide/index.js +8 -0
  230. package/packages/guide/src/directive.js +47 -0
  231. package/packages/guide/src/guide.vue +89 -0
  232. package/packages/guide/src/manager.js +133 -0
  233. package/packages/input/src/input.vue +1 -1
  234. package/packages/login/src/login.vue +47 -46
  235. package/packages/lowcode/src/aside.vue +43 -8
  236. package/packages/lowcode/src/attribute/bind.vue +447 -236
  237. package/packages/lowcode/src/attribute/dependency.vue +474 -267
  238. package/packages/lowcode/src/attribute/function.vue +389 -51
  239. package/packages/lowcode/src/attribute/javascript.vue +311 -0
  240. package/packages/lowcode/src/attribute/property.vue +257 -166
  241. package/packages/lowcode/src/attribute/styles.vue +116 -15
  242. package/packages/lowcode/src/attribute.vue +654 -46
  243. package/packages/lowcode/src/canvas.vue +361 -60
  244. package/packages/lowcode/src/editor.vue +15 -2
  245. package/packages/lowcode/src/iframe.vue +60 -0
  246. package/packages/lowcode/src/lowcode.vue +233 -21
  247. package/packages/lowcode/src/mixins/history.js +132 -0
  248. package/packages/lowcode/src/pages.vue +1 -53
  249. package/packages/lowcode/src/render.vue +381 -56
  250. package/packages/lowcode/src/source.vue +12 -5
  251. package/packages/lowcode/src/toolbar.vue +43 -20
  252. package/packages/lowcode/src/util/source-generator.js +531 -0
  253. package/packages/lowcode/src/{source-parser.js → util/source-parser.js} +86 -32
  254. package/packages/lowcode-view/index.js +5 -0
  255. package/packages/lowcode-view/src/Iframe.vue +55 -0
  256. package/packages/lowcode-view/src/Modulels.vue +239 -0
  257. package/packages/lowcode-view/src/render.vue +337 -0
  258. package/packages/lowcode-view/src/view.vue +763 -0
  259. package/packages/main/src/components/pages.vue +11 -2
  260. package/packages/main/src/event-center.js +160 -0
  261. package/packages/main/src/minxs.js +60 -90
  262. package/packages/process-config/index.js +5 -0
  263. package/packages/process-config/src/FormList.vue +180 -0
  264. package/packages/process-config/src/NodeConfig.vue +212 -0
  265. package/packages/process-config/src/NodeForm.vue +237 -0
  266. package/packages/process-config/src/main.vue +257 -0
  267. package/packages/process-module/index.js +5 -0
  268. package/packages/process-module/src/FormList.vue +177 -0
  269. package/packages/process-module/src/main.vue +233 -0
  270. package/packages/process-rule/index.js +5 -0
  271. package/packages/process-rule/src/FormList.vue +614 -0
  272. package/packages/process-rule/src/companyReportDetail.vue +92 -0
  273. package/packages/process-rule/src/main.vue +749 -0
  274. package/packages/progress/src/progress.vue +1 -1
  275. package/packages/radio/src/radio-button.vue +12 -9
  276. package/packages/radio/src/radio-group.vue +10 -14
  277. package/packages/radio/src/radio.vue +12 -11
  278. package/packages/select/src/option-tree.vue +4 -4
  279. package/packages/select/src/option.vue +2 -2
  280. package/packages/select/src/select.vue +34 -37
  281. package/packages/selector/src/selector.vue +10 -12
  282. package/packages/theme-chalk/src/audit-trajectory.scss +0 -0
  283. package/packages/theme-chalk/src/button-group.scss +7 -0
  284. package/packages/theme-chalk/src/common/var.scss +34 -10
  285. package/packages/theme-chalk/src/guide.scss +93 -0
  286. package/packages/theme-chalk/src/icon.scss +425 -426
  287. package/packages/theme-chalk/src/icons.scss +1 -1
  288. package/packages/theme-chalk/src/index.scss +7 -0
  289. package/packages/theme-chalk/src/lowcode-view.scss +288 -0
  290. package/packages/theme-chalk/src/lowcode.scss +59 -2
  291. package/packages/theme-chalk/src/process-config.scss +0 -0
  292. package/packages/theme-chalk/src/process-module.scss +0 -0
  293. package/packages/theme-chalk/src/process-rule.scss +57 -0
  294. package/packages/theme-chalk/src/select-dropdown.scss +1 -1
  295. package/packages/theme-chalk/src/tree.scss +1 -0
  296. package/packages/theme-chalk/src/update-history.scss +0 -0
  297. package/packages/theme-chalk/src/wujie.scss +5 -0
  298. package/packages/update-history/index.js +5 -0
  299. package/packages/update-history/src/main.vue +54 -0
  300. package/packages/wujie/index.js +10 -0
  301. package/packages/wujie/src/wujie.vue +205 -0
  302. package/src/components/field-render.vue +5 -0
  303. package/src/config/api.js +80 -0
  304. package/src/index.js +23 -2
  305. package/src/utils/ajax.js +2 -2
  306. package/src/utils/frame.js +102 -0
  307. package/packages/lowcode/src/source-generator.js +0 -316
  308. /package/packages/lowcode/src/{json-repair.js → util/json-repair.js} +0 -0
  309. /package/packages/lowcode/src/{monaco-vue-completions.js → util/monaco-vue-completions.js} +0 -0
@@ -16,21 +16,26 @@
16
16
  <div
17
17
  class="es-lowcode__canvas--components"
18
18
  ref="container"
19
+ :key="page && page.style ? page.style.display : ''"
19
20
  :style="getStyle(page)"
20
21
  >
21
22
  <Render
22
23
  class="es-lowcode__canvas--component"
23
24
  :class="{ 'is-active': active === node.id }"
24
- v-for="(node, index) in components"
25
+ v-for="(node, index) in children"
25
26
  :key="node.id"
26
27
  :node="node"
28
+ :page="page"
27
29
  :active="active"
28
30
  :span="page && page.span"
29
- @click="handleClick(node)"
31
+ @click="handleClick"
30
32
  @change="
31
- (newNode, direction) => handleChange(newNode, index, direction)
33
+ (newNode, direction, initialWidth) =>
34
+ handleChange(newNode, index, direction, initialWidth)
32
35
  "
33
- @remove="handleRemove(index)"
36
+ @remove="handleRemoveNode"
37
+ @drop="handleNodeDrop"
38
+ @selectAncestor="selectNode"
34
39
  />
35
40
  </div>
36
41
  </es-scrollbar>
@@ -48,6 +53,125 @@ import {
48
53
  import bus from 'eoss/src/utils/bus.js';
49
54
  import Sortable from 'sortablejs';
50
55
 
56
+ // 原生 HTML 元素标签名集合
57
+ const HTML_TAGS = new Set([
58
+ 'a',
59
+ 'abbr',
60
+ 'address',
61
+ 'area',
62
+ 'article',
63
+ 'aside',
64
+ 'audio',
65
+ 'b',
66
+ 'base',
67
+ 'bdi',
68
+ 'bdo',
69
+ 'blockquote',
70
+ 'body',
71
+ 'br',
72
+ 'button',
73
+ 'canvas',
74
+ 'caption',
75
+ 'cite',
76
+ 'code',
77
+ 'col',
78
+ 'colgroup',
79
+ 'data',
80
+ 'datalist',
81
+ 'dd',
82
+ 'del',
83
+ 'details',
84
+ 'dfn',
85
+ 'dialog',
86
+ 'div',
87
+ 'dl',
88
+ 'dt',
89
+ 'em',
90
+ 'embed',
91
+ 'fieldset',
92
+ 'figcaption',
93
+ 'figure',
94
+ 'footer',
95
+ 'form',
96
+ 'h1',
97
+ 'h2',
98
+ 'h3',
99
+ 'h4',
100
+ 'h5',
101
+ 'h6',
102
+ 'head',
103
+ 'header',
104
+ 'hgroup',
105
+ 'hr',
106
+ 'html',
107
+ 'i',
108
+ 'iframe',
109
+ 'img',
110
+ 'input',
111
+ 'ins',
112
+ 'kbd',
113
+ 'label',
114
+ 'legend',
115
+ 'li',
116
+ 'link',
117
+ 'main',
118
+ 'map',
119
+ 'mark',
120
+ 'menu',
121
+ 'meta',
122
+ 'meter',
123
+ 'nav',
124
+ 'noscript',
125
+ 'object',
126
+ 'ol',
127
+ 'optgroup',
128
+ 'option',
129
+ 'output',
130
+ 'p',
131
+ 'param',
132
+ 'picture',
133
+ 'pre',
134
+ 'progress',
135
+ 'q',
136
+ 'rp',
137
+ 'rt',
138
+ 'ruby',
139
+ 's',
140
+ 'samp',
141
+ 'script',
142
+ 'section',
143
+ 'select',
144
+ 'slot',
145
+ 'small',
146
+ 'source',
147
+ 'span',
148
+ 'strong',
149
+ 'style',
150
+ 'sub',
151
+ 'summary',
152
+ 'sup',
153
+ 'table',
154
+ 'tbody',
155
+ 'td',
156
+ 'template',
157
+ 'textarea',
158
+ 'tfoot',
159
+ 'th',
160
+ 'thead',
161
+ 'time',
162
+ 'title',
163
+ 'tr',
164
+ 'track',
165
+ 'u',
166
+ 'ul',
167
+ 'var',
168
+ 'video',
169
+ 'wbr',
170
+ // 特殊元素
171
+ 'component',
172
+ 'slot'
173
+ ]);
174
+
51
175
  export default {
52
176
  name: 'Canvas',
53
177
  components: {
@@ -64,7 +188,7 @@ export default {
64
188
  styles: {},
65
189
  active: '',
66
190
  isEmpty: true,
67
- components: [],
191
+ children: [],
68
192
  columns: 1,
69
193
  gap: 0,
70
194
  widths: {},
@@ -79,12 +203,11 @@ export default {
79
203
  page: {
80
204
  handler(val) {
81
205
  this.isEmpty = !val;
82
- this.components = (val && val.children) || [];
206
+ this.children = (val && val.children) || [];
83
207
  this.$nextTick(() => {
84
208
  this.initSortable();
85
- if (val && val.style && val.style.display === 'masonry') {
86
- this.layoutWaterfall();
87
- }
209
+ // 始终调用 layoutWaterfall,内部根据 display 类型决定是否执行瀑布流布局
210
+ this.layoutWaterfall();
88
211
  });
89
212
  },
90
213
  deep: true,
@@ -125,10 +248,37 @@ export default {
125
248
  const style = page.style || {};
126
249
  this.columns = parseInt(style.columns || 1, 10);
127
250
  this.gap = parseInt(style.gap || 0, 10);
251
+
252
+ // 仅 masonry 模式执行瀑布流布局
253
+ if (style.display !== 'masonry') {
254
+ // 清除之前瀑布流设置的绝对定位样式(保留 width/height,grid/flex 模式下有效)
255
+ this.children.forEach((item) => {
256
+ if (!item.style) this.$set(item, 'style', {});
257
+ if (item.style.position) this.$set(item.style, 'position', '');
258
+ if (item.style.left) this.$set(item.style, 'left', '');
259
+ if (item.style.top) this.$set(item.style, 'top', '');
260
+ // grid 模式宽度由列宽/span 决定,移除瀑布流残留的 width
261
+ if (style.display === 'grid' && item.style.width) {
262
+ this.$delete(item.style, 'width');
263
+ }
264
+ // flex 模式下空的原生元素(如空 div)没有宽高会塌成 0,补默认可见尺寸
265
+ if (style.display === 'flex' && this.isHtmlElement(item.name)) {
266
+ if (!item.style.width) this.$set(item.style, 'width', '100px');
267
+ if (!item.style.height) this.$set(item.style, 'height', '100px');
268
+ }
269
+ });
270
+ const container = this.$refs.container;
271
+ if (container) {
272
+ container.style.height = '';
273
+ }
274
+ this.widths = [];
275
+ return;
276
+ }
277
+
128
278
  this.widths = layoutWaterfall(
129
279
  this,
130
280
  this.$refs.container,
131
- this.components,
281
+ this.children,
132
282
  this.columns,
133
283
  this.gap
134
284
  );
@@ -137,11 +287,30 @@ export default {
137
287
  const style = page ? page.style || {} : {};
138
288
 
139
289
  let { columns, span, ...styles } = style;
140
- if (styles.display && styles.display !== 'masonry') {
141
- delete styles.display;
290
+
291
+ // gap 纯数字时补 px,保证 CSS 生效
292
+ if (
293
+ styles.gap !== undefined &&
294
+ styles.gap !== '' &&
295
+ !isNaN(parseFloat(styles.gap)) &&
296
+ !/px|%|em|rem|vh|vw$/.test(String(styles.gap).trim())
297
+ ) {
298
+ styles.gap = `${styles.gap}px`;
142
299
  }
143
- if (styles.display && styles.display === 'grid' && columns) {
144
- styles['grid-template-columns'] = `repeat(${columns}, 1fr)`;
300
+
301
+ if (styles.display === 'grid') {
302
+ // grid 模式:转换为 grid-template-columns,保留 display: grid
303
+ if (columns) {
304
+ styles['grid-template-columns'] = `repeat(${columns}, 1fr)`;
305
+ }
306
+ styles['grid-gap'] = styles.gap || '0px';
307
+ } else if (styles.display === 'flex') {
308
+ // flex 模式:保留 display: flex,gap 生效;默认换行让间隙可见
309
+ styles.gap = styles.gap || '0px';
310
+ if (!styles['flex-wrap']) styles['flex-wrap'] = 'wrap';
311
+ } else if (styles.display) {
312
+ // masonry 及其它 display 不应用到容器
313
+ delete styles.display;
145
314
  }
146
315
  return styles;
147
316
  },
@@ -169,78 +338,201 @@ export default {
169
338
  pull: true,
170
339
  put: true
171
340
  },
172
- onEnd: (evt) => {
173
- const oldIndex = evt.oldIndex;
174
- const newIndex = evt.newIndex;
341
+ onEnd: () => {
342
+ // 拖拽结束后读取 DOM 的真实顺序,避免索引计算错误
343
+ const container = this.$refs.container;
344
+ if (!container) return;
345
+
346
+ const domIds = Array.from(container.children)
347
+ .map((el) => el.getAttribute('data-id'))
348
+ .filter(Boolean);
175
349
 
176
- // 如果位置没有变化则不处理
177
- if (
178
- oldIndex === newIndex ||
179
- oldIndex === undefined ||
180
- newIndex === undefined
181
- )
182
- return;
350
+ // 顺序未变化则不处理
351
+ const curIds = this.children.map((c) => c.id);
352
+ if (curIds.join(',') === domIds.join(',')) return;
183
353
 
184
- // 移动组件数组中的元素
185
- const movedItem = this.components[oldIndex];
186
- this.components.splice(newIndex, 0, movedItem);
187
- this.components.splice(
188
- oldIndex > newIndex ? oldIndex + 1 : oldIndex,
189
- 1
190
- );
191
- // 通知 lowcode 同步更新 page.children
192
- this.notifyChildrenChange();
354
+ // 按 DOM 顺序重建节点列表
355
+ const byId = {};
356
+ this.children.forEach((c) => {
357
+ byId[c.id] = c;
358
+ });
359
+ const newCombined = domIds.map((id) => byId[id]).filter(Boolean);
360
+
361
+ // 按 DOM 顺序写回 children
362
+ this.children = newCombined;
363
+ this.notifyAllChange();
193
364
  }
194
365
  });
195
366
  },
196
367
  handleClickPage(page) {
197
368
  this.handleClick(page);
198
- // this.$nextTick(() => {
199
- // this.layoutWaterfall();
200
- // });
201
369
  },
202
370
  /**
203
371
  * 处理组件点击事件
204
372
  * @param {Object} comp 被点击的组件
205
373
  */
206
- handleClick(comp) {
374
+ handleClick(comp, event) {
375
+ // Alt + 点击:选择父级元素
376
+ if (event && event.altKey) {
377
+ const parentId = this.findParentId(comp.id);
378
+ if (parentId) {
379
+ this.active = parentId;
380
+ bus.$emit('componentClick', parentId);
381
+ return;
382
+ }
383
+ }
207
384
  this.active = comp.id;
208
385
  bus.$emit('componentClick', comp.id);
209
386
  },
387
+ /**
388
+ * 查找指定节点的父节点 ID
389
+ * @param {String} nodeId - 节点 ID
390
+ * @returns {String|null} 父节点 ID,如果未找到则返回 null
391
+ */
392
+ findParentId(nodeId) {
393
+ // 如果节点是顶层节点,返回页面 ID
394
+ for (const node of this.children) {
395
+ if (node.id === nodeId) {
396
+ return this.page ? this.page.id : null;
397
+ }
398
+ }
399
+ // 递归查找父节点
400
+ const findParent = (nodes, targetId) => {
401
+ if (!nodes) return null;
402
+ for (const node of nodes) {
403
+ if (node.children) {
404
+ for (const child of node.children) {
405
+ if (child.id === targetId) {
406
+ return node.id;
407
+ }
408
+ }
409
+ const found = findParent(node.children, targetId);
410
+ if (found) return found;
411
+ }
412
+ }
413
+ return null;
414
+ };
415
+ return findParent(this.children, nodeId);
416
+ },
417
+ /**
418
+ * 通过面包屑选择指定节点
419
+ * @param {String} nodeId - 节点 ID
420
+ */
421
+ selectNode(nodeId) {
422
+ this.active = nodeId;
423
+ bus.$emit('componentClick', nodeId);
424
+ },
425
+ /**
426
+ * 处理嵌套节点的拖放事件:将拖动的元素/组件添加到目标节点的 children 中
427
+ * @param {Object} data - 包含 targetNode 和 droppedItem
428
+ */
429
+ handleNodeDrop(data) {
430
+ const { targetNode, droppedItem } = data;
431
+ const id = `${uuid()}`;
432
+ const newNode = { ...droppedItem, id };
433
+ // 确保目标节点有 children 数组
434
+ if (!targetNode.children) {
435
+ this.$set(targetNode, 'children', []);
436
+ }
437
+ targetNode.children.push(newNode);
438
+ // 通知 lowcode 更新整个页面数据
439
+ bus.$emit('updateNode', targetNode);
440
+ },
210
441
  /**
211
442
  * 处理 Render 子组件的数据变更(如调整大小等)
212
443
  * @param {Object} node 变更后的组件数据
213
444
  * @param {Number} index 组件在列表中的索引
214
445
  */
215
- handleChange(node, index, direction) {
216
- const old = this.components[index];
217
- const oldWidth = parseInt(old.style.width, 10);
446
+ handleChange(node, index, direction, initialWidth) {
447
+ const combined = this.children;
448
+ const old = combined[index];
218
449
  const width = parseInt(node.style.width, 10);
450
+ const parentDisplay =
451
+ this.page && this.page.style && this.page.style.display;
452
+
219
453
  if (direction === 'left' || direction === 'right') {
220
- // margin 在盒模型之外,占列槽的实际宽度要算上它;
221
- // border-box 下 width 本身已含 border,不需再扣
222
- const occupied = width + getHorizontalMargin(node.style);
223
- if (width > oldWidth) {
224
- node.style.span = Math.ceil(occupied / this.widths.columnWidth);
454
+ if (parentDisplay === 'flex') {
455
+ // flex 下拖动宽度为精确宽度;若设置了 flex 填充则移除,展示真实宽度
456
+ if (node.style.flex) this.$delete(node.style, 'flex');
457
+ // width 已由 render 写入,保留
225
458
  } else {
226
- node.style.span = Math.floor(occupied / this.widths.columnWidth);
459
+ // grid/masonry 下按整列调整:拖动停止后宽度增加 +1 列,减少 -1 列
460
+ const columns = parseInt(this.page.style.columns || 2, 10);
461
+ const currentSpan = node.style.span || 1;
462
+ let newSpan = currentSpan;
463
+ if (width > initialWidth) {
464
+ newSpan = Math.min(currentSpan + 1, columns);
465
+ } else if (width < initialWidth) {
466
+ newSpan = Math.max(currentSpan - 1, 1);
467
+ }
468
+ this.$set(node.style, 'span', newSpan);
469
+ if (parentDisplay === 'grid') {
470
+ // grid 下宽度由列控制,清除精确宽度
471
+ this.$delete(node.style, 'width');
472
+ }
227
473
  }
474
+ } else if (direction === 'top' || direction === 'bottom') {
475
+ // 高度调整:直接保留 style.height,无需额外处理
228
476
  }
229
- this.components.splice(index, 1, node);
477
+ // 更新 children
478
+ this.children.splice(index, 1, node);
230
479
  // 通知 lowcode 更新对应组件
231
480
  this.notifyComponentChange(node);
232
481
  this.$nextTick(() => {
233
482
  this.layoutWaterfall();
234
483
  });
235
484
  },
485
+ /**
486
+ * 递归查找指定 ID 的节点(含顶层与嵌套)
487
+ * @param {String} nodeId - 节点 ID
488
+ * @returns {Object|null} 节点对象
489
+ */
490
+ findNodeById(nodeId) {
491
+ const find = (nodes) => {
492
+ if (!nodes) return null;
493
+ for (const node of nodes) {
494
+ if (node.id === nodeId) return node;
495
+ if (node.children) {
496
+ const found = find(node.children);
497
+ if (found) return found;
498
+ }
499
+ }
500
+ return null;
501
+ };
502
+ return find(this.children);
503
+ },
504
+ /**
505
+ * 处理删除事件:支持删除顶层节点与嵌套节点
506
+ * @param {Object} node 被删除的节点
507
+ */
508
+ handleRemoveNode(node) {
509
+ const topIndex = this.children.findIndex((c) => c.id === node.id);
510
+ if (topIndex > -1) {
511
+ // 顶层节点
512
+ this.children.splice(topIndex, 1);
513
+ } else {
514
+ // 嵌套节点:从父节点的 children 中移除
515
+ const parentId = this.findParentId(node.id);
516
+ const parent = this.findNodeById(parentId);
517
+ if (parent && parent.children) {
518
+ const idx = parent.children.findIndex((c) => c.id === node.id);
519
+ if (idx > -1) parent.children.splice(idx, 1);
520
+ }
521
+ }
522
+ // 通知 lowcode 同步更新
523
+ this.notifyAllChange();
524
+ this.$nextTick(() => {
525
+ this.layoutWaterfall();
526
+ });
527
+ },
236
528
  /**
237
529
  * 处理组件删除事件
238
530
  * @param {Number} index 被删除的组件索引
239
531
  */
240
532
  handleRemove(index) {
241
- this.components.splice(index, 1);
242
- // 通知 lowcode 同步更新 page.children
243
- this.notifyChildrenChange();
533
+ this.children.splice(index, 1);
534
+ // 通知 lowcode 同步更新
535
+ this.notifyAllChange();
244
536
  this.$nextTick(() => {
245
537
  this.layoutWaterfall();
246
538
  });
@@ -250,10 +542,12 @@ export default {
250
542
  * @param {Event} event 拖动事件对象
251
543
  */
252
544
  handleDragOver(event) {
545
+ // 仅对组件库拖入生效,避免干扰 Sortable 排序
546
+ const isComponentDrag =
547
+ event.dataTransfer && event.dataTransfer.types.includes('component');
548
+ if (!isComponentDrag) return;
253
549
  event.preventDefault();
254
- if (event.dataTransfer) {
255
- event.dataTransfer.dropEffect = 'copy';
256
- }
550
+ event.dataTransfer.dropEffect = 'copy';
257
551
  },
258
552
  /**
259
553
  * 处理拖动放置事件
@@ -270,18 +564,25 @@ export default {
270
564
  if (componentData) {
271
565
  const component = JSON.parse(componentData);
272
566
  const id = `${uuid()}`;
273
- // 生成新组件并添加到列表
274
- this.components.push({ ...component, id });
275
- // 通知 lowcode 同步更新 page.children
276
- this.notifyChildrenChange();
567
+ const newNode = { ...component, id };
568
+ // 元素与组件统一放入 children,用 type 区分
569
+ this.children.push(newNode);
570
+ // 通知 lowcode 同步更新
571
+ this.notifyAllChange();
277
572
  }
278
573
  }
279
574
  },
280
575
  /**
281
- * 通知 lowcode 更新整个 children 列表
576
+ * 判断是否为原生 HTML 元素
577
+ */
578
+ isHtmlElement(name) {
579
+ return HTML_TAGS.has(name);
580
+ },
581
+ /**
582
+ * 通知 lowcode 同步更新 children
282
583
  */
283
- notifyChildrenChange() {
284
- bus.$emit('updateChildren', [...this.components]);
584
+ notifyAllChange() {
585
+ bus.$emit('updateChildren', [...this.children]);
285
586
  },
286
587
  /**
287
588
  * 通知 lowcode 更新单个组件数据
@@ -25,8 +25,8 @@
25
25
  </template>
26
26
 
27
27
  <script>
28
- import { registerVueCompletions } from './monaco-vue-completions';
29
- import { repairJson } from './json-repair';
28
+ import { registerVueCompletions } from './util/monaco-vue-completions';
29
+ import { repairJson } from './util/json-repair';
30
30
 
31
31
  // monaco 模块加载缓存,多个编辑器实例共用同一次动态加载
32
32
  let monacoLoader = null;
@@ -141,6 +141,9 @@ export default {
141
141
  scrollBeyondLastLine: false,
142
142
  fontSize: 13,
143
143
  tabSize: 2,
144
+ // 当前行高亮配置
145
+ renderLineHighlight: 'all', // 高亮当前行(包含 gutter 和行背景)
146
+ renderLineHighlightOnlyWhenFocus: false, // 即使未聚焦也高亮
144
147
  // 代码提示相关配置
145
148
  quickSuggestions: {
146
149
  other: true, // 普通代码区输入时自动提示
@@ -337,3 +340,13 @@ export default {
337
340
  }
338
341
  };
339
342
  </script>
343
+
344
+ <style>
345
+ /* Monaco 编辑器当前行高亮样式 - 使用全局样式 */
346
+ .monaco-editor .current-line {
347
+ background-color: rgba(255, 213, 0, 0.15) !important;
348
+ }
349
+ .monaco-editor .current-line-margin-top {
350
+ background-color: rgba(255, 213, 0, 0.15) !important;
351
+ }
352
+ </style>
@@ -0,0 +1,60 @@
1
+ <template>
2
+ <es-card class="module-card">
3
+ <div slot="header" class="module-card-header" v-if="title || more">
4
+ <i class="iconfont shujuchaoshi module-card-header-title-icon"></i>
5
+ <span class="module-card-header-title">{{ title }}</span>
6
+ <span
7
+ class="module-card-header-right"
8
+ v-if="more && showHandle"
9
+ @click="handleMore"
10
+ >
11
+ 更多
12
+ <i class="es-icon-you"></i>
13
+ </span>
14
+ </div>
15
+ <iframe :src="url" frameborder="0" width="100%" height="100%"></iframe>
16
+ </es-card>
17
+ </template>
18
+
19
+ <script>
20
+ export default {
21
+ name: 'Frame',
22
+
23
+ components: {},
24
+
25
+ props: {
26
+ title: String,
27
+ more: String,
28
+ url: String,
29
+ showHandle: {
30
+ type: Boolean,
31
+ default: true
32
+ }
33
+ },
34
+
35
+ data() {
36
+ return {};
37
+ },
38
+
39
+ computed: {},
40
+
41
+ watch: {},
42
+
43
+ created() {},
44
+
45
+ mounted() {},
46
+
47
+ methods: {}
48
+ };
49
+ </script>
50
+ <style lang="scss" scoped>
51
+ // @import '@/assets/style/home.scss';
52
+ // ::v-deep {
53
+ // .es-card__body {
54
+ // height: 100%;
55
+ // }
56
+ // .es-card__header + .es-card__body {
57
+ // height: calc(100% - 43px);
58
+ // }
59
+ // }
60
+ </style>