vue2-client 1.8.263 → 1.8.264

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 (209) hide show
  1. package/.env +19 -19
  2. package/.eslintrc.js +90 -90
  3. package/CHANGELOG.md +824 -824
  4. package/Components.md +60 -60
  5. package/babel.config.js +21 -21
  6. package/docs/index.md +30 -30
  7. package/docs/lowcode.md +188 -188
  8. package/docs/lowcodeForDeveloper.md +200 -200
  9. package/index.js +31 -31
  10. package/jest-transform-stub.js +8 -8
  11. package/jest.config.js +21 -21
  12. package/jest.setup.js +7 -7
  13. package/package.json +95 -95
  14. package/public/index.html +27 -27
  15. package/src/App.vue +188 -188
  16. package/src/ReportView.js +19 -19
  17. package/src/assets/img/querySlotDemo.svg +15 -15
  18. package/src/assets/svg/badtwo.svg +1 -1
  19. package/src/assets/svg/goodtwo.svg +1 -1
  20. package/src/base-client/components/common/AMisRender/index.js +3 -3
  21. package/src/base-client/components/common/AMisRender/index.vue +263 -263
  22. package/src/base-client/components/common/AddressSearchCombobox/AddressSearchCombobox.vue +413 -413
  23. package/src/base-client/components/common/AddressSearchCombobox/demo.vue +36 -36
  24. package/src/base-client/components/common/AmapMarker/AmapPointRendering.vue +120 -120
  25. package/src/base-client/components/common/CitySelect/CitySelect.vue +348 -348
  26. package/src/base-client/components/common/CitySelect/index.js +3 -3
  27. package/src/base-client/components/common/CitySelect/index.md +109 -109
  28. package/src/base-client/components/common/CreateQuery/CreateQuery.vue +669 -669
  29. package/src/base-client/components/common/CreateQuery/CreateQueryItem.vue +1014 -1014
  30. package/src/base-client/components/common/CreateQuery/index.js +3 -3
  31. package/src/base-client/components/common/CreateQuery/index.md +42 -42
  32. package/src/base-client/components/common/CreateSimpleFormQuery/CreateSimpleFormQuery.vue +452 -452
  33. package/src/base-client/components/common/CreateSimpleFormQuery/CreateSimpleFormQueryItem.vue +511 -511
  34. package/src/base-client/components/common/CreateSimpleFormQuery/index.js +3 -3
  35. package/src/base-client/components/common/CreateSimpleFormQuery/index.md +42 -42
  36. package/src/base-client/components/common/FormGroupEdit/FormGroupEdit.vue +149 -149
  37. package/src/base-client/components/common/FormGroupEdit/index.js +3 -3
  38. package/src/base-client/components/common/FormGroupEdit/index.md +43 -43
  39. package/src/base-client/components/common/FormGroupQuery/FormGroupQuery.vue +166 -166
  40. package/src/base-client/components/common/FormGroupQuery/index.js +3 -3
  41. package/src/base-client/components/common/FormGroupQuery/index.md +43 -43
  42. package/src/base-client/components/common/JSONToTree/jsontotree.vue +271 -271
  43. package/src/base-client/components/common/LowCodeComponent/LowCodePageOrganization.vue +471 -440
  44. package/src/base-client/components/common/LowCodePageRender/LowCodePageRender.vue +29 -29
  45. package/src/base-client/components/common/LowCodePageRender/editorPageRender.vue +559 -541
  46. package/src/base-client/components/common/LowCodePageRender/index.js +3 -3
  47. package/src/base-client/components/common/PersonSetting/PersonSetting.vue +208 -208
  48. package/src/base-client/components/common/PersonSetting/index.js +3 -3
  49. package/src/base-client/components/common/Tree/Tree.vue +149 -149
  50. package/src/base-client/components/common/Tree/index.js +2 -2
  51. package/src/base-client/components/common/Upload/Upload.vue +207 -207
  52. package/src/base-client/components/common/Upload/index.js +3 -3
  53. package/src/base-client/components/common/XAddForm/XAddForm.vue +98 -98
  54. package/src/base-client/components/common/XAddNativeForm/XAddNativeForm.vue +792 -732
  55. package/src/base-client/components/common/XAddNativeForm/index.md +146 -146
  56. package/src/base-client/components/common/XAddNativeForm/lowcodeEditorRegister.js +16 -16
  57. package/src/base-client/components/common/XAddNativeFormOA/XAddNativeFormOA.vue +303 -303
  58. package/src/base-client/components/common/XAddNativeFormOA/index.js +3 -3
  59. package/src/base-client/components/common/XAddNativeFormOA/index.md +146 -146
  60. package/src/base-client/components/common/XBadge/XBadge.vue +78 -78
  61. package/src/base-client/components/common/XCard/XCard.vue +64 -64
  62. package/src/base-client/components/common/XDataDrawer/XDataDrawer.vue +180 -180
  63. package/src/base-client/components/common/XDataDrawer/index.js +3 -3
  64. package/src/base-client/components/common/XDataDrawer/index.md +41 -41
  65. package/src/base-client/components/common/XDescriptions/XDescriptions.vue +167 -167
  66. package/src/base-client/components/common/XDescriptions/XDescriptionsGroup.vue +299 -299
  67. package/src/base-client/components/common/XDescriptions/demo.vue +50 -50
  68. package/src/base-client/components/common/XDescriptions/index.js +3 -3
  69. package/src/base-client/components/common/XDescriptions/index.md +83 -83
  70. package/src/base-client/components/common/XDetailsView/XDetailsView.vue +214 -214
  71. package/src/base-client/components/common/XDetailsView/index.js +3 -3
  72. package/src/base-client/components/common/XForm/XForm.vue +281 -281
  73. package/src/base-client/components/common/XForm/XFormItem.vue +807 -807
  74. package/src/base-client/components/common/XForm/XTreeSelect.vue +206 -206
  75. package/src/base-client/components/common/XForm/index.md +178 -178
  76. package/src/base-client/components/common/XFormCol/XFormCol.vue +36 -36
  77. package/src/base-client/components/common/XFormGroup/XFormGroup.vue +241 -241
  78. package/src/base-client/components/common/XFormGroup/demo.vue +40 -40
  79. package/src/base-client/components/common/XFormGroup/index.js +3 -3
  80. package/src/base-client/components/common/XFormGroup/index.md +38 -38
  81. package/src/base-client/components/common/XFormGroupDetails/XFormGroupDetails.vue +72 -72
  82. package/src/base-client/components/common/XFormGroupDetails/index.js +3 -3
  83. package/src/base-client/components/common/XFormTable/XFormTable.vue +519 -519
  84. package/src/base-client/components/common/XFormTable/index.md +98 -98
  85. package/src/base-client/components/common/XFormTable/lowcodeEditorRegister.js +16 -16
  86. package/src/base-client/components/common/XImportExcel/XImportExcel.vue +147 -147
  87. package/src/base-client/components/common/XReport/XReport.vue +852 -852
  88. package/src/base-client/components/common/XReport/XReportDemo.vue +2233 -2233
  89. package/src/base-client/components/common/XReport/XReportDesign.vue +496 -496
  90. package/src/base-client/components/common/XReport/XReportJsonRender.vue +277 -277
  91. package/src/base-client/components/common/XReport/XReportTrGroup.vue +757 -757
  92. package/src/base-client/components/common/XReport/index.js +3 -3
  93. package/src/base-client/components/common/XReport/index.md +44 -44
  94. package/src/base-client/components/common/XReportSlot/XReportSlot.vue +110 -110
  95. package/src/base-client/components/common/XReportSlot/index.js +3 -3
  96. package/src/base-client/components/common/XStepView/XStepView.vue +252 -252
  97. package/src/base-client/components/common/XStepView/index.js +3 -3
  98. package/src/base-client/components/common/XStepView/index.md +31 -31
  99. package/src/base-client/components/common/XTable/XTable.vue +636 -636
  100. package/src/base-client/components/common/XTable/index.md +255 -255
  101. package/src/base-client/components/common/XTree/XTree.vue +318 -318
  102. package/src/base-client/components/common/XTree/index.js +3 -3
  103. package/src/base-client/components/common/XTree/index.md +36 -36
  104. package/src/base-client/components/common/XTreeOne/XTreeOne.vue +114 -114
  105. package/src/base-client/components/common/XTreeOne/lowcodeEditorRegister.js +11 -11
  106. package/src/base-client/components/index.js +51 -51
  107. package/src/base-client/components/system/DictionaryDetailsView/DictionaryDetailsView.vue +232 -232
  108. package/src/base-client/components/system/QueryParamsDetailsView/QueryParamsDetailsView.vue +281 -281
  109. package/src/base-client/plugins/AppData.js +115 -115
  110. package/src/base-client/plugins/Config.js +19 -19
  111. package/src/base-client/plugins/GetLoginInfoService.js +183 -183
  112. package/src/base-client/plugins/tabs-page-plugin.js +39 -39
  113. package/src/bootstrap.js +39 -39
  114. package/src/components/CodeMirror/inedx.vue +118 -118
  115. package/src/components/CodeMirror/setting.js +40 -40
  116. package/src/components/FilePreview/FilePreview.vue +166 -166
  117. package/src/components/NumberInfo/NumberInfo.vue +54 -54
  118. package/src/components/STable/index.js +323 -323
  119. package/src/components/checkbox/ColorCheckbox.vue +157 -157
  120. package/src/components/checkbox/ImgCheckbox.vue +163 -163
  121. package/src/components/menu/SideMenu.vue +75 -75
  122. package/src/components/menu/menu.js +273 -273
  123. package/src/components/tool/AStepItem.vue +60 -60
  124. package/src/config/CreateQueryConfig.js +322 -322
  125. package/src/config/default/antd.config.js +89 -89
  126. package/src/config/default/setting.config.js +55 -55
  127. package/src/font-style/font.css +4 -4
  128. package/src/layouts/CommonLayout.vue +56 -56
  129. package/src/layouts/PageLayout.vue +151 -151
  130. package/src/layouts/SinglePageView.vue +138 -138
  131. package/src/layouts/header/AdminHeader.vue +132 -132
  132. package/src/layouts/header/HeaderNotice.vue +177 -177
  133. package/src/layouts/tabs/TabsHead.vue +189 -189
  134. package/src/layouts/tabs/TabsView.vue +387 -387
  135. package/src/lib.js +1 -1
  136. package/src/main.js +26 -26
  137. package/src/mock/extend/index.js +84 -84
  138. package/src/mock/goods/index.js +108 -108
  139. package/src/pages/AMisDemo/AMisDemo.vue +325 -325
  140. package/src/pages/AMisDemo/AMisDemo2.vue +74 -74
  141. package/src/pages/DynamicStatistics/ChartSelector.vue +331 -331
  142. package/src/pages/DynamicStatistics/DataTabs.vue +83 -83
  143. package/src/pages/DynamicStatistics/DynamicTable.vue +128 -128
  144. package/src/pages/DynamicStatistics/EvaluationArea.vue +69 -69
  145. package/src/pages/DynamicStatistics/FavoriteList.vue +51 -51
  146. package/src/pages/DynamicStatistics/QuestionHistoryAndFavorites.vue +591 -591
  147. package/src/pages/DynamicStatistics/SearchBar.vue +192 -192
  148. package/src/pages/DynamicStatistics/index.vue +282 -282
  149. package/src/pages/Example/index.vue +32 -32
  150. package/src/pages/NewDynamicStatistics/ChartSelector.vue +331 -331
  151. package/src/pages/NewDynamicStatistics/DataTabs.vue +122 -122
  152. package/src/pages/NewDynamicStatistics/DynamicTable.vue +128 -128
  153. package/src/pages/NewDynamicStatistics/EvaluationArea.vue +69 -69
  154. package/src/pages/NewDynamicStatistics/FavoriteList.vue +51 -51
  155. package/src/pages/NewDynamicStatistics/QuestionHistoryAndFavorites.vue +289 -289
  156. package/src/pages/NewDynamicStatistics/SearchBar.vue +193 -193
  157. package/src/pages/NewDynamicStatistics/index.vue +258 -258
  158. package/src/pages/ServiceReview/index.vue +284 -284
  159. package/src/pages/XReportView/index.vue +62 -62
  160. package/src/pages/login/Login.vue +378 -378
  161. package/src/pages/login/LoginV3.vue +389 -389
  162. package/src/pages/lowCode/lowCodeEditor.vue +1824 -1554
  163. package/src/pages/lowCode/lowCodeRender.vue +39 -39
  164. package/src/pages/resourceManage/orgListManage.vue +98 -98
  165. package/src/pages/system/dictionary/index.vue +44 -44
  166. package/src/pages/system/monitor/loginInfor/index.vue +37 -37
  167. package/src/pages/system/monitor/operLog/index.vue +37 -37
  168. package/src/pages/system/settings/modifyPassword.vue +117 -117
  169. package/src/pages/system/ticket/index.vue +480 -480
  170. package/src/pages/system/ticket/submitTicketSuccess.vue +484 -484
  171. package/src/router/async/config.async.js +33 -33
  172. package/src/router/async/router.map.js +107 -107
  173. package/src/router/guards.js +220 -220
  174. package/src/router/index.js +27 -27
  175. package/src/router.js +19 -19
  176. package/src/services/api/TicketDetailsViewApi.js +46 -46
  177. package/src/services/api/cas.js +79 -79
  178. package/src/services/api/common.js +284 -284
  179. package/src/services/api/entity.js +18 -18
  180. package/src/services/api/index.js +17 -17
  181. package/src/services/api/restTools.js +46 -46
  182. package/src/services/apiService.js +14 -14
  183. package/src/services/user.js +71 -71
  184. package/src/store/modules/setting.js +119 -119
  185. package/src/theme/default/style.less +57 -57
  186. package/src/theme/global.less +130 -130
  187. package/src/utils/authority-utils.js +85 -85
  188. package/src/utils/errorCode.js +6 -6
  189. package/src/utils/htmlToPDF.js +108 -108
  190. package/src/utils/htmlToPDFApi.js +5 -5
  191. package/src/utils/indexedDB.js +201 -201
  192. package/src/utils/login.js +144 -144
  193. package/src/utils/lowcode/lowcodeComponentMixin.js +112 -112
  194. package/src/utils/lowcode/lowcodeLog.js +29 -29
  195. package/src/utils/lowcode/lowcodeUtils.js +331 -276
  196. package/src/utils/lowcode/registerComponentForEditor.js +11 -11
  197. package/src/utils/lowcode/registerComponentForRender.js +11 -11
  198. package/src/utils/map-utils.js +47 -47
  199. package/src/utils/reg.js +19 -19
  200. package/src/utils/request.js +343 -343
  201. package/src/utils/routerUtil.js +435 -435
  202. package/src/utils/runEvalFunction.js +6 -6
  203. package/src/utils/util.js +241 -241
  204. package/src/utils/waterMark.js +31 -31
  205. package/test/Amis.spec.js +163 -163
  206. package/test/Tree.spec.js +167 -167
  207. package/test/myDialog.spec.js +46 -46
  208. package/vue.config.js +177 -177
  209. package//350/277/201/347/247/273/346/227/245/345/277/227.md +15 -15
@@ -1,1554 +1,1824 @@
1
- <template>
2
- <div>
3
- <!-- 标题 -->
4
- <a-card>
5
- <a-page-header
6
- title="奥枫低代码前端编辑器"
7
- sub-title="af-lowcode"
8
- :backIcon="false"
9
- @back="() => null"
10
- >
11
- <template slot="extra">
12
- <a-button @click="test">测试</a-button>
13
- <a-button @click="editModeActive">编辑</a-button>
14
- <a-button @click="previewModeActive">预览</a-button>
15
- <a-button type="primary" @click="exportConfig">导出</a-button>
16
- </template>
17
- </a-page-header>
18
- </a-card>
19
- <!-- 预览模式 -->
20
- <a-card v-if="preview">
21
- <editor-page-render :page-config="config" :edit-mode="false"/>
22
- </a-card>
23
- <!-- 编辑模式 -->
24
- <div v-show="!preview">
25
- <a-row :gutter="2">
26
- <!-- 左侧 -->
27
- <a-col :span="4">
28
- <a-card>
29
- <a-tabs>
30
- <!-- UI库 -->
31
- <a-tab-pane key="1" tab="UI库">
32
- <a-card style="margin-bottom: 5%">
33
- <!-- 所有组件 -->
34
- <a-card-grid class="ui-item" @click="addContainer">
35
- 组件容器
36
- </a-card-grid>
37
- <template v-for="(item, index) in getRegisteredComponents()">
38
- <a-card-grid :key="index" class="ui-item" @click="addComponentToContainer(item)">
39
- {{ item }}
40
- </a-card-grid>
41
- </template>
42
- </a-card>
43
- </a-tab-pane>
44
- <!-- 页面架构 -->
45
- <a-tab-pane key="2" tab="架构">
46
- <div style="margin-bottom: 3%">
47
- <LowCodePageOrganization
48
- :config="config"
49
- v-if="showPageOrganization"
50
- :select-tree-node="selectTreeNode"
51
- @rename="rename"
52
- @split="handleSplit"
53
- @pasteItem="handlePasteItem"
54
- @componentMove="handleTreeDrag"
55
- @deleteComponent="deleteComponentInTree"
56
- @treeOrganizationClick="treeOrganizationClick"/>
57
- </div>
58
- </a-tab-pane>
59
- </a-tabs>
60
- </a-card>
61
- </a-col>
62
- <!-- 中间主体编辑器 -->
63
- <a-col :span="15">
64
- <a-card>
65
- <!-- 切换显示的组件 -->
66
- <div style="margin-bottom: 3%">
67
- <!-- 添加页面组件按钮 -->
68
- <div style="float: right">
69
- <a-popover>
70
- <template slot="content">
71
- <p>添加页面组件</p>
72
- </template>
73
- <a-button @click="addPageContainer" >
74
- <a-icon type="plus"/>
75
- </a-button>
76
- </a-popover>
77
- </div>
78
- <!-- 每个页面按钮切换栏 -->
79
- <a-menu v-model="mainPageMenu" mode="horizontal" @click="handleMainPageMenuChange">
80
- <template v-for="(page) in config.page">
81
- <a-menu-item :key="page.id">{{ page.title + '(' + determinePageType(page.type) + ')' }}</a-menu-item>
82
- </template>
83
- </a-menu>
84
- </div>
85
- <!-- 渲染器 -->
86
- <div v-if="activeMainPageType === 'page'">
87
- <editor-page-render
88
- v-if="renderPreview"
89
- @spanDrag="handleDrag"
90
- @containerDelete="handleContainerDelete"
91
- @clickComponentInEditor="clickComponentInEditor"
92
- :page-config="{ data: config.data, page: config.page.filter(page => page.id === activeMainPage)}"/>
93
- <a-skeleton v-else/>
94
- </div>
95
- <div v-if="activeMainPageType === 'modal'">
96
- <editor-page-render
97
- v-if="renderModalPreview"
98
- @spanDrag="handleDrag"
99
- @containerDelete="handleContainerDelete"
100
- @clickComponentInEditor="clickComponentInEditor"
101
- :page-config="{ data: config.data, page: config.page.filter(page => page.id === activeMainPage)}"/>
102
- <a-skeleton v-else/>
103
- </div>
104
- <div v-if="activeMainPageType === 'draw'">
105
- <editor-page-render
106
- v-if="renderDrawPreview"
107
- @spanDrag="handleDrag"
108
- @containerDelete="handleContainerDelete"
109
- @clickComponentInEditor="clickComponentInEditor"
110
- :page-config="{ data: config.data, page: config.page.filter(page => page.id === activeMainPage)}"/>
111
- <a-skeleton v-else/>
112
- </div>
113
- </a-card>
114
- </a-col>
115
- <!-- 右侧 -->
116
- <a-col :span="5">
117
- <!-- 属性编辑 -->
118
- <a-card>
119
- <template v-if="editorPropertiesConfig === 'unregistered'">
120
- <p>所选组件并未注册</p>
121
- </template>
122
- <template v-else>
123
- <!-- 组件名 -->
124
- <template v-if="editorPropertiesConfig.name">
125
- <h3>组件名</h3>
126
- <h4>{{ editorPropertiesConfig.name }}</h4>
127
- </template>
128
- <template v-else-if="editorPropertiesConfig.id">
129
- <h3>组件ID</h3>
130
- <h4>{{ editorPropertiesConfig.id }}</h4>
131
- </template>
132
- <!-- 切换 -->
133
- <a-menu v-model="editorPanelCurrent" mode="horizontal" @click="() => null">
134
- <a-menu-item key="properties">属性</a-menu-item>
135
- <a-menu-item key="events">事件</a-menu-item>
136
- </a-menu>
137
- <!-- 属性编辑 -->
138
- <div v-if="editorPanelCurrent[0] === 'properties'">
139
- <div v-if="editorPropertiesConfig.props !== undefined">
140
- <div>
141
- 栅格数:<a-input :default-value="editorPropertiesConfig.span" @change="changeSpan"/>
142
- </div>
143
- <template v-for="(value,key) in editorPropertiesConfig.props">
144
- <div :key="editorPropertiesConfig.id + '_' + key">
145
- <a-tooltip>
146
- <template slot="title" v-if="resolveEditorPropsLabel(editorPropertiesConfig.type, key).desc">
147
- {{ resolveEditorPropsLabel(editorPropertiesConfig.type, key).desc }}
148
- </template>
149
- {{ resolveEditorPropsLabel(editorPropertiesConfig.type, key).label }}:
150
- </a-tooltip>
151
- <a-input :default-value="value" @change="editorPropertiesInputChange($event, key)"/>
152
- </div>
153
- </template>
154
- </div>
155
- <p v-else>您未选择任何组件</p>
156
- </div>
157
- <!-- 事件编辑 -->
158
- <div v-else-if="editorPanelCurrent[0] === 'events'">
159
- <template v-if="editorPropertiesConfig.onEvent !== undefined">
160
- <a-collapse v-model="eventCollapseActive">
161
- <a-collapse-panel
162
- v-for="(eventConfig,eventType) in editorPropertiesConfig.onEvent"
163
- :key="eventType"
164
- :header="eventType">
165
- <div v-for="(singleEvent,singleEventIndex) in eventConfig" :key="singleEventIndex" class="singleEvent">
166
- <p>
167
- <span style="color:rgb( 24,144,255)">{{ singleEvent.eventType }}</span>
168
- 事件
169
- </p>
170
- <!-- 事件 编辑/删除 按钮 -->
171
- <div style="display: flex; justify-content: space-evenly">
172
- <a-icon type="edit" theme="twoTone" class="edit_icon" @click="editEventIconClick(eventType,singleEventIndex)"/>
173
- <a-popconfirm title="确认删除" ok-text="确认删除" cancel-text="取消" @confirm="removeEventClick(eventType,singleEventIndex)" @cancel="() => null">
174
- <a-icon type="delete" theme="twoTone" class="edit_icon"/>
175
- </a-popconfirm>
176
- </div>
177
- </div>
178
- </a-collapse-panel>
179
- </a-collapse>
180
- </template>
181
- <a-button v-if="editorPropertiesConfig.id !== undefined" @click="addEvent">添加事件</a-button>
182
- <p v-else>您未选择任何组件</p>
183
- </div>
184
- </template>
185
- </a-card>
186
- </a-col>
187
- </a-row>
188
- </div>
189
- <!-- 自定义事件弹框 -->
190
- <a-modal
191
- title="事件编辑器"
192
- width="60%"
193
- :z-index="1001"
194
- :destroyOnClose="true"
195
- @ok="handleEventEditorOk"
196
- @cancel="handleEventEditorCancel"
197
- v-if="showEventEditor"
198
- :visible="showEventEditor">
199
- <a-form :label-col="{ span: 6 }" :wrapper-col="{ span: 14 }">
200
- <!-- 事件触发类型 -->
201
- <a-form-item label="事件触发类型">
202
- <a-select @change="handleEventEditorTypeChange" :default-value="eventEditorContent.emitType">
203
- <a-select-option
204
- v-for="(eventType, eventTypeIndex) in editorPropertiesConfig.selfEvent"
205
- :key="eventTypeIndex"
206
- :value="eventType">
207
- {{ eventType }}
208
- </a-select-option>
209
- <a-select-option value="customEmitType">
210
- 自定义触发类型
211
- </a-select-option>
212
- <a-select-option value="lifeCycle">
213
- 生命周期函数
214
- </a-select-option>
215
- </a-select>
216
- </a-form-item>
217
- <!-- 自定义事件触发类型 -->
218
- <a-form-item label="自定义事件触发名" v-if="eventEditorContent.emitType === 'customEmitType'">
219
- <a-input v-model="eventEditorContent.customEmitType"/>
220
- </a-form-item>
221
- <!-- 事件类型 -->
222
- <a-form-item label="事件类型" v-if="eventEditorContent.emitType !== 'lifeCycle'">
223
- <a-select @change="handleEventEditorEventTypeChange" :default-value="eventEditorContent.eventType">
224
- <a-select-option value="changeValue">
225
- 修改组件的值
226
- </a-select-option>
227
- <a-select-option value="changeProps">
228
- 修改组件的Props
229
- </a-select-option>
230
- <a-select-option value="runLogic">
231
- 执行Logic
232
- </a-select-option>
233
- <a-select-option value="log">
234
- 打印日志
235
- </a-select-option>
236
- <a-select-option value="showModal" v-if="this.config.page.filter(page => page.type === 'modal').length > 0">
237
- 修改弹框可见
238
- </a-select-option>
239
- <a-select-option value="showDraw" v-if="this.config.page.filter(page => page.type === 'draw').length > 0">
240
- 修改抽屉可见
241
- </a-select-option>
242
- </a-select>
243
- </a-form-item>
244
- <!-- 生命周期函数 -->
245
- <a-form-item label="生命周期名" v-if="eventEditorContent.emitType === 'lifeCycle'">
246
- <a-select @change="handleEventEditorLifeCycleChange" :default-value="eventEditorContent.lifeCycle">
247
- <a-select-option value="created">
248
- created
249
- </a-select-option>
250
- <a-select-option value="beforeMount">
251
- beforeMount
252
- </a-select-option>
253
- <a-select-option value="mounted">
254
- mounted
255
- </a-select-option>
256
- <a-select-option value="beforeUpdate">
257
- beforeUpdate
258
- </a-select-option>
259
- <a-select-option value="updated">
260
- updated
261
- </a-select-option>
262
- <a-select-option value="beforeDestroy">
263
- beforeDestroy
264
- </a-select-option>
265
- <a-select-option value="destroyed">
266
- destroyed
267
- </a-select-option>
268
- </a-select>
269
- </a-form-item>
270
- <!-- 修改弹框可见 or 修改抽屉可见 -->
271
- <a-form-item label="修改可见" v-if="eventEditorContent.eventType === 'showModal' || eventEditorContent.eventType === 'showDraw'">
272
- <a-radio-group v-model="eventEditorContent.visible" button-style="solid">
273
- <a-radio-button value="open">
274
- 显示
275
- </a-radio-button>
276
- <a-radio-button value="close">
277
- 隐藏
278
- </a-radio-button>
279
- </a-radio-group>
280
- </a-form-item>
281
- <!-- 弹框容器ID -->
282
- <a-form-item label="弹框容器ID" v-if="eventEditorContent.eventType === 'showModal'">
283
- <a-select v-model="eventEditorContent.containerId">
284
- <a-select-option
285
- v-for="(modal) in config.page.filter(page => page.type === 'modal')"
286
- :key="modal.id"
287
- :value="modal.id">
288
- 弹框_{{ modal.id }}
289
- </a-select-option>
290
- </a-select>
291
- </a-form-item>
292
- <!-- 抽屉容器ID -->
293
- <a-form-item label="抽屉容器ID" v-if="eventEditorContent.eventType === 'showDraw'">
294
- <a-select v-model="eventEditorContent.containerId">
295
- <a-select-option
296
- v-for="(draw) in config.page.filter(page => page.type === 'draw')"
297
- :key="draw.id"
298
- :value="draw.id">
299
- 抽屉_{{ draw.id }}
300
- </a-select-option>
301
- </a-select>
302
- </a-form-item>
303
- <!-- Logic名 -->
304
- <a-form-item label="Logic名" v-if="eventEditorContent.eventType === 'runLogic'">
305
- <a-input v-model="eventEditorContent.logicName"/>
306
- </a-form-item>
307
- <!-- 服务名 -->
308
- <a-form-item label="服务名" v-if="eventEditorContent.eventType === 'runLogic'">
309
- <a-input v-model="eventEditorContent.serviceName"/>
310
- </a-form-item>
311
- <!-- 自定义Logic参数,由哪些组件传递 -->
312
- <a-form-item label="Logic参数取值组件" v-if="eventEditorContent.eventType === 'runLogic'">
313
- <a-transfer
314
- :data-source="logicParamTransferDataSource"
315
- :render="item => item.title"
316
- :target-keys="eventEditorContent.logicParamTransfer"
317
- @change="handleLogicParamTransferChange"/>
318
- </a-form-item>
319
- <!-- 自定义Logic参数 -->
320
- <a-form-item label="自定义Logic参数" v-if="eventEditorContent.eventType === 'runLogic'">
321
- <a-button type="primary" @click="openLogicParamJSEditor">
322
- 打开编辑器
323
- </a-button>
324
- </a-form-item>
325
- <!-- 自定义Logic回调 -->
326
- <a-form-item label="自定义Logic回调" v-if="eventEditorContent.eventType === 'runLogic'" >
327
- <a-button type="primary" @click="openLogicCallbackEditor">
328
- 打开编辑器
329
- </a-button>
330
- </a-form-item>
331
- <!-- 修改组件的值 才会显示的其余参数 -->
332
- <template v-if="eventEditorContent.eventType === 'changeValue' || eventEditorContent.eventType === 'changeProps'">
333
- <!-- 目标组件 -->
334
- <a-form-item label="目标组件">
335
- <a-select @change="handleEventEditorTargetChange" :default-value="eventEditorContent.target">
336
- <a-select-option
337
- v-for="(targetId, targetIndex) in getAllRenderedComponents()"
338
- :key="targetIndex"
339
- :value="targetId">
340
- {{ targetId }}
341
- </a-select-option>
342
- </a-select>
343
- </a-form-item>
344
- <!-- 目标组件执行事件名 -->
345
- <a-form-item label="目标组件执行事件名" v-if="eventEditorContent.eventName === 'changeValue'">
346
- <a-select @change="handleEventEditorTargetEventTypeChange" :default-value="eventEditorContent.eventName">
347
- <a-select-option :value="eventType" v-for="(eventType,eventTypeIndex) in supportedEventType" :key="'eventType_' + eventTypeIndex">
348
- {{ eventType }}
349
- </a-select-option>
350
- </a-select>
351
- </a-form-item>
352
- <!-- 目标组件修改值对应的key -->
353
- <a-form-item label="目标组件修改值对应的key" v-if="eventEditorContent.target !== undefined">
354
- <a-input v-model="eventEditorContent.targetKey"/>
355
- </a-form-item>
356
- </template>
357
- <!-- 自定义JS方法 -->
358
- <a-form-item label="自定义JS方法" v-if="eventEditorContent.emitType !== 'lifeCycle'">
359
- <a-button type="primary" @click="openEventJSEditor">打开编辑器</a-button>
360
- </a-form-item>
361
- <!-- 自定义钩子函数 -->
362
- <a-form-item label="自定义生命周期函数" v-if="eventEditorContent.emitType === 'lifeCycle'">
363
- <a-button type="primary" @click="openEventLifeCycleJSEditor">打开编辑器</a-button>
364
- </a-form-item>
365
- </a-form>
366
- </a-modal>
367
- <!-- 自定义JS事件弹框 -->
368
- <a-modal
369
- title="事件编辑器"
370
- width="60%"
371
- :destroyOnClose="true"
372
- :z-index="1002"
373
- @ok="handleJSEventEditorOk"
374
- @cancel="handleJSEventEditorCancel"
375
- :visible="showJSEventEditor">
376
- <a-popover title="参数说明" style="margin-right: 5%">
377
- <template slot="content">
378
- <p>该方法有以下几个参数:</p>
379
- <p>eventType:事件类型,比如:changeValue代表修改目标组件的值</p>
380
- <p>data:由事件源发出的参数列表</p>
381
- <p>targetKey:修改目标组件值所对应的key</p>
382
- <p>sourceVM:事件源的vue对象</p>
383
- <p>targetVM:目标的vue对象</p>
384
- </template>
385
- <a-button type="primary">
386
- 参数说明
387
- </a-button>
388
- </a-popover>
389
- <a-popover title="返回值说明" style="margin-bottom: 5%">
390
- <template slot="content">
391
- <p>该方法需要的返回值:</p>
392
- <p>eventType:事件类型</p>
393
- <p>data:传递给目标组件的数据</p>
394
- <p>targetKey:修改目标组件值所对应的key</p>
395
- </template>
396
- <a-button type="primary">
397
- 返回值说明
398
- </a-button>
399
- </a-popover>
400
- <code-mirror
401
- :style-obj="{height:'80%',fontSize:'18px',marginBottom:'15px'}"
402
- :mode="'javascript'"
403
- :theme="'monokai'"
404
- v-model="eventEditorContent.JSFunction"
405
- :value="eventEditorContent.JSFunction"/>
406
- </a-modal>
407
- <!-- 自定义Logic参数JS弹框 -->
408
- <a-modal
409
- title="自定义Logic参数JS编辑器"
410
- width="60%"
411
- :destroyOnClose="true"
412
- :z-index="1002"
413
- @ok="() => { showLogicParamJSEditor = false}"
414
- @cancel="() => { showLogicParamJSEditor = false}"
415
- :visible="showLogicParamJSEditor">
416
- <a-popover title="参数说明" style="margin-right: 5%">
417
- <template slot="content">
418
- <p>该方法有以下几个参数:</p>
419
- <p>componentData:Logic参数取值组件中选中的组件,将会把数据打包存在此对象中,key则为组件的id</p>
420
- <p>data:由事件源emit发出的参数</p>
421
- </template>
422
- <a-button type="primary">
423
- 参数说明
424
- </a-button>
425
- </a-popover>
426
- <a-popover title="返回值说明" style="margin-bottom: 5%">
427
- <template slot="content">
428
- <p>该方法需要一个JSON类型的返回值</p>
429
- <p>该返回值就是传递给Logic执行的参数</p>
430
- </template>
431
- <a-button type="primary">
432
- 返回值说明
433
- </a-button>
434
- </a-popover>
435
- <code-mirror
436
- :style-obj="{height:'80%',fontSize:'18px',marginBottom:'15px'}"
437
- :mode="'javascript'"
438
- :theme="'monokai'"
439
- v-model="eventEditorContent.logicParamJSFunction"
440
- :value="eventEditorContent.logicParamJSFunction"/>
441
- </a-modal>
442
- <!-- 自定义Logic回调弹框 -->
443
- <a-modal
444
- title="事件编辑器"
445
- width="60%"
446
- :destroyOnClose="true"
447
- :z-index="1002"
448
- @ok="() => { showLogicCallBackEditor = false}"
449
- @cancel="() => { showLogicCallBackEditor = false}"
450
- :visible="showLogicCallBackEditor">
451
- <a-popover title="参数说明" style="margin-bottom: 5%">
452
- <template slot="content">
453
- <p>该方法有以下几个参数:</p>
454
- <p>componentsMap:所有组件注册的Map</p>
455
- <p>responseData:后端的返回值</p>
456
- </template>
457
- <a-button type="primary">
458
- 参数说明
459
- </a-button>
460
- </a-popover>
461
- <code-mirror
462
- :style-obj="{height:'80%',fontSize:'18px',marginBottom:'15px'}"
463
- :mode="'javascript'"
464
- :theme="'monokai'"
465
- v-model="eventEditorContent.logicCallBackFunction"
466
- :value="eventEditorContent.logicCallBackFunction"/>
467
- </a-modal>
468
- <!-- 自定义生命周期函数弹框 -->
469
- <a-modal
470
- title="生命周期函数编辑器"
471
- width="60%"
472
- :destroyOnClose="true"
473
- :z-index="1002"
474
- @ok="() => { showLifeCycleFunctionEditor = false}"
475
- @cancel="() => { showLifeCycleFunctionEditor = false}"
476
- :visible="showLifeCycleFunctionEditor">
477
- <a-popover title="参数说明" style="margin-bottom: 5%">
478
- <template slot="content">
479
- <p>该方法有以下几个参数:</p>
480
- <p>vm:VUE组件对象(this)</p>
481
- </template>
482
- <a-button type="primary">
483
- 参数说明
484
- </a-button>
485
- </a-popover>
486
- <code-mirror
487
- :style-obj="{height:'80%',fontSize:'18px',marginBottom:'15px'}"
488
- :mode="'javascript'"
489
- :theme="'monokai'"
490
- v-model="eventEditorContent.LifeCycleFunction"
491
- :value="eventEditorContent.LifeCycleFunction"/>
492
- </a-modal>
493
- <!-- 新增页面容器弹框 -->
494
- <a-modal
495
- title="新增页面容器"
496
- width="60%"
497
- :z-index="1001"
498
- :destroyOnClose="true"
499
- @ok="handleAddPageContainerModalOk"
500
- @cancel="() => { showPageContainerAddModal = false }"
501
- :visible="showPageContainerAddModal">
502
- <a-form :label-col="{ span: 7 }" :wrapper-col="{ span: 12 }">
503
- <!-- 容器类型 -->
504
- <a-form-item label="容器类型">
505
- <a-select v-model="addComponentTemp.type" @change="pageContainerAddTypeChange">
506
- <a-select-option value="page">
507
- 页面
508
- </a-select-option>
509
- <a-select-option value="modal">
510
- 弹框
511
- </a-select-option>
512
- <a-select-option value="draw">
513
- 抽屉
514
- </a-select-option>
515
- </a-select>
516
- </a-form-item>
517
- <!-- 标题 -->
518
- <a-form-item label="标题">
519
- <a-input v-model="addComponentTemp.title"/>
520
- </a-form-item>
521
- <template v-if="addComponentTemp.type !== 'page'">
522
- <!-- 宽度 -->
523
- <a-form-item label="宽度">
524
- <a-input v-model="addComponentTemp.width"/>
525
- </a-form-item>
526
- </template>
527
- </a-form>
528
- </a-modal>
529
- </div>
530
- </template>
531
-
532
- <script>
533
- import editorPageRender from '@vue2-client/base-client/components/common/LowCodePageRender/editorPageRender.vue'
534
- import * as registeredRender from '@vue2-client/utils/lowcode/registerComponentForRender'
535
- import * as lowcodeUtils from '@vue2-client/utils/lowcode/lowcodeUtils'
536
- import codeMirror from '@vue2-client/components/CodeMirror/inedx.vue'
537
- import lowcodeComponentMixin from '@vue2-client/utils/lowcode/lowcodeComponentMixin'
538
- // eslint-disable-next-line no-unused-vars
539
- import lowcodeLog from '@vue2-client/utils/lowcode/lowcodeLog'
540
- import LowCodePageOrganization from '@vue2-client/base-client/components/common/LowCodeComponent/LowCodePageOrganization.vue'
541
-
542
- // 函数编辑器显示的模板
543
- const JSEventFunctionTemplate = 'function(eventType, data, targetKey, sourceVM, targetVM) {\n \n return {\n "eventType": eventType,\n "data": data,\n "targetKey": targetKey\n }\n}'
544
- const LogicParamFunctionTemplate = 'function(componentData, data) {\n \n return {\n \n }\n}'
545
- const LogicCallBackFunctionTemplate = 'function(componentsMap, responseData) {\n \n}'
546
- const LifeCycleFunctionTemplate = 'function(vm) {\n \n}'
547
-
548
- export default {
549
- components: {
550
- LowCodePageOrganization,
551
- editorPageRender,
552
- codeMirror
553
- },
554
- props: {
555
- // 页面原始的配置,用于从琉璃中读取
556
- originalConfig: {
557
- type: Object,
558
- default: () => {
559
- return {
560
- page: []
561
- }
562
- }
563
- }
564
- },
565
- data () {
566
- return {
567
- // 主体窗口选择的标签
568
- mainPageMenu: ['none'],
569
- // 默认的配置
570
- config: { page: [] },
571
- // 选中的容器
572
- targetContainer: undefined,
573
- // 控制是否渲染页面
574
- preview: false,
575
- // 控制架构树显隐,用于刷新组件
576
- showPageOrganization: true,
577
- // 用于保存右侧编辑组件的属性
578
- editorPropertiesConfig: {},
579
- // 编辑属性时用到的定时器
580
- inputTimeout: undefined,
581
- // 当前激活的是组件事件中哪一类触发属性,对应事件编辑中的手风琴面板
582
- eventCollapseActive: undefined,
583
- // 控制事件编辑器弹框显隐
584
- showEventEditor: false,
585
- // 控制自定义JS函数弹框显隐
586
- showJSEventEditor: false,
587
- // 控制页面显隐,用于属性面板编辑后,触发页面更新
588
- renderPreview: true,
589
- // 控制弹框显隐,用于属性面板编辑后,触发页面更新
590
- renderModalPreview: true,
591
- // 控制抽屉显隐,用于属性面板编辑后,触发页面更新
592
- renderDrawPreview: true,
593
- // 控制右侧编辑器切换标签页
594
- editorPanelCurrent: ['properties'],
595
- // 事件编辑内容的缓存
596
- eventEditorContent: {},
597
- // 用于事件编辑的回显,在点击事件编辑按钮后,会将此变量赋值
598
- eventEditorCurrent: undefined,
599
- // 保存目标组件可以触发哪些事件
600
- supportedEventType: undefined,
601
- // 控制自定义Logic参数自定义JS函数弹框显隐
602
- showLogicParamJSEditor: false,
603
- // 控制自定义Logic回调弹框显隐
604
- showLogicCallBackEditor: false,
605
- // 保存主体中,当前激活的标签栏ID
606
- activeMainPage: undefined,
607
- // 保存主体中,当前激活的标签栏类型
608
- activeMainPageType: undefined,
609
- // 定义Logic参数从哪些组件获取
610
- logicParamTransferDataSource: [],
611
- // 添加页面容器参数
612
- addComponentTemp: { type: 'page' },
613
- // 控制添加页面容器弹框显隐
614
- showPageContainerAddModal: false,
615
- showLifeCycleFunctionEditor: false,
616
- selectTreeNode: undefined
617
- }
618
- },
619
- provide () {
620
- return {
621
- // 将注册的组件传递给子组件
622
- componentsMap: {}
623
- }
624
- },
625
- methods: {
626
- handleSplit (id, isVertical) {
627
- const target = lowcodeUtils.getComponentConfig(id, this.config)
628
- const row = lowcodeUtils.getRowConfigByComponentId(id, this.config)
629
- let index
630
- for (let i = 0; i < row.length; i++) {
631
- if (row[i].id === id) {
632
- index = i
633
- break
634
- }
635
- }
636
- const cache = JSON.parse(JSON.stringify(target))
637
- if (isVertical) {
638
- const temp = {
639
- type: 'container_page',
640
- span: cache.span,
641
- id: 'container_' + lowcodeUtils.nanoidWithoutSymbol(6),
642
- page: [
643
- {
644
- id: 'container_page_' + lowcodeUtils.nanoidWithoutSymbol(2),
645
- type: 'page',
646
- body: [
647
- []
648
- ]
649
- }
650
- ]
651
- }
652
- cache.span = 24
653
- temp.page[0].body[0].push(cache)
654
- temp.page[0].body[1] = []
655
- temp.page[0].body[1].push({
656
- type: 'container',
657
- span: 24,
658
- id: 'container_' + lowcodeUtils.nanoidWithoutSymbol(6)
659
- })
660
- row.splice(index, 1, temp)
661
- } else {
662
- const outerSpan = cache.span
663
- const firstSpan = Math.round(outerSpan / 2)
664
- const secondSpan = outerSpan - firstSpan
665
- cache.span = firstSpan
666
- row.splice(index, 1, cache, {
667
- type: 'container',
668
- span: secondSpan,
669
- id: 'container_' + lowcodeUtils.nanoidWithoutSymbol(6)
670
- })
671
- }
672
- this.refreshOrganization()
673
- },
674
- refreshRender () {
675
- this.renderPreview = false
676
- this.renderModalPreview = false
677
- this.renderDrawPreview = false
678
- this.$nextTick(() => {
679
- this.renderPreview = true
680
- this.renderModalPreview = true
681
- this.renderDrawPreview = true
682
- })
683
- },
684
- // 添加页面容器弹框确认
685
- handleAddPageContainerModalOk () {
686
- const result = {
687
- id: 'page_' + lowcodeUtils.nanoidWithoutSymbol(6),
688
- type: this.addComponentTemp.type,
689
- title: this.addComponentTemp.title,
690
- width: this.addComponentTemp.width,
691
- body: []
692
- }
693
- this.addComponentTemp = { type: 'page' }
694
- this.config.page.push(result)
695
- this.refreshOrganization()
696
- this.showPageContainerAddModal = false
697
- },
698
- // 添加页面容器类型修改
699
- pageContainerAddTypeChange (value) {
700
- if (value !== 'page') {
701
- this.addComponentTemp = { width: '70%', type: value }
702
- } else {
703
- this.addComponentTemp = { type: value }
704
- }
705
- },
706
- // 添加页面容器
707
- addPageContainer () {
708
- this.addComponentTemp = { type: 'page' }
709
- this.showPageContainerAddModal = true
710
- },
711
- // 通过组件类型和key解析出该key对应的中文定义
712
- resolveEditorPropsLabel (type, key) {
713
- const def = lowcodeUtils.getEditorConfigByType(type)
714
- const propsDef = def.properties
715
- const targetDef = propsDef[key]
716
- if (!targetDef.label) {
717
- targetDef.label = key
718
- targetDef.desc = '未配置该参数的说明!'
719
- } else if (!targetDef.desc) {
720
- targetDef.desc = '未配置该参数的说明!'
721
- }
722
- return targetDef
723
- },
724
- // 架构重命名
725
- rename (id, newName) {
726
- const target = lowcodeUtils.getConfig(id, this.config)
727
- if (id.length <= 2) {
728
- target.title = newName
729
- } else {
730
- target.name = newName
731
- }
732
- this.refreshOrganization()
733
- },
734
- // 复制粘贴组件
735
- handlePasteItem (id, copyCache, type) {
736
- const target = lowcodeUtils.getConfig(id, this.config)
737
- // 页面中插入行
738
- if (type === 'page-row') {
739
- const content = copyCache.content
740
- const contentKeys = Object.keys(content)
741
- const result = []
742
- contentKeys.forEach(key => {
743
- result.push(content[key])
744
- })
745
- target.body.push(result)
746
- } else if (type === 'row-item') {
747
- // 行中插入组件
748
- target.push(copyCache.content)
749
- } else if (type === 'page') {
750
- // 复制页面
751
- this.config.page.push(copyCache)
752
- this.$message.success('复制成功!')
753
- }
754
- this.refreshOrganization()
755
- },
756
- // span属性通过input框修改
757
- changeSpan (event) {
758
- this.editorPropertiesConfig.span = event.target.value
759
- },
760
- // logic从组件中取值穿梭框改变事件
761
- handleLogicParamTransferChange (targetKeys, direction, moveKeys) {
762
- this.eventEditorContent.logicParamTransfer = targetKeys
763
- this.$forceUpdate()
764
- },
765
- // 点击架构树
766
- treeOrganizationClick (id) {
767
- // 如果类型是page证明,选中的是最外层容器
768
- // if (type === 'page') {
769
- // this.mainPageMenu[0] = id
770
- // this.activeMainPage = id
771
- // for (let i = 0; i < this.config.page.length; i++) {
772
- // if (this.config.page[i].id === this.activeMainPage) {
773
- // this.activeMainPageType = this.config.page[i].type
774
- // break
775
- // }
776
- // }
777
- // this.$forceUpdate()
778
- // } else if (type === 'component') {
779
- // this.config.page.forEach(page => {
780
- // page.body.forEach(row => {
781
- // row.forEach(item => {
782
- // if (item.id === id) {
783
- // this.mainPageMenu[0] = page.id
784
- // this.activeMainPage = page.id
785
- // this.activeMainPageType = page.type
786
- // this.$forceUpdate()
787
- // }
788
- // })
789
- // })
790
- // })
791
- // 将组件选中
792
- const target = lowcodeUtils.getComponentConfig(id, this.config)
793
- this.clickComponentInEditor(target)
794
- },
795
- // 架构树拖拽事件
796
- handleTreeDrag (dragKey, dropKey, dropLevel, dropPosition) {
797
- let dragElement
798
- // 如果被拖拽的id小于等于5位则为行
799
- if (dragKey.length <= 5) {
800
- const targetPageId = dragKey.split('_')[0]
801
- const targetRowId = dragKey.split('_')[1] - 1
802
- for (let i = 0; i < this.config.page.length; i++) {
803
- const page = this.config.page[i]
804
- if (page.id === targetPageId) {
805
- dragElement = page.body[targetRowId]
806
- }
807
- }
808
- this.deleteRow(dragKey)
809
- } else {
810
- // 组件的拖拽
811
- dragElement = JSON.parse(JSON.stringify(lowcodeUtils.getComponentConfig(dragKey, this.config)))
812
- this.deleteComponent(dragKey, false)
813
- }
814
-
815
- // position有三种状态,-1表示在目标前,0表示插入,1表示在目标之后
816
- if (dropPosition === 0) {
817
- const target = lowcodeUtils.getComponentConfig(dropKey, this.config)
818
- target.unshift(dragElement)
819
- this.refreshOrganization()
820
- this.$forceUpdate()
821
- } else {
822
- // 如果目标是一行
823
- if (dropLevel === 'row') {
824
- const targetPageId = dropKey.split('_')[0]
825
- const targetRowId = dropKey.split('_')[1] - 1
826
- for (let i = 0; i < this.config.page.length; i++) {
827
- const page = this.config.page[i]
828
- if (page.id === targetPageId) {
829
- if (dropPosition > 0) {
830
- page.body.splice(targetRowId + 1, 0, dragElement)
831
- } else {
832
- page.body.splice(targetRowId, 0, dragElement)
833
- }
834
- this.refreshOrganization()
835
- this.$forceUpdate()
836
- return
837
- }
838
- }
839
- // 如果目标是组件
840
- } else if (dropLevel === 'item') {
841
- for (let i = 0; i < this.config.page.length; i++) {
842
- const page = this.config.page[i]
843
- for (let j = 0; j < page.body.length; j++) {
844
- const row = page.body[j]
845
- for (let k = 0; k < row.length; k++) {
846
- const item = row[k]
847
- if (item.id === dropKey) {
848
- if (dropPosition > 0) {
849
- row.splice(k + 1, 0, dragElement)
850
- } else {
851
- row.splice(k, 0, dragElement)
852
- }
853
- this.refreshOrganization()
854
- this.$forceUpdate()
855
- return
856
- }
857
- }
858
- }
859
- }
860
- }
861
- }
862
- },
863
- // 主页面标签切换
864
- handleMainPageMenuChange (value) {
865
- this.activeMainPage = value.key
866
- for (let i = 0; i < this.config.page.length; i++) {
867
- if (this.config.page[i].id === this.activeMainPage) {
868
- this.activeMainPageType = this.config.page[i].type
869
- return
870
- }
871
- }
872
- },
873
- // 将页面标签类型渲染为对应的文字
874
- determinePageType (type) {
875
- return lowcodeUtils.resolvePageType(type)
876
- },
877
- // 架构添加组件后,将配置添加到config中
878
- handleAddComponent (config) {
879
- this.config.page.push(config)
880
- this.refreshOrganization()
881
- },
882
- // 打开logic回调编辑弹框
883
- openLogicCallbackEditor () {
884
- if (!this.eventEditorContent.logicCallBackFunction) {
885
- this.eventEditorContent.logicCallBackFunction = LogicCallBackFunctionTemplate
886
- }
887
- this.showLogicCallBackEditor = true
888
- },
889
- // 打开logic参数JS编辑器弹框
890
- openLogicParamJSEditor () {
891
- if (!this.eventEditorContent.logicParamJSFunction) {
892
- this.eventEditorContent.logicParamJSFunction = LogicParamFunctionTemplate
893
- }
894
- this.showLogicParamJSEditor = true
895
- },
896
- // 刷新架构
897
- refreshOrganization () {
898
- this.showPageOrganization = false
899
- this.$nextTick(() => {
900
- this.showPageOrganization = true
901
- })
902
- },
903
- // 拖拽完成后,将新的span赋值
904
- handleDrag (targetEle, nextEle) {
905
- const target = lowcodeUtils.getComponentConfig(targetEle.id, this.config.page)
906
- const targetNext = lowcodeUtils.getComponentConfig(nextEle.id, this.config.page)
907
- target.span = targetEle.span
908
- targetNext.span = nextEle.span
909
- },
910
- // 删除组件
911
- deleteComponentInTree (id, type) {
912
- if (type === 'page') {
913
- const page = lowcodeUtils.getPageConfigById(id, this.config)
914
- this.deletePage(page)
915
- } else if (type === 'component') {
916
- this.deleteComponent(id)
917
- } else if (type === 'row') {
918
- this.deleteRow(id)
919
- } else if (type === 'container_page') {
920
- this.deleteContainerPage(id)
921
- }
922
- },
923
- deleteContainerPage (id) {
924
- console.warn('id', id)
925
- const target = lowcodeUtils.getContainerPageOuterByContainerPageId(id, this.config)
926
- console.warn('target', target)
927
- target.type = 'container'
928
- delete target.page
929
- this.targetContainer = undefined
930
- this.editorPropertiesConfig = {}
931
- this.refreshOrganization()
932
- },
933
- // 删除行
934
- deleteRow (id) {
935
- const pageId = id.substring(0, id.length - 2)
936
- const rowId = id.substring(id.length - 1)
937
- const page = lowcodeUtils.getPageConfigById(pageId, this.config)
938
- page.body.splice(rowId - 1, 1)
939
- this.targetContainer = undefined
940
- this.editorPropertiesConfig = {}
941
- this.refreshOrganization()
942
- },
943
- // 删除页面容器
944
- deletePage (page) {
945
- console.warn('123', page)
946
- page.body.forEach(row => {
947
- row.forEach(item => {
948
- if (item.type === 'container_page') {
949
- this.deletePage(item.page)
950
- } else {
951
- delete this.$children[0]._provided.componentsMap[item.id]
952
- }
953
- })
954
- })
955
- for (let i = 0; i < this.config.page.length; i++) {
956
- if (this.config.page[i].id === page.id) {
957
- this.config.page.splice(i, 1)
958
- this.targetContainer = undefined
959
- this.editorPropertiesConfig = {}
960
- this.refreshOrganization()
961
- return
962
- }
963
- }
964
- },
965
- // 删除组件
966
- deleteComponent (id, addOnSpan = true) {
967
- const row = lowcodeUtils.getRowConfigByComponentId(id, this.config)
968
- const target = lowcodeUtils.getComponentConfig(id, this.config)
969
- const deletedSpan = target.span
970
- let index
971
- for (let i = 0; i < row.length; i++) {
972
- if (target.id === row[i].id) {
973
- index = i
974
- break
975
- }
976
- }
977
- row.splice(index, 1)
978
- if (addOnSpan) {
979
- // 如果该组件之前还有组件,将该组件的span加给之前的组件
980
- if (index !== 0) {
981
- row[index - 1].span += deletedSpan
982
- } else if (row.length > 0) {
983
- row[0].span += deletedSpan
984
- }
985
- }
986
- // 从注册的全局Map中删除
987
- delete this.$children[0]._provided.componentsMap[id]
988
- this.targetContainer = undefined
989
- this.editorPropertiesConfig = {}
990
- this.refreshOrganization()
991
- },
992
- // 打开JS函数编辑器
993
- openEventJSEditor () {
994
- if (!this.eventEditorContent.JSFunction) {
995
- this.eventEditorContent.JSFunction = JSEventFunctionTemplate
996
- }
997
- this.showJSEventEditor = true
998
- },
999
- openEventLifeCycleJSEditor () {
1000
- if (!this.eventEditorContent.LifeCycleFunction) {
1001
- this.eventEditorContent.LifeCycleFunction = LifeCycleFunctionTemplate
1002
- }
1003
- this.showLifeCycleFunctionEditor = true
1004
- },
1005
- // 事件编辑器中,点击编辑按钮
1006
- editEventIconClick (eventType, eventIndex) {
1007
- // 找到目标配置
1008
- const targetConfig = lowcodeUtils.getComponentConfig(this.editorPropertiesConfig.id, this.config.page)
1009
- // 将目标对应的配置赋值到事件编辑器缓存
1010
- this.eventEditorContent = { ...targetConfig.onEvent[eventType][eventIndex] }
1011
- this.eventEditorContent.emitType = eventType
1012
- this.eventEditorCurrent = {
1013
- type: eventType,
1014
- index: eventIndex
1015
- }
1016
- this.showEventEditor = true
1017
- },
1018
- // 删除事件
1019
- removeEventClick (eventType, eventIndex) {
1020
- const targetConfig = lowcodeUtils.getComponentConfig(this.editorPropertiesConfig.id, this.config.page)
1021
- targetConfig.onEvent[eventType].splice(eventIndex, 1)
1022
- if (targetConfig.onEvent[eventType].length === 0) {
1023
- delete targetConfig.onEvent[eventType]
1024
- }
1025
- this.$forceUpdate()
1026
- },
1027
- // 添加事件
1028
- addEvent () {
1029
- this.showEventEditor = true
1030
- },
1031
- // 获取所有注册组件
1032
- getAllRenderedComponents () {
1033
- const IDs = Object.keys(this.$children[0]._provided.componentsMap)
1034
- const result = []
1035
- IDs.forEach(id => {
1036
- const config = lowcodeUtils.getConfig(id, this.config)
1037
- if (config.name) {
1038
- result.push(config.name)
1039
- } else {
1040
- result.push(config.id)
1041
- }
1042
- })
1043
- return result
1044
- },
1045
- // 容器删除
1046
- handleContainerDelete (id) {
1047
- let index
1048
- const row = lowcodeUtils.getRowConfigByComponentId(id, this.config)
1049
- for (let i = 0; i < row.length; i++) {
1050
- const item = row[i]
1051
- if (item.id === id) {
1052
- index = i
1053
- break
1054
- }
1055
- }
1056
- row.splice(index, 1)
1057
- this.targetContainer = undefined
1058
- // 如果删除后只剩一个容器,将该容器span设置为24
1059
- if (row.length === 1) {
1060
- row[0].span = 24
1061
- }
1062
- this.refreshOrganization()
1063
- },
1064
- // 事件编辑器点击完成
1065
- handleEventEditorOk () {
1066
- let emitTypeKey = this.eventEditorContent.emitType
1067
- // 是否是自定义事件触发
1068
- if (this.eventEditorContent.customEmitType) {
1069
- emitTypeKey = this.eventEditorContent.customEmitType
1070
- }
1071
- // 如果当前是回显事件
1072
- if (this.eventEditorCurrent) {
1073
- const targetConfig = lowcodeUtils.getComponentConfig(this.editorPropertiesConfig.id, this.config.page)
1074
- targetConfig.onEvent[this.eventEditorCurrent.type][this.eventEditorCurrent.index] = { ...this.eventEditorContent }
1075
- } else {
1076
- // 当前是新增事件
1077
- const target = lowcodeUtils.getComponentConfig(this.editorPropertiesConfig.id, this.config.page)
1078
- // 如果没有onEvent属性则初始化
1079
- if (!target.onEvent) {
1080
- target.onEvent = {}
1081
- }
1082
- // 如果当前触发类型没有初始化,则初始化
1083
- if (!target.onEvent[emitTypeKey]) {
1084
- target.onEvent[emitTypeKey] = []
1085
- }
1086
- // 将缓存的事件属性赋值
1087
- target.onEvent[emitTypeKey].push({
1088
- ...this.eventEditorContent
1089
- })
1090
- }
1091
- this.showEventEditor = false
1092
- this.eventEditorContent = {}
1093
- this.eventEditorCurrent = undefined
1094
- },
1095
- // 关闭事件编辑器弹框
1096
- handleEventEditorCancel () {
1097
- this.showEventEditor = false
1098
- this.eventEditorContent = {}
1099
- this.eventEditorCurrent = undefined
1100
- },
1101
- // 事件编辑器中,触发类型改变
1102
- handleEventEditorTypeChange (type) {
1103
- this.eventEditorContent.emitType = type
1104
- this.$forceUpdate()
1105
- },
1106
- // 事件编辑器中,目标组件改变
1107
- handleEventEditorTargetChange (target) {
1108
- this.eventEditorContent.target = target
1109
- this.$forceUpdate()
1110
- },
1111
- handleEventEditorLifeCycleChange (lifeCycleName) {
1112
- this.eventEditorContent.lifeCycle = lifeCycleName
1113
- },
1114
- // 事件编辑器中,事件类型改变
1115
- handleEventEditorEventTypeChange (type) {
1116
- const componentsMap = this.$children[0]._provided.componentsMap
1117
- this.eventEditorContent.eventType = type
1118
- this.logicParamTransferDataSource = []
1119
- // 如果事件为运行Logic将组件加入穿梭框
1120
- if (type === 'runLogic') {
1121
- const keys = Object.keys(componentsMap)
1122
- keys.forEach(key => {
1123
- const name = lowcodeUtils.getComponentNameById(key, this.config)
1124
- this.logicParamTransferDataSource.push({
1125
- key: key,
1126
- title: name,
1127
- })
1128
- })
1129
- this.eventEditorContent.logicParamTransfer = []
1130
- }
1131
- this.$forceUpdate()
1132
- },
1133
- // 事件编辑器中,目标组件执行事件类型改变
1134
- handleEventEditorTargetEventTypeChange (type) {
1135
- this.eventEditorContent.eventName = type
1136
- this.$forceUpdate()
1137
- },
1138
- // 自定义JS方法弹框确认
1139
- handleJSEventEditorOk () {
1140
- this.showJSEventEditor = false
1141
- },
1142
- // 自定义JS方法弹框关闭
1143
- handleJSEventEditorCancel () {
1144
- this.showJSEventEditor = false
1145
- },
1146
- // 添加组件到容器中
1147
- addComponentToContainer (type) {
1148
- // 如果没有选中容器
1149
- if (!this.targetContainer) {
1150
- this.$message.error('请先选择目标容器!')
1151
- this.targetContainer = undefined
1152
- return
1153
- }
1154
- // 获取选中的容器
1155
- const target = lowcodeUtils.getComponentConfig(this.targetContainer.id, this.config.page)
1156
- // 将容器的类型和id改变
1157
- target.type = type
1158
- target.id = target.type + '_' + lowcodeUtils.nanoidWithoutSymbol(6)
1159
- this.targetContainer = undefined
1160
- this.refreshOrganization()
1161
- },
1162
- // 添加容器
1163
- addContainer () {
1164
- // 如果目标不是一个容器
1165
- if (!this.targetContainer) {
1166
- // 如果没有指定页面容器,则直接报错
1167
- if (this.activeMainPage === undefined) {
1168
- this.$message.error('未选中任何工作空间!')
1169
- return
1170
- }
1171
- // 获取当前选中的页面容器
1172
- let targetIndex = this.activeMainPage
1173
- for (let i = 0; i < this.config.page.length; i++) {
1174
- if (this.config.page[i].id === this.activeMainPage) {
1175
- targetIndex = i
1176
- break
1177
- }
1178
- }
1179
- // 如果是page类型,添加两个容器。其他类型添加一个容器
1180
- if (this.config.page[targetIndex].type === 'page') {
1181
- this.config.page[targetIndex].body.push([
1182
- {
1183
- type: 'container_page',
1184
- span: 24,
1185
- id: 'container_' + lowcodeUtils.nanoidWithoutSymbol(6),
1186
- page: [
1187
- {
1188
- id: 'container_page_' + lowcodeUtils.nanoidWithoutSymbol(6),
1189
- type: 'page',
1190
- body: [
1191
- [
1192
- {
1193
- type: 'container',
1194
- span: 12,
1195
- id: 'container_' + lowcodeUtils.nanoidWithoutSymbol(6)
1196
- },
1197
- {
1198
- type: 'container',
1199
- span: 12,
1200
- id: 'container_' + lowcodeUtils.nanoidWithoutSymbol(6)
1201
- },
1202
- ]
1203
- ]
1204
- }
1205
- ]
1206
- }
1207
- ])
1208
- } else {
1209
- this.config.page[targetIndex].body.push([{
1210
- type: 'container',
1211
- span: 24,
1212
- id: 'container_' + lowcodeUtils.nanoidWithoutSymbol(6)
1213
- }])
1214
- }
1215
- } else {
1216
- // 如果目标是容器
1217
- const row = lowcodeUtils.getRowConfigByComponentId(this.targetContainer.id, this.config)
1218
- const targetInRowIndex = lowcodeUtils.getComponentInRowIndex(this.targetContainer.id, this.config)
1219
- const targetItem = lowcodeUtils.getComponentConfig(this.targetContainer.id, this.config)
1220
- const maxWidth = targetItem.span
1221
- // 确认是水平拆分还是垂直拆分
1222
- this.$confirm({
1223
- content: '是否为水平拆分',
1224
- onOk: () => {
1225
- // 将目标容器一分为二
1226
- row.splice(targetInRowIndex, 1, {
1227
- type: 'container',
1228
- span: Math.floor(maxWidth / 2),
1229
- id: 'container_' + lowcodeUtils.nanoidWithoutSymbol(6)
1230
- }, {
1231
- type: 'container',
1232
- span: Math.ceil(maxWidth / 2),
1233
- id: 'container_' + lowcodeUtils.nanoidWithoutSymbol(6)
1234
- })
1235
- this.targetContainer = undefined
1236
- this.refreshOrganization()
1237
- },
1238
- onCancel: () => {
1239
- targetItem.type = 'container_page'
1240
- targetItem.page = [{
1241
- id: 'container_page_' + lowcodeUtils.nanoidWithoutSymbol(6),
1242
- type: 'page',
1243
- body: [
1244
- [{
1245
- type: 'container',
1246
- span: 24,
1247
- id: 'container_' + lowcodeUtils.nanoidWithoutSymbol(6)
1248
- }],
1249
- [{
1250
- type: 'container',
1251
- span: 24,
1252
- id: 'container_' + lowcodeUtils.nanoidWithoutSymbol(6)
1253
- }]
1254
- ]
1255
- }]
1256
- this.targetContainer = undefined
1257
- this.refreshOrganization()
1258
- }
1259
- })
1260
- }
1261
- this.refreshOrganization()
1262
- },
1263
- // 获取所有已注册组件,用于添加至UI库
1264
- getRegisteredComponents () {
1265
- return Object.keys(registeredRender)
1266
- },
1267
- // 组件属性编辑
1268
- editorPropertiesInputChange (event, key) {
1269
- this.renderPreview = false
1270
- this.renderModalPreview = false
1271
- this.renderDrawPreview = false
1272
- // 如果当前有定时器,清除该定时器,并设置新的定时器
1273
- // 也就是说:每次操作间隔指定时间后才会触发更新
1274
- // 如果在此期间又进行了操作,则重新开始计时
1275
- if (this.inputTimeout) {
1276
- clearTimeout(this.inputTimeout)
1277
- }
1278
- this.inputTimeout = setTimeout(() => {
1279
- const target = lowcodeUtils.getComponentConfig(this.editorPropertiesConfig.id, this.config.page)
1280
- lowcodeLog('组件属性修改', '触发更新', target.id, true, false)
1281
- // 拿到组件注册的配置
1282
- const editorConfig = lowcodeUtils.getEditorConfigById(this.editorPropertiesConfig.id, this.config.page)
1283
- // 根据类型,将input框中的内容赋值
1284
- if (editorConfig.properties[key].type === 'object') {
1285
- target.props[key] = JSON.parse(event.target.value)
1286
- } else if (editorConfig.properties[key].type === 'string') {
1287
- target.props[key] = event.target.value
1288
- } else if (editorConfig.properties[key].type === 'boolean') {
1289
- const input = event.target.value.toLowerCase()
1290
- target.props[key] = input === 'true' || input !== '0'
1291
- }
1292
- this.renderPreview = true
1293
- this.renderModalPreview = true
1294
- this.renderDrawPreview = true
1295
- }, 1500)
1296
- },
1297
- // 切换预览模式
1298
- previewModeActive () {
1299
- // TODO 新标签页中预览
1300
- // const params = {
1301
- // config: this.config
1302
- // }
1303
- // const routeData = this.$router.resolve({
1304
- // path: '/lowCodeReview',
1305
- // query: params
1306
- // })
1307
- // window.open(routeData.location.path, '_blank')
1308
- this.preview = true
1309
- },
1310
- // 切换编辑模式
1311
- editModeActive () {
1312
- this.preview = false
1313
- },
1314
- // 选中某个组件
1315
- clickComponentInEditor (configItem) {
1316
- // 同步选中架构
1317
- this.selectTreeNode = configItem.id
1318
- this.editorPropertiesConfig = {}
1319
- // 如果选中的是容器
1320
- if (configItem.type === 'container') {
1321
- // 如果已经选中,则反选,selected属性用于改变容器样式
1322
- if (configItem.selected) {
1323
- configItem.selected = false
1324
- this.targetContainer = undefined
1325
- } else {
1326
- // 将所有已选中组件取消选择
1327
- lowcodeUtils.unCheckAll(this.config)
1328
- // 将目标设置为选定
1329
- configItem.selected = true
1330
- this.targetContainer = configItem
1331
- }
1332
- return
1333
- }
1334
- // 如果是组件对象
1335
- // 拿注册的配置
1336
- const configInJson = lowcodeUtils.getEditorConfigByType(configItem.type)
1337
- if (configInJson) {
1338
- this.editorPropertiesConfig = configItem
1339
- // 为编辑器变量初始化
1340
- if (configInJson.properties) {
1341
- if (!this.editorPropertiesConfig.props) {
1342
- this.editorPropertiesConfig.props = {}
1343
- }
1344
- const editableKeys = Object.keys(configInJson.properties)
1345
- editableKeys.forEach(editableKey => {
1346
- // 如果该值并不存在,则初始化
1347
- if (!this.editorPropertiesConfig.props[editableKey]) {
1348
- this.editorPropertiesConfig.props[editableKey] = ''
1349
- } else {
1350
- if (typeof this.editorPropertiesConfig.props[editableKey] === 'object') {
1351
- this.editorPropertiesConfig.props[editableKey] = JSON.stringify(this.editorPropertiesConfig.props[editableKey])
1352
- }
1353
- }
1354
- })
1355
- }
1356
- // 为编辑器事件初始化
1357
- if (configInJson.selfEvent) {
1358
- if (!this.editorPropertiesConfig.selfEvent) {
1359
- this.editorPropertiesConfig.selfEvent = []
1360
- configInJson.selfEvent.forEach(everyEvent => {
1361
- this.editorPropertiesConfig.selfEvent.push(everyEvent)
1362
- })
1363
- }
1364
- }
1365
- } else {
1366
- this.editorPropertiesConfig = 'unregistered'
1367
- }
1368
- },
1369
- // 点击测试按钮
1370
- test () {
1371
- // 输出当前配置,和组件注册Map
1372
- console.warn('config', this.config)
1373
- console.warn('map', this.$children[0]._provided.componentsMap)
1374
- },
1375
- // 点击导出按钮
1376
- exportConfig () {
1377
- console.warn('导出', this.config)
1378
- this.$emit('exportConfig', this.config)
1379
- }
1380
- },
1381
- mounted () {
1382
- // 将mixin中已经实现的通用响应方法添加
1383
- this.supportedEventType = [...lowcodeComponentMixin.supportedEventType]
1384
- // 深拷贝外侧传来的配置
1385
- this.config = JSON.parse(JSON.stringify(this.originalConfig))
1386
- this.config = {
1387
- page: [
1388
- {
1389
- id: 'page_KBjw2i',
1390
- type: 'page',
1391
- title: '111',
1392
- body: [
1393
- [
1394
- {
1395
- type: 'XFormTable',
1396
- span: 12,
1397
- id: 'XFormTable_BV6Nwk',
1398
- selected: false,
1399
- props: {
1400
- queryParamsName: '',
1401
- serviceName: ''
1402
- },
1403
- selfEvent: [
1404
- 'action'
1405
- ]
1406
- },
1407
- {
1408
- type: 'XAddNativeForm',
1409
- span: 12,
1410
- id: 'XAddNativeForm_ekihTp',
1411
- selected: false,
1412
- props: {
1413
- configNameForLowCode: '',
1414
- systemNameForLowCode: ''
1415
- },
1416
- selfEvent: [
1417
- 'onSubmit'
1418
- ]
1419
- }
1420
- ],
1421
- [
1422
- {
1423
- type: 'XTreeOne',
1424
- span: 12,
1425
- id: 'XTreeOne_szu7Al',
1426
- selected: false
1427
- },
1428
- {
1429
- type: 'XDescriptions',
1430
- span: 12,
1431
- id: 'XDescriptions_DTkbEg',
1432
- selected: false,
1433
- props: {
1434
- title: '111',
1435
- content: {
1436
- c_f_user_phone: '2323',
1437
- c_f_total_fee: 33356,
1438
- c_f_address: '22',
1439
- c_f_meterlen: 2,
1440
- c_f_bank_card_number: '23',
1441
- c_f_create_user: '超级管理员',
1442
- c_f_customer: '23',
1443
- c_f_balance: 33356,
1444
- c_f_create_date: '2024-06-23 21:31:24',
1445
- c_f_operator_date: '2024-06-23 21:31:24',
1446
- c_f_total_times: 2,
1447
- c_f_user_name: '23',
1448
- c_f_comments: '323',
1449
- c_id: 39,
1450
- c_f_operatorid: '15',
1451
- c_f_operator: '超级管理员',
1452
- c_f_orgid: '9'
1453
- },
1454
- configName: 'Unit_Desc_Config',
1455
- serviceName: 'af-revenue',
1456
- getRealData: true
1457
- },
1458
- selfEvent: []
1459
- }
1460
- ]
1461
- ]
1462
- },
1463
- {
1464
- id: 'page_FgItf6',
1465
- type: 'page',
1466
- title: '22',
1467
- body: [
1468
- [
1469
- {
1470
- type: 'container',
1471
- span: 4,
1472
- id: 'container_ir2gR2',
1473
- selected: false
1474
- },
1475
- {
1476
- type: 'container_page',
1477
- span: 10,
1478
- id: 'container_xIRHGg',
1479
- selected: true,
1480
- page: [
1481
- {
1482
- id: 'container_page_IgYw9u',
1483
- type: 'page',
1484
- body: [
1485
- [
1486
- {
1487
- type: 'container',
1488
- span: 24,
1489
- id: 'container_tqVFCL'
1490
- }
1491
- ],
1492
- [
1493
- {
1494
- type: 'container',
1495
- span: 24,
1496
- id: 'container_i8VXCZ'
1497
- }
1498
- ]
1499
- ]
1500
- }
1501
- ]
1502
- },
1503
- {
1504
- type: 'container',
1505
- span: 10,
1506
- id: 'container_PT9n3Q',
1507
- selected: false
1508
- }
1509
- ],
1510
- [
1511
- {
1512
- type: 'container',
1513
- span: 18,
1514
- id: 'container_q04vQr',
1515
- selected: false
1516
- },
1517
- {
1518
- type: 'container',
1519
- span: 6,
1520
- id: 'container_MKwNvz',
1521
- selected: false
1522
- }
1523
- ]
1524
- ]
1525
- }
1526
- ]
1527
- }
1528
- this.refreshOrganization()
1529
- }
1530
- }
1531
- </script>
1532
-
1533
- <style scoped lang="less">
1534
- .ui-item:hover {
1535
- cursor: pointer;
1536
- }
1537
-
1538
- .ui-item{
1539
- width: 100%;
1540
- height:10%;
1541
- text-align: center;
1542
- overflow-wrap: break-word;
1543
- padding: 7%
1544
- }
1545
-
1546
- .singleEvent {
1547
- border: black dashed 1px;
1548
- padding: 10%;
1549
- }
1550
-
1551
- .edit_icon:hover {
1552
- cursor: pointer;
1553
- }
1554
- </style>
1
+ <template>
2
+ <div>
3
+ <!-- 标题 -->
4
+ <a-card>
5
+ <a-page-header
6
+ title="奥枫低代码前端编辑器"
7
+ sub-title="af-lowcode"
8
+ :backIcon="false"
9
+ @back="() => null"
10
+ >
11
+ <template slot="extra">
12
+ <a-button @click="test">测试</a-button>
13
+ <a-button @click="editModeActive">编辑</a-button>
14
+ <a-button @click="previewModeActive">预览</a-button>
15
+ <a-button type="primary" @click="exportConfig">导出</a-button>
16
+ </template>
17
+ </a-page-header>
18
+ </a-card>
19
+ <!-- 预览模式 -->
20
+ <a-card v-if="preview">
21
+ <editor-page-render :page-config="config" :edit-mode="false"/>
22
+ </a-card>
23
+ <!-- 编辑模式 -->
24
+ <div v-show="!preview">
25
+ <a-row :gutter="2">
26
+ <!-- 左侧 -->
27
+ <a-col :span="4">
28
+ <a-card>
29
+ <a-tabs>
30
+ <!-- UI库 -->
31
+ <a-tab-pane key="1" tab="UI库">
32
+ <a-card style="margin-bottom: 5%">
33
+ <!-- 所有组件 -->
34
+ <a-card-grid class="ui-item" @click="addContainer">
35
+ 组件容器
36
+ </a-card-grid>
37
+ <template v-for="(item, index) in getRegisteredComponents()">
38
+ <a-card-grid :key="index" class="ui-item" @click="addComponentToContainer(item)">
39
+ {{ item }}
40
+ </a-card-grid>
41
+ </template>
42
+ </a-card>
43
+ </a-tab-pane>
44
+ <!-- 页面架构 -->
45
+ <a-tab-pane key="2" tab="架构">
46
+ <div style="margin-bottom: 3%">
47
+ <LowCodePageOrganization
48
+ :config="filterOrganizationConfig()"
49
+ v-if="showPageOrganization"
50
+ :select-tree-node="selectTreeNode"
51
+ @rename="rename"
52
+ @add="handleTreeAdd"
53
+ @split="handleSplit"
54
+ @pasteItem="handlePasteItem"
55
+ @componentMove="handleTreeDrag"
56
+ @deleteComponent="deleteComponentInTree"
57
+ @treeOrganizationClick="treeOrganizationClick"/>
58
+ </div>
59
+ </a-tab-pane>
60
+ </a-tabs>
61
+ </a-card>
62
+ </a-col>
63
+ <!-- 中间主体编辑器 -->
64
+ <a-col :span="15">
65
+ <a-card>
66
+ <!-- 切换显示的组件 -->
67
+ <div style="margin-bottom: 3%">
68
+ <!-- 添加页面组件按钮 -->
69
+ <div style="float: right">
70
+ <a-popover>
71
+ <template slot="content">
72
+ <p>添加页面组件</p>
73
+ </template>
74
+ <a-button @click="addPageContainer" >
75
+ <a-icon type="plus"/>
76
+ </a-button>
77
+ </a-popover>
78
+ </div>
79
+ <!-- 每个页面按钮切换栏 -->
80
+ <a-menu v-model="mainPageMenu" mode="horizontal" @click="handleMainPageMenuChange">
81
+ <template v-for="(page) in config.page">
82
+ <a-menu-item :key="page.id">{{ page.title + '(' + determinePageType(page.type) + ')' }}</a-menu-item>
83
+ </template>
84
+ </a-menu>
85
+ </div>
86
+ <!-- 渲染器 -->
87
+ <div v-if="activeMainPageType === 'page'">
88
+ <editor-page-render
89
+ ref="page_render"
90
+ v-if="renderPreview"
91
+ @spanDrag="handleDrag"
92
+ @containerDelete="handleContainerDelete"
93
+ @clickComponentInEditor="clickComponentInEditor"
94
+ :page-config="{ data: config.data, page: config.page.filter(page => page.id === activeMainPage)}"/>
95
+ <a-skeleton v-else/>
96
+ </div>
97
+ <div v-if="activeMainPageType === 'modal'">
98
+ <editor-page-render
99
+ ref="modal_render"
100
+ v-if="renderModalPreview"
101
+ @spanDrag="handleDrag"
102
+ @containerDelete="handleContainerDelete"
103
+ @clickComponentInEditor="clickComponentInEditor"
104
+ :page-config="{ data: config.data, page: config.page.filter(page => page.id === activeMainPage)}"/>
105
+ <a-skeleton v-else/>
106
+ </div>
107
+ <div v-if="activeMainPageType === 'draw'">
108
+ <editor-page-render
109
+ ref="draw_render"
110
+ v-if="renderDrawPreview"
111
+ @spanDrag="handleDrag"
112
+ @containerDelete="handleContainerDelete"
113
+ @clickComponentInEditor="clickComponentInEditor"
114
+ :page-config="{ data: config.data, page: config.page.filter(page => page.id === activeMainPage)}"/>
115
+ <a-skeleton v-else/>
116
+ </div>
117
+ </a-card>
118
+ </a-col>
119
+ <!-- 右侧 -->
120
+ <a-col :span="5">
121
+ <!-- 属性编辑 -->
122
+ <a-card>
123
+ <template v-if="editorPropertiesConfig === 'unregistered'">
124
+ <p>所选组件并未注册</p>
125
+ </template>
126
+ <template v-else>
127
+ <!-- 组件名 -->
128
+ <template v-if="editorPropertiesConfig.name">
129
+ <h3>组件名</h3>
130
+ <h4>{{ editorPropertiesConfig.name }}</h4>
131
+ </template>
132
+ <template v-else-if="editorPropertiesConfig.id">
133
+ <h3>组件ID</h3>
134
+ <h4>{{ editorPropertiesConfig.id }}</h4>
135
+ </template>
136
+ <!-- 切换 -->
137
+ <a-menu v-model="editorPanelCurrent" mode="horizontal" @click="() => null">
138
+ <a-menu-item key="properties">属性</a-menu-item>
139
+ <a-menu-item key="events">事件</a-menu-item>
140
+ </a-menu>
141
+ <!-- 属性编辑 -->
142
+ <div v-if="editorPanelCurrent[0] === 'properties'">
143
+ <div v-if="editorPropertiesConfig.props !== undefined">
144
+ <div>
145
+ 栅格数:<a-input :default-value="editorPropertiesConfig.span" @change="changeSpan"/>
146
+ </div>
147
+ <template v-for="(value,key) in editorPropertiesConfig.props">
148
+ <div :key="editorPropertiesConfig.id + '_' + key">
149
+ <a-tooltip>
150
+ <template slot="title" v-if="resolveEditorPropsLabel(editorPropertiesConfig.type, key).desc">
151
+ {{ resolveEditorPropsLabel(editorPropertiesConfig.type, key).desc }}
152
+ </template>
153
+ {{ resolveEditorPropsLabel(editorPropertiesConfig.type, key).label }}:
154
+ </a-tooltip>
155
+ <a-input :default-value="value" @change="editorPropertiesInputChange($event, key)"/>
156
+ </div>
157
+ </template>
158
+ </div>
159
+ <p v-else>您未选择任何组件</p>
160
+ </div>
161
+ <!-- 事件编辑 -->
162
+ <div v-else-if="editorPanelCurrent[0] === 'events'">
163
+ <template v-if="editorPropertiesConfig.onEvent !== undefined">
164
+ <a-collapse v-model="eventCollapseActive">
165
+ <a-collapse-panel
166
+ v-for="(eventConfig,eventType) in editorPropertiesConfig.onEvent"
167
+ :key="eventType"
168
+ :header="eventType">
169
+ <div v-for="(singleEvent,singleEventIndex) in eventConfig" :key="singleEventIndex" class="singleEvent">
170
+ <p>
171
+ <span style="color:rgb( 24,144,255)">{{ singleEvent.eventType }}</span>
172
+ 事件
173
+ </p>
174
+ <!-- 事件 编辑/删除 按钮 -->
175
+ <div style="display: flex; justify-content: space-evenly">
176
+ <a-icon type="edit" theme="twoTone" class="edit_icon" @click="editEventIconClick(eventType,singleEventIndex)"/>
177
+ <a-popconfirm title="确认删除" ok-text="确认删除" cancel-text="取消" @confirm="removeEventClick(eventType,singleEventIndex)" @cancel="() => null">
178
+ <a-icon type="delete" theme="twoTone" class="edit_icon"/>
179
+ </a-popconfirm>
180
+ </div>
181
+ </div>
182
+ </a-collapse-panel>
183
+ </a-collapse>
184
+ </template>
185
+ <a-button v-if="editorPropertiesConfig.id !== undefined" @click="addEvent">添加事件</a-button>
186
+ <p v-else>您未选择任何组件</p>
187
+ </div>
188
+ </template>
189
+ </a-card>
190
+ </a-col>
191
+ </a-row>
192
+ </div>
193
+ <!-- 自定义事件弹框 -->
194
+ <a-modal
195
+ title="事件编辑器"
196
+ width="60%"
197
+ :z-index="1001"
198
+ :destroyOnClose="true"
199
+ @ok="handleEventEditorOk"
200
+ @cancel="handleEventEditorCancel"
201
+ v-if="showEventEditor"
202
+ :visible="showEventEditor">
203
+ <a-form :label-col="{ span: 6 }" :wrapper-col="{ span: 14 }">
204
+ <!-- 事件触发类型 -->
205
+ <a-form-item label="事件触发类型">
206
+ <a-select @change="handleEventEditorTypeChange" :default-value="eventEditorContent.emitType">
207
+ <a-select-option
208
+ v-for="(eventType, eventTypeIndex) in editorPropertiesConfig.selfEvent"
209
+ :key="eventTypeIndex"
210
+ :value="eventType">
211
+ {{ eventType }}
212
+ </a-select-option>
213
+ <a-select-option value="customEmitType">
214
+ 自定义触发类型
215
+ </a-select-option>
216
+ <a-select-option value="lifeCycle">
217
+ 生命周期函数
218
+ </a-select-option>
219
+ </a-select>
220
+ </a-form-item>
221
+ <!-- 自定义事件触发类型 -->
222
+ <a-form-item label="自定义事件触发名" v-if="eventEditorContent.emitType === 'customEmitType'">
223
+ <a-input v-model="eventEditorContent.customEmitType"/>
224
+ </a-form-item>
225
+ <!-- 事件类型 -->
226
+ <a-form-item label="事件类型" v-if="eventEditorContent.emitType !== 'lifeCycle'">
227
+ <a-select @change="handleEventEditorEventTypeChange" :default-value="eventEditorContent.eventType">
228
+ <a-select-option value="changeValue">
229
+ 修改组件的值
230
+ </a-select-option>
231
+ <a-select-option value="changeProps">
232
+ 修改组件的Props
233
+ </a-select-option>
234
+ <a-select-option value="runLogic">
235
+ 执行Logic
236
+ </a-select-option>
237
+ <a-select-option value="log">
238
+ 打印日志
239
+ </a-select-option>
240
+ <a-select-option value="showModal" v-if="this.config.page.filter(page => page.type === 'modal').length > 0">
241
+ 修改弹框可见
242
+ </a-select-option>
243
+ <a-select-option value="showDraw" v-if="this.config.page.filter(page => page.type === 'draw').length > 0">
244
+ 修改抽屉可见
245
+ </a-select-option>
246
+ </a-select>
247
+ </a-form-item>
248
+ <!-- 生命周期函数 -->
249
+ <a-form-item label="生命周期名" v-if="eventEditorContent.emitType === 'lifeCycle'">
250
+ <a-select @change="handleEventEditorLifeCycleChange" :default-value="eventEditorContent.lifeCycle">
251
+ <a-select-option value="created">
252
+ created
253
+ </a-select-option>
254
+ <a-select-option value="beforeMount">
255
+ beforeMount
256
+ </a-select-option>
257
+ <a-select-option value="mounted">
258
+ mounted
259
+ </a-select-option>
260
+ <a-select-option value="beforeUpdate">
261
+ beforeUpdate
262
+ </a-select-option>
263
+ <a-select-option value="updated">
264
+ updated
265
+ </a-select-option>
266
+ <a-select-option value="beforeDestroy">
267
+ beforeDestroy
268
+ </a-select-option>
269
+ <a-select-option value="destroyed">
270
+ destroyed
271
+ </a-select-option>
272
+ </a-select>
273
+ </a-form-item>
274
+ <!-- 修改弹框可见 or 修改抽屉可见 -->
275
+ <a-form-item label="修改可见" v-if="eventEditorContent.eventType === 'showModal' || eventEditorContent.eventType === 'showDraw'">
276
+ <a-radio-group v-model="eventEditorContent.visible" button-style="solid">
277
+ <a-radio-button value="open">
278
+ 显示
279
+ </a-radio-button>
280
+ <a-radio-button value="close">
281
+ 隐藏
282
+ </a-radio-button>
283
+ </a-radio-group>
284
+ </a-form-item>
285
+ <!-- 弹框容器ID -->
286
+ <a-form-item label="弹框容器ID" v-if="eventEditorContent.eventType === 'showModal'">
287
+ <a-select v-model="eventEditorContent.containerId">
288
+ <a-select-option
289
+ v-for="(modal) in config.page.filter(page => page.type === 'modal')"
290
+ :key="modal.id"
291
+ :value="modal.id">
292
+ 弹框_{{ modal.id }}
293
+ </a-select-option>
294
+ </a-select>
295
+ </a-form-item>
296
+ <!-- 抽屉容器ID -->
297
+ <a-form-item label="抽屉容器ID" v-if="eventEditorContent.eventType === 'showDraw'">
298
+ <a-select v-model="eventEditorContent.containerId">
299
+ <a-select-option
300
+ v-for="(draw) in config.page.filter(page => page.type === 'draw')"
301
+ :key="draw.id"
302
+ :value="draw.id">
303
+ 抽屉_{{ draw.id }}
304
+ </a-select-option>
305
+ </a-select>
306
+ </a-form-item>
307
+ <!-- Logic名 -->
308
+ <a-form-item label="Logic名" v-if="eventEditorContent.eventType === 'runLogic'">
309
+ <a-input v-model="eventEditorContent.logicName"/>
310
+ </a-form-item>
311
+ <!-- 服务名 -->
312
+ <a-form-item label="服务名" v-if="eventEditorContent.eventType === 'runLogic'">
313
+ <a-input v-model="eventEditorContent.serviceName"/>
314
+ </a-form-item>
315
+ <!-- 自定义Logic参数,由哪些组件传递 -->
316
+ <a-form-item label="Logic参数取值组件" v-if="eventEditorContent.eventType === 'runLogic'">
317
+ <a-transfer
318
+ :data-source="logicParamTransferDataSource"
319
+ :render="item => item.title"
320
+ :target-keys="eventEditorContent.logicParamTransfer"
321
+ @change="handleLogicParamTransferChange"/>
322
+ </a-form-item>
323
+ <!-- 自定义Logic参数 -->
324
+ <a-form-item label="自定义Logic参数" v-if="eventEditorContent.eventType === 'runLogic'">
325
+ <a-button type="primary" @click="openLogicParamJSEditor">
326
+ 打开编辑器
327
+ </a-button>
328
+ </a-form-item>
329
+ <!-- 自定义Logic回调 -->
330
+ <a-form-item label="自定义Logic回调" v-if="eventEditorContent.eventType === 'runLogic'" >
331
+ <a-button type="primary" @click="openLogicCallbackEditor">
332
+ 打开编辑器
333
+ </a-button>
334
+ </a-form-item>
335
+ <!-- 修改组件的值 才会显示的其余参数 -->
336
+ <template v-if="eventEditorContent.eventType === 'changeValue' || eventEditorContent.eventType === 'changeProps'">
337
+ <!-- 目标组件 -->
338
+ <a-form-item label="目标组件">
339
+ <a-select @change="handleEventEditorTargetChange" :default-value="eventEditorContent.target">
340
+ <a-select-option
341
+ v-for="(targetId, targetIndex) in getAllRenderedComponents()"
342
+ :key="targetIndex"
343
+ :value="targetId">
344
+ {{ targetId }}
345
+ </a-select-option>
346
+ </a-select>
347
+ </a-form-item>
348
+ <!-- 目标组件执行事件名 -->
349
+ <a-form-item label="目标组件执行事件名" v-if="eventEditorContent.eventName === 'changeValue'">
350
+ <a-select @change="handleEventEditorTargetEventTypeChange" :default-value="eventEditorContent.eventName">
351
+ <a-select-option :value="eventType" v-for="(eventType,eventTypeIndex) in supportedEventType" :key="'eventType_' + eventTypeIndex">
352
+ {{ eventType }}
353
+ </a-select-option>
354
+ </a-select>
355
+ </a-form-item>
356
+ <!-- 目标组件修改值对应的key -->
357
+ <a-form-item label="目标组件修改值对应的key" v-if="eventEditorContent.target !== undefined">
358
+ <a-input v-model="eventEditorContent.targetKey"/>
359
+ </a-form-item>
360
+ </template>
361
+ <!-- 自定义JS方法 -->
362
+ <a-form-item label="自定义JS方法" v-if="eventEditorContent.emitType !== 'lifeCycle'">
363
+ <a-button type="primary" @click="openEventJSEditor">打开编辑器</a-button>
364
+ </a-form-item>
365
+ <!-- 自定义钩子函数 -->
366
+ <a-form-item label="自定义生命周期函数" v-if="eventEditorContent.emitType === 'lifeCycle'">
367
+ <a-button type="primary" @click="openEventLifeCycleJSEditor">打开编辑器</a-button>
368
+ </a-form-item>
369
+ </a-form>
370
+ </a-modal>
371
+ <!-- 自定义JS事件弹框 -->
372
+ <a-modal
373
+ title="事件编辑器"
374
+ width="60%"
375
+ :destroyOnClose="true"
376
+ :z-index="1002"
377
+ @ok="handleJSEventEditorOk"
378
+ @cancel="handleJSEventEditorCancel"
379
+ :visible="showJSEventEditor">
380
+ <a-popover title="参数说明" style="margin-right: 5%">
381
+ <template slot="content">
382
+ <p>该方法有以下几个参数:</p>
383
+ <p>eventType:事件类型,比如:changeValue代表修改目标组件的值</p>
384
+ <p>data:由事件源发出的参数列表</p>
385
+ <p>targetKey:修改目标组件值所对应的key</p>
386
+ <p>sourceVM:事件源的vue对象</p>
387
+ <p>targetVM:目标的vue对象</p>
388
+ </template>
389
+ <a-button type="primary">
390
+ 参数说明
391
+ </a-button>
392
+ </a-popover>
393
+ <a-popover title="返回值说明" style="margin-bottom: 5%">
394
+ <template slot="content">
395
+ <p>该方法需要的返回值:</p>
396
+ <p>eventType:事件类型</p>
397
+ <p>data:传递给目标组件的数据</p>
398
+ <p>targetKey:修改目标组件值所对应的key</p>
399
+ </template>
400
+ <a-button type="primary">
401
+ 返回值说明
402
+ </a-button>
403
+ </a-popover>
404
+ <code-mirror
405
+ :style-obj="{height:'80%',fontSize:'18px',marginBottom:'15px'}"
406
+ :mode="'javascript'"
407
+ :theme="'monokai'"
408
+ v-model="eventEditorContent.JSFunction"
409
+ :value="eventEditorContent.JSFunction"/>
410
+ </a-modal>
411
+ <!-- 自定义Logic参数JS弹框 -->
412
+ <a-modal
413
+ title="自定义Logic参数JS编辑器"
414
+ width="60%"
415
+ :destroyOnClose="true"
416
+ :z-index="1002"
417
+ @ok="() => { showLogicParamJSEditor = false}"
418
+ @cancel="() => { showLogicParamJSEditor = false}"
419
+ :visible="showLogicParamJSEditor">
420
+ <a-popover title="参数说明" style="margin-right: 5%">
421
+ <template slot="content">
422
+ <p>该方法有以下几个参数:</p>
423
+ <p>componentData:Logic参数取值组件中选中的组件,将会把数据打包存在此对象中,key则为组件的id</p>
424
+ <p>data:由事件源emit发出的参数</p>
425
+ </template>
426
+ <a-button type="primary">
427
+ 参数说明
428
+ </a-button>
429
+ </a-popover>
430
+ <a-popover title="返回值说明" style="margin-bottom: 5%">
431
+ <template slot="content">
432
+ <p>该方法需要一个JSON类型的返回值</p>
433
+ <p>该返回值就是传递给Logic执行的参数</p>
434
+ </template>
435
+ <a-button type="primary">
436
+ 返回值说明
437
+ </a-button>
438
+ </a-popover>
439
+ <code-mirror
440
+ :style-obj="{height:'80%',fontSize:'18px',marginBottom:'15px'}"
441
+ :mode="'javascript'"
442
+ :theme="'monokai'"
443
+ v-model="eventEditorContent.logicParamJSFunction"
444
+ :value="eventEditorContent.logicParamJSFunction"/>
445
+ </a-modal>
446
+ <!-- 自定义Logic回调弹框 -->
447
+ <a-modal
448
+ title="事件编辑器"
449
+ width="60%"
450
+ :destroyOnClose="true"
451
+ :z-index="1002"
452
+ @ok="() => { showLogicCallBackEditor = false}"
453
+ @cancel="() => { showLogicCallBackEditor = false}"
454
+ :visible="showLogicCallBackEditor">
455
+ <a-popover title="参数说明" style="margin-bottom: 5%">
456
+ <template slot="content">
457
+ <p>该方法有以下几个参数:</p>
458
+ <p>componentsMap:所有组件注册的Map</p>
459
+ <p>responseData:后端的返回值</p>
460
+ </template>
461
+ <a-button type="primary">
462
+ 参数说明
463
+ </a-button>
464
+ </a-popover>
465
+ <code-mirror
466
+ :style-obj="{height:'80%',fontSize:'18px',marginBottom:'15px'}"
467
+ :mode="'javascript'"
468
+ :theme="'monokai'"
469
+ v-model="eventEditorContent.logicCallBackFunction"
470
+ :value="eventEditorContent.logicCallBackFunction"/>
471
+ </a-modal>
472
+ <!-- 自定义生命周期函数弹框 -->
473
+ <a-modal
474
+ title="生命周期函数编辑器"
475
+ width="60%"
476
+ :destroyOnClose="true"
477
+ :z-index="1002"
478
+ @ok="() => { showLifeCycleFunctionEditor = false}"
479
+ @cancel="() => { showLifeCycleFunctionEditor = false}"
480
+ :visible="showLifeCycleFunctionEditor">
481
+ <a-popover title="参数说明" style="margin-bottom: 5%">
482
+ <template slot="content">
483
+ <p>该方法有以下几个参数:</p>
484
+ <p>vm:VUE组件对象(this)</p>
485
+ </template>
486
+ <a-button type="primary">
487
+ 参数说明
488
+ </a-button>
489
+ </a-popover>
490
+ <code-mirror
491
+ :style-obj="{height:'80%',fontSize:'18px',marginBottom:'15px'}"
492
+ :mode="'javascript'"
493
+ :theme="'monokai'"
494
+ v-model="eventEditorContent.LifeCycleFunction"
495
+ :value="eventEditorContent.LifeCycleFunction"/>
496
+ </a-modal>
497
+ <!-- 新增页面容器弹框 -->
498
+ <a-modal
499
+ title="新增页面容器"
500
+ width="60%"
501
+ :z-index="1001"
502
+ :destroyOnClose="true"
503
+ @ok="handleAddPageContainerModalOk"
504
+ @cancel="() => { showPageContainerAddModal = false }"
505
+ :visible="showPageContainerAddModal">
506
+ <a-form :label-col="{ span: 7 }" :wrapper-col="{ span: 12 }">
507
+ <!-- 容器类型 -->
508
+ <a-form-item label="容器类型">
509
+ <a-select v-model="addComponentTemp.type" @change="pageContainerAddTypeChange">
510
+ <a-select-option value="page">
511
+ 页面
512
+ </a-select-option>
513
+ <a-select-option value="modal">
514
+ 弹框
515
+ </a-select-option>
516
+ <a-select-option value="draw">
517
+ 抽屉
518
+ </a-select-option>
519
+ </a-select>
520
+ </a-form-item>
521
+ <!-- 标题 -->
522
+ <a-form-item label="标题">
523
+ <a-input v-model="addComponentTemp.title"/>
524
+ </a-form-item>
525
+ <template v-if="addComponentTemp.type !== 'page'">
526
+ <!-- 宽度 -->
527
+ <a-form-item label="宽度">
528
+ <a-input v-model="addComponentTemp.width"/>
529
+ </a-form-item>
530
+ </template>
531
+ </a-form>
532
+ </a-modal>
533
+ </div>
534
+ </template>
535
+
536
+ <script>
537
+ import editorPageRender from '@vue2-client/base-client/components/common/LowCodePageRender/editorPageRender.vue'
538
+ import * as registeredRender from '@vue2-client/utils/lowcode/registerComponentForRender'
539
+ import * as lowcodeUtils from '@vue2-client/utils/lowcode/lowcodeUtils'
540
+ import codeMirror from '@vue2-client/components/CodeMirror/inedx.vue'
541
+ import lowcodeComponentMixin from '@vue2-client/utils/lowcode/lowcodeComponentMixin'
542
+ // eslint-disable-next-line no-unused-vars
543
+ import lowcodeLog from '@vue2-client/utils/lowcode/lowcodeLog'
544
+ import LowCodePageOrganization from '@vue2-client/base-client/components/common/LowCodeComponent/LowCodePageOrganization.vue'
545
+
546
+ // 函数编辑器显示的模板
547
+ const JSEventFunctionTemplate = 'function(eventType, data, targetKey, sourceVM, targetVM) {\n \n return {\n "eventType": eventType,\n "data": data,\n "targetKey": targetKey\n }\n}'
548
+ const LogicParamFunctionTemplate = 'function(componentData, data) {\n \n return {\n \n }\n}'
549
+ const LogicCallBackFunctionTemplate = 'function(componentsMap, responseData) {\n \n}'
550
+ const LifeCycleFunctionTemplate = 'function(vm) {\n \n}'
551
+
552
+ export default {
553
+ components: {
554
+ LowCodePageOrganization,
555
+ editorPageRender,
556
+ codeMirror
557
+ },
558
+ props: {
559
+ // 页面原始的配置,用于从琉璃中读取
560
+ originalConfig: {
561
+ type: Object,
562
+ default: () => {
563
+ return {
564
+ page: []
565
+ }
566
+ }
567
+ }
568
+ },
569
+ data () {
570
+ return {
571
+ // 主体窗口选择的标签
572
+ mainPageMenu: ['none'],
573
+ // 默认的配置
574
+ config: { page: [] },
575
+ // 选中的容器
576
+ targetContainer: undefined,
577
+ // 控制是否渲染页面
578
+ preview: false,
579
+ // 控制架构树显隐,用于刷新组件
580
+ showPageOrganization: true,
581
+ // 用于保存右侧编辑组件的属性
582
+ editorPropertiesConfig: {},
583
+ // 编辑属性时用到的定时器
584
+ inputTimeout: undefined,
585
+ // 当前激活的是组件事件中哪一类触发属性,对应事件编辑中的手风琴面板
586
+ eventCollapseActive: undefined,
587
+ // 控制事件编辑器弹框显隐
588
+ showEventEditor: false,
589
+ // 控制自定义JS函数弹框显隐
590
+ showJSEventEditor: false,
591
+ // 控制页面显隐,用于属性面板编辑后,触发页面更新
592
+ renderPreview: true,
593
+ // 控制弹框显隐,用于属性面板编辑后,触发页面更新
594
+ renderModalPreview: true,
595
+ // 控制抽屉显隐,用于属性面板编辑后,触发页面更新
596
+ renderDrawPreview: true,
597
+ // 控制右侧编辑器切换标签页
598
+ editorPanelCurrent: ['properties'],
599
+ // 事件编辑内容的缓存
600
+ eventEditorContent: {},
601
+ // 用于事件编辑的回显,在点击事件编辑按钮后,会将此变量赋值
602
+ eventEditorCurrent: undefined,
603
+ // 保存目标组件可以触发哪些事件
604
+ supportedEventType: undefined,
605
+ // 控制自定义Logic参数自定义JS函数弹框显隐
606
+ showLogicParamJSEditor: false,
607
+ // 控制自定义Logic回调弹框显隐
608
+ showLogicCallBackEditor: false,
609
+ // 保存主体中,当前激活的标签栏ID
610
+ activeMainPage: undefined,
611
+ // 保存主体中,当前激活的标签栏类型
612
+ activeMainPageType: undefined,
613
+ // 定义Logic参数从哪些组件获取
614
+ logicParamTransferDataSource: [],
615
+ // 添加页面容器参数
616
+ addComponentTemp: { type: 'page' },
617
+ // 控制添加页面容器弹框显隐
618
+ showPageContainerAddModal: false,
619
+ showLifeCycleFunctionEditor: false,
620
+ selectTreeNode: undefined
621
+ }
622
+ },
623
+ provide () {
624
+ return {
625
+ // 将注册的组件传递给子组件
626
+ componentsMap: {}
627
+ }
628
+ },
629
+ methods: {
630
+ handleTreeAdd (id, type) {
631
+ if (type === 'container') {
632
+ const lastIndex = id.lastIndexOf('_')
633
+ const pageId = id.substring(0, lastIndex)
634
+ const rowIndex = id.substring(lastIndex + 1)
635
+ const row = lowcodeUtils.getRowByRowId(pageId, rowIndex - 1, this.config)
636
+ if (row.length === 0) {
637
+ row.push({
638
+ type: 'container',
639
+ span: 24,
640
+ id: 'container_' + lowcodeUtils.nanoidWithoutSymbol(6)
641
+ })
642
+ } else {
643
+ const lastSpan = row[row.length - 1].span
644
+ const firstSpan = Math.round(lastSpan / 2)
645
+ const newSpan = lastSpan - firstSpan
646
+ row[row.length - 1].span = firstSpan
647
+ row.push({
648
+ type: 'container',
649
+ span: newSpan,
650
+ id: 'container_' + lowcodeUtils.nanoidWithoutSymbol(6)
651
+ })
652
+ }
653
+ } else {
654
+ const page = lowcodeUtils.getPageConfigById(id, this.config)
655
+ page.body.push([])
656
+ }
657
+ this.refreshOrganization()
658
+ },
659
+ filterOrganizationConfig () {
660
+ const result = { page: [] }
661
+ this.config.page.forEach(page => {
662
+ if (page.id === this.activeMainPage) {
663
+ result.page.push(page)
664
+ }
665
+ })
666
+ return result
667
+ },
668
+ handleSplit (id, isVertical) {
669
+ const target = lowcodeUtils.getComponentConfig(id, this.config)
670
+ const row = lowcodeUtils.getRowConfigByComponentId(id, this.config)
671
+ let index
672
+ for (let i = 0; i < row.length; i++) {
673
+ if (row[i].id === id) {
674
+ index = i
675
+ break
676
+ }
677
+ }
678
+ const cache = JSON.parse(JSON.stringify(target))
679
+ if (isVertical) {
680
+ const temp = {
681
+ type: 'container_page',
682
+ span: cache.span,
683
+ id: 'container_' + lowcodeUtils.nanoidWithoutSymbol(6),
684
+ page: [
685
+ {
686
+ id: 'container_page_' + lowcodeUtils.nanoidWithoutSymbol(2),
687
+ type: 'page',
688
+ body: [
689
+ []
690
+ ]
691
+ }
692
+ ]
693
+ }
694
+ cache.span = 24
695
+ temp.page[0].body[0].push(cache)
696
+ temp.page[0].body[1] = []
697
+ temp.page[0].body[1].push({
698
+ type: 'container',
699
+ span: 24,
700
+ id: 'container_' + lowcodeUtils.nanoidWithoutSymbol(6)
701
+ })
702
+ row.splice(index, 1, temp)
703
+ } else {
704
+ const outerSpan = cache.span
705
+ const firstSpan = Math.round(outerSpan / 2)
706
+ const secondSpan = outerSpan - firstSpan
707
+ cache.span = firstSpan
708
+ row.splice(index, 1, cache, {
709
+ type: 'container',
710
+ span: secondSpan,
711
+ id: 'container_' + lowcodeUtils.nanoidWithoutSymbol(6)
712
+ })
713
+ }
714
+ this.refreshOrganization()
715
+ },
716
+ refreshRender () {
717
+ this.renderPreview = false
718
+ this.renderModalPreview = false
719
+ this.renderDrawPreview = false
720
+ this.$nextTick(() => {
721
+ this.renderPreview = true
722
+ this.renderModalPreview = true
723
+ this.renderDrawPreview = true
724
+ })
725
+ },
726
+ // 添加页面容器弹框确认
727
+ handleAddPageContainerModalOk () {
728
+ const result = {
729
+ id: 'page_' + lowcodeUtils.nanoidWithoutSymbol(6),
730
+ type: this.addComponentTemp.type,
731
+ title: this.addComponentTemp.title,
732
+ width: this.addComponentTemp.width,
733
+ body: []
734
+ }
735
+ this.addComponentTemp = { type: 'page' }
736
+ this.config.page.push(result)
737
+ this.refreshOrganization()
738
+ this.showPageContainerAddModal = false
739
+ },
740
+ // 添加页面容器类型修改
741
+ pageContainerAddTypeChange (value) {
742
+ if (value !== 'page') {
743
+ this.addComponentTemp = { width: '70%', type: value }
744
+ } else {
745
+ this.addComponentTemp = { type: value }
746
+ }
747
+ },
748
+ // 添加页面容器
749
+ addPageContainer () {
750
+ this.addComponentTemp = { type: 'page' }
751
+ this.showPageContainerAddModal = true
752
+ },
753
+ // 通过组件类型和key解析出该key对应的中文定义
754
+ resolveEditorPropsLabel (type, key) {
755
+ const def = lowcodeUtils.getEditorConfigByType(type)
756
+ const propsDef = def.properties
757
+ const targetDef = propsDef[key]
758
+ if (!targetDef.label) {
759
+ targetDef.label = key
760
+ targetDef.desc = '未配置该参数的说明!'
761
+ } else if (!targetDef.desc) {
762
+ targetDef.desc = '未配置该参数的说明!'
763
+ }
764
+ return targetDef
765
+ },
766
+ // 架构重命名
767
+ rename (id, newName) {
768
+ const target = lowcodeUtils.getConfig(id, this.config)
769
+ if (id.length <= 2) {
770
+ target.title = newName
771
+ } else {
772
+ target.name = newName
773
+ }
774
+ this.refreshOrganization()
775
+ },
776
+ // 复制粘贴组件
777
+ handlePasteItem (id, copyCache, type) {
778
+ const target = lowcodeUtils.getConfig(id, this.config)
779
+ // 页面中插入行
780
+ if (type === 'page-row') {
781
+ const content = copyCache.content
782
+ const contentKeys = Object.keys(content)
783
+ const result = []
784
+ contentKeys.forEach(key => {
785
+ result.push(content[key])
786
+ })
787
+ target.body.push(result)
788
+ } else if (type === 'row-item') {
789
+ // 行中插入组件
790
+ target.push(copyCache.content)
791
+ } else if (type === 'page') {
792
+ // 复制页面
793
+ this.config.page.push(copyCache)
794
+ this.$message.success('复制成功!')
795
+ }
796
+ this.refreshOrganization()
797
+ },
798
+ // span属性通过input框修改
799
+ changeSpan (event) {
800
+ this.editorPropertiesConfig.span = event.target.value
801
+ },
802
+ // logic从组件中取值穿梭框改变事件
803
+ handleLogicParamTransferChange (targetKeys, direction, moveKeys) {
804
+ this.eventEditorContent.logicParamTransfer = targetKeys
805
+ this.$forceUpdate()
806
+ },
807
+ // 点击架构树
808
+ treeOrganizationClick (id) {
809
+ // 如果类型是page证明,选中的是最外层容器
810
+ // if (type === 'page') {
811
+ // this.mainPageMenu[0] = id
812
+ // this.activeMainPage = id
813
+ // for (let i = 0; i < this.config.page.length; i++) {
814
+ // if (this.config.page[i].id === this.activeMainPage) {
815
+ // this.activeMainPageType = this.config.page[i].type
816
+ // break
817
+ // }
818
+ // }
819
+ // this.$forceUpdate()
820
+ // } else if (type === 'component') {
821
+ // this.config.page.forEach(page => {
822
+ // page.body.forEach(row => {
823
+ // row.forEach(item => {
824
+ // if (item.id === id) {
825
+ // this.mainPageMenu[0] = page.id
826
+ // this.activeMainPage = page.id
827
+ // this.activeMainPageType = page.type
828
+ // this.$forceUpdate()
829
+ // }
830
+ // })
831
+ // })
832
+ // })
833
+ let target
834
+ if (id.includes('container_page')) {
835
+ target = lowcodeUtils.getContainerPageOuterByContainerPageId(id, this.config)
836
+ } else {
837
+ target = lowcodeUtils.getComponentConfig(id, this.config)
838
+ }
839
+ // 将组件选中
840
+ this.clickComponentInEditor(target)
841
+ this.twink(id)
842
+ },
843
+ // 架构树拖拽事件
844
+ handleTreeDrag (dragKey, dropKey, dragLevel, dropLevel, dropPosition, dragType) {
845
+ // 只有三种情况可以拖拽
846
+ // 1.平级挪
847
+ // 2.高一级插
848
+ // 3.行插子页面
849
+ let dragEle, rowConfig, father, cache, deleteIndex
850
+
851
+ // 复制移动组件,并将其从原位删除
852
+ switch (dragLevel.type) {
853
+ case 'row':
854
+ rowConfig = lowcodeUtils.getPageIdAndRowIndexByRowId(dragKey)
855
+ father = lowcodeUtils.getPageConfigById(rowConfig.pageId, this.config)
856
+ dragEle = father.body[rowConfig.rowIndex - 1]
857
+ // 复制原始
858
+ cache = JSON.parse(JSON.stringify(dragEle))
859
+ // 删除原始
860
+ deleteIndex = rowConfig.rowIndex - 1
861
+ father.body.splice(deleteIndex, 1, { placeHold: true })
862
+ break
863
+ case 'item':
864
+ father = lowcodeUtils.getRowConfigByComponentId(dragKey, this.config)
865
+ dragEle = lowcodeUtils.getComponentConfig(dragKey, this.config)
866
+ // 复制原始
867
+ cache = JSON.parse(JSON.stringify(dragEle))
868
+ // 删除原始
869
+ for (let i = 0; i < father.length; i++) {
870
+ const item = father[i]
871
+ if (item.id === dragKey) {
872
+ deleteIndex = i
873
+ break
874
+ }
875
+ }
876
+ father.splice(deleteIndex, 1, { placeHold: true })
877
+ break
878
+ case 'container_page':
879
+ father = lowcodeUtils.getContainerPageRow(dragKey, this.config)
880
+ dragEle = lowcodeUtils.getContainerPageOuterByContainerPageId(dragKey, this.config)
881
+ // 复制原始
882
+ cache = JSON.parse(JSON.stringify(dragEle))
883
+ // 删除原始
884
+ for (let i = 0; i < father.length; i++) {
885
+ const item = father[i]
886
+ if (item.type === 'container_page' && item.page[0].id === dragKey) {
887
+ deleteIndex = i
888
+ break
889
+ }
890
+ }
891
+ father.splice(deleteIndex, 1, { placeHold: true })
892
+ break
893
+ }
894
+
895
+ let target, dropConfig, targetCache, targetIndex
896
+ switch (dragType) {
897
+ case 'move':
898
+ // 1. 平级挪
899
+ switch (dragLevel.type) {
900
+ case 'row':
901
+ // 移动行
902
+ // 拿到父容器和目标Index
903
+ dropConfig = lowcodeUtils.getPageIdAndRowIndexByRowId(dropKey)
904
+ target = lowcodeUtils.getPageConfigById(dropConfig.pageId, this.config)
905
+ // 保存目标
906
+ targetCache = target.body[dropConfig.rowIndex - 1]
907
+ // 插入
908
+ console.warn('temp', JSON.parse(JSON.stringify(target)))
909
+ console.warn('temp', dropConfig.rowIndex - 1)
910
+ if (dropPosition < 0) {
911
+ target.body.splice(dropConfig.rowIndex - 1, 1, cache, targetCache)
912
+ } else {
913
+ target.body.splice(dropConfig.rowIndex - 1, 1, targetCache, cache)
914
+ }
915
+ // 清理占位
916
+ for (let i = 0; i < target.body.length; i++) {
917
+ const item = target.body[i]
918
+ if (item.placeHold) {
919
+ target.body.splice(i, 1)
920
+ break
921
+ }
922
+ }
923
+ break
924
+ case 'item':
925
+ // 移动组件
926
+ // 拿到父容器和目标Index
927
+ if (dropLevel.type === 'container_page') {
928
+ target = lowcodeUtils.getContainerPageRow(dropKey, this.config)
929
+ for (let i = 0; i < target.length; i++) {
930
+ const item = target[i]
931
+ if (item.type === 'container_page' && item.page[0].id === dropKey) {
932
+ targetIndex = i
933
+ break
934
+ }
935
+ }
936
+ } else {
937
+ target = lowcodeUtils.getRowByComponentId(dropKey, this.config)
938
+ for (let i = 0; i < target.length; i++) {
939
+ const item = target[i]
940
+ if (item.id === dropKey) {
941
+ targetIndex = i
942
+ break
943
+ }
944
+ }
945
+ }
946
+ // 保存目标
947
+ targetCache = target[targetIndex]
948
+ // 插入
949
+ if (dropPosition < 0) {
950
+ target.splice(targetIndex, 1, cache, targetCache)
951
+ } else {
952
+ target.splice(targetIndex, 1, targetCache, cache)
953
+ }
954
+ // 清理占位
955
+ for (let i = 0; i < target.length; i++) {
956
+ const item = target[i]
957
+ if (item.placeHold) {
958
+ target.splice(i, 1)
959
+ break
960
+ }
961
+ }
962
+ break
963
+ case 'container_page':
964
+ // 移动容器页面
965
+ // 拿到父容器和目标Index
966
+ if (dropLevel.type === 'container_page') {
967
+ target = lowcodeUtils.getContainerPageRow(dropKey, this.config)
968
+ for (let i = 0; i < target.length; i++) {
969
+ const item = target[i]
970
+ if (item.type === 'container_page' && item.page[0].id === dropKey) {
971
+ targetIndex = i
972
+ break
973
+ }
974
+ }
975
+ } else {
976
+ target = lowcodeUtils.getRowByComponentId(dropKey, this.config)
977
+ for (let i = 0; i < target.length; i++) {
978
+ const item = target[i]
979
+ if (item.id === dropKey) {
980
+ targetIndex = i
981
+ break
982
+ }
983
+ }
984
+ }
985
+ // 保存目标
986
+ targetCache = target[targetIndex]
987
+ // 插入
988
+ if (dropPosition < 0) {
989
+ target.splice(targetIndex, 1, cache, targetCache)
990
+ } else {
991
+ target.splice(targetIndex, 1, targetCache, cache)
992
+ }
993
+ // 清理占位
994
+ for (let i = 0; i < target.length; i++) {
995
+ const item = target[i]
996
+ if (item.placeHold) {
997
+ target.splice(i, 1)
998
+ break
999
+ }
1000
+ }
1001
+ }
1002
+ break
1003
+ case 'higher':
1004
+ // 2.高一级插
1005
+ switch (dragLevel.type) {
1006
+ case 'row':
1007
+ // 行插页
1008
+ target = lowcodeUtils.getPageConfigById(dropKey, this.config)
1009
+ target.body.push(cache)
1010
+ for (let i = 0; i < father.body.length; i++) {
1011
+ const item = father.body[i]
1012
+ if (item.placeHold) {
1013
+ father.body.splice(i, 1)
1014
+ break
1015
+ }
1016
+ }
1017
+ break
1018
+ case 'item':
1019
+ // 组件插行
1020
+ rowConfig = lowcodeUtils.getPageIdAndRowIndexByRowId(dropKey)
1021
+ target = lowcodeUtils.getRowByRowId(rowConfig.pageId, rowConfig.rowIndex - 1, this.config)
1022
+ target.push(cache)
1023
+ for (let i = 0; i < father.length; i++) {
1024
+ if (father[i].placeHold) {
1025
+ father.splice(i, 1)
1026
+ break
1027
+ }
1028
+ }
1029
+ break
1030
+ case 'container_page':
1031
+ // 子页面插行
1032
+ rowConfig = lowcodeUtils.getPageIdAndRowIndexByRowId(dropKey)
1033
+ target = lowcodeUtils.getRowByRowId(rowConfig.pageId, rowConfig.rowIndex - 1, this.config)
1034
+ target.push(cache)
1035
+ for (let i = 0; i < father.length; i++) {
1036
+ if (father[i].placeHold) {
1037
+ father.splice(i, 1)
1038
+ break
1039
+ }
1040
+ }
1041
+ break
1042
+ }
1043
+ break
1044
+ case 'rowToContainer':
1045
+ // 3.行插子页面
1046
+ target = lowcodeUtils.getContainerPageOuterByContainerPageId(dropKey, this.config)
1047
+ target.page[0].body.push(cache)
1048
+ for (let i = 0; i < father.body.length; i++) {
1049
+ const item = father.body[i]
1050
+ if (item.placeHold) {
1051
+ father.body.splice(i, 1)
1052
+ break
1053
+ }
1054
+ }
1055
+ break
1056
+ }
1057
+
1058
+ this.refreshOrganization()
1059
+ },
1060
+ cleanPlaceHolder (config) {
1061
+ for (let i = 0; i < config.page.length; i++) {
1062
+ const page = config.page[i]
1063
+ if (page.placeHold) {
1064
+ config.page.splice(i, 1)
1065
+ return true
1066
+ }
1067
+ for (let j = 0; j < page.body.length; j++) {
1068
+ const row = page.body[j]
1069
+ if (row.placeHold) {
1070
+ page.splice(j, 1)
1071
+ return true
1072
+ }
1073
+ for (let k = 0; k < row.length; k++) {
1074
+ const item = row[k]
1075
+ if (item.placeHold) {
1076
+ row.splice(k, 1)
1077
+ return true
1078
+ }
1079
+ if (item === 'container_page') {
1080
+ const flag = this.cleanPlaceHolder(item)
1081
+ if (flag) {
1082
+ return true
1083
+ }
1084
+ }
1085
+ }
1086
+ }
1087
+ }
1088
+ },
1089
+ // 主页面标签切换
1090
+ handleMainPageMenuChange (value) {
1091
+ this.activeMainPage = value.key
1092
+ for (let i = 0; i < this.config.page.length; i++) {
1093
+ if (this.config.page[i].id === this.activeMainPage) {
1094
+ this.activeMainPageType = this.config.page[i].type
1095
+ this.refreshOrganization()
1096
+ return
1097
+ }
1098
+ }
1099
+ },
1100
+ // 将页面标签类型渲染为对应的文字
1101
+ determinePageType (type) {
1102
+ return lowcodeUtils.resolvePageType(type)
1103
+ },
1104
+ // 架构添加组件后,将配置添加到config中
1105
+ handleAddComponent (config) {
1106
+ this.config.page.push(config)
1107
+ this.refreshOrganization()
1108
+ },
1109
+ // 打开logic回调编辑弹框
1110
+ openLogicCallbackEditor () {
1111
+ if (!this.eventEditorContent.logicCallBackFunction) {
1112
+ this.eventEditorContent.logicCallBackFunction = LogicCallBackFunctionTemplate
1113
+ }
1114
+ this.showLogicCallBackEditor = true
1115
+ },
1116
+ // 打开logic参数JS编辑器弹框
1117
+ openLogicParamJSEditor () {
1118
+ if (!this.eventEditorContent.logicParamJSFunction) {
1119
+ this.eventEditorContent.logicParamJSFunction = LogicParamFunctionTemplate
1120
+ }
1121
+ this.showLogicParamJSEditor = true
1122
+ },
1123
+ // 刷新架构
1124
+ refreshOrganization () {
1125
+ this.showPageOrganization = false
1126
+ this.$nextTick(() => {
1127
+ this.showPageOrganization = true
1128
+ })
1129
+ },
1130
+ // 拖拽完成后,将新的span赋值
1131
+ handleDrag (targetEle, nextEle) {
1132
+ const target = lowcodeUtils.getComponentConfig(targetEle.id, this.config.page)
1133
+ const targetNext = lowcodeUtils.getComponentConfig(nextEle.id, this.config.page)
1134
+ target.span = targetEle.span
1135
+ targetNext.span = nextEle.span
1136
+ },
1137
+ // 删除组件
1138
+ deleteComponentInTree (id, type) {
1139
+ if (type === 'page') {
1140
+ const page = lowcodeUtils.getPageConfigById(id, this.config)
1141
+ this.deletePage(page)
1142
+ } else if (type === 'component') {
1143
+ this.deleteComponent(id)
1144
+ } else if (type === 'row') {
1145
+ this.deleteRow(id)
1146
+ } else if (type === 'container_page') {
1147
+ this.deleteContainerPage(id)
1148
+ }
1149
+ },
1150
+ deleteContainerPage (id) {
1151
+ console.warn('id', id)
1152
+ const target = lowcodeUtils.getContainerPageOuterByContainerPageId(id, this.config)
1153
+ console.warn('target', target)
1154
+ target.type = 'container'
1155
+ delete target.page
1156
+ this.targetContainer = undefined
1157
+ this.editorPropertiesConfig = {}
1158
+ this.refreshOrganization()
1159
+ },
1160
+ // 删除行
1161
+ deleteRow (id) {
1162
+ const pageId = id.substring(0, id.length - 2)
1163
+ const rowId = id.substring(id.length - 1)
1164
+ const page = lowcodeUtils.getPageConfigById(pageId, this.config)
1165
+ page.body.splice(rowId - 1, 1)
1166
+ this.targetContainer = undefined
1167
+ this.editorPropertiesConfig = {}
1168
+ this.refreshOrganization()
1169
+ },
1170
+ // 删除页面容器
1171
+ deletePage (page) {
1172
+ console.warn('123', page)
1173
+ page.body.forEach(row => {
1174
+ row.forEach(item => {
1175
+ if (item.type === 'container_page') {
1176
+ this.deletePage(item.page)
1177
+ } else {
1178
+ delete this.$children[0]._provided.componentsMap[item.id]
1179
+ }
1180
+ })
1181
+ })
1182
+ for (let i = 0; i < this.config.page.length; i++) {
1183
+ if (this.config.page[i].id === page.id) {
1184
+ this.config.page.splice(i, 1)
1185
+ this.targetContainer = undefined
1186
+ this.editorPropertiesConfig = {}
1187
+ this.refreshOrganization()
1188
+ return
1189
+ }
1190
+ }
1191
+ },
1192
+ // 删除组件
1193
+ deleteComponent (id, addOnSpan = true) {
1194
+ const row = lowcodeUtils.getRowConfigByComponentId(id, this.config)
1195
+ const target = lowcodeUtils.getComponentConfig(id, this.config)
1196
+ const deletedSpan = target.span
1197
+ let index
1198
+ for (let i = 0; i < row.length; i++) {
1199
+ if (target.id === row[i].id) {
1200
+ index = i
1201
+ break
1202
+ }
1203
+ }
1204
+ row.splice(index, 1)
1205
+ if (addOnSpan) {
1206
+ // 如果该组件之前还有组件,将该组件的span加给之前的组件
1207
+ if (index !== 0) {
1208
+ row[index - 1].span += deletedSpan
1209
+ } else if (row.length > 0) {
1210
+ row[0].span += deletedSpan
1211
+ }
1212
+ }
1213
+ // 从注册的全局Map中删除
1214
+ delete this.$children[0]._provided.componentsMap[id]
1215
+ this.targetContainer = undefined
1216
+ this.editorPropertiesConfig = {}
1217
+ this.refreshOrganization()
1218
+ },
1219
+ // 打开JS函数编辑器
1220
+ openEventJSEditor () {
1221
+ if (!this.eventEditorContent.JSFunction) {
1222
+ this.eventEditorContent.JSFunction = JSEventFunctionTemplate
1223
+ }
1224
+ this.showJSEventEditor = true
1225
+ },
1226
+ openEventLifeCycleJSEditor () {
1227
+ if (!this.eventEditorContent.LifeCycleFunction) {
1228
+ this.eventEditorContent.LifeCycleFunction = LifeCycleFunctionTemplate
1229
+ }
1230
+ this.showLifeCycleFunctionEditor = true
1231
+ },
1232
+ // 事件编辑器中,点击编辑按钮
1233
+ editEventIconClick (eventType, eventIndex) {
1234
+ // 找到目标配置
1235
+ const targetConfig = lowcodeUtils.getComponentConfig(this.editorPropertiesConfig.id, this.config.page)
1236
+ // 将目标对应的配置赋值到事件编辑器缓存
1237
+ this.eventEditorContent = { ...targetConfig.onEvent[eventType][eventIndex] }
1238
+ this.eventEditorContent.emitType = eventType
1239
+ this.eventEditorCurrent = {
1240
+ type: eventType,
1241
+ index: eventIndex
1242
+ }
1243
+ this.showEventEditor = true
1244
+ },
1245
+ // 删除事件
1246
+ removeEventClick (eventType, eventIndex) {
1247
+ const targetConfig = lowcodeUtils.getComponentConfig(this.editorPropertiesConfig.id, this.config.page)
1248
+ targetConfig.onEvent[eventType].splice(eventIndex, 1)
1249
+ if (targetConfig.onEvent[eventType].length === 0) {
1250
+ delete targetConfig.onEvent[eventType]
1251
+ }
1252
+ this.$forceUpdate()
1253
+ },
1254
+ // 添加事件
1255
+ addEvent () {
1256
+ this.showEventEditor = true
1257
+ },
1258
+ // 获取所有注册组件
1259
+ getAllRenderedComponents () {
1260
+ const IDs = Object.keys(this.$children[0]._provided.componentsMap)
1261
+ const result = []
1262
+ IDs.forEach(id => {
1263
+ const config = lowcodeUtils.getConfig(id, this.config)
1264
+ if (config.name) {
1265
+ result.push(config.name)
1266
+ } else {
1267
+ result.push(config.id)
1268
+ }
1269
+ })
1270
+ return result
1271
+ },
1272
+ // 容器删除
1273
+ handleContainerDelete (id) {
1274
+ let index
1275
+ const row = lowcodeUtils.getRowConfigByComponentId(id, this.config)
1276
+ for (let i = 0; i < row.length; i++) {
1277
+ const item = row[i]
1278
+ if (item.id === id) {
1279
+ index = i
1280
+ break
1281
+ }
1282
+ }
1283
+ row.splice(index, 1)
1284
+ this.targetContainer = undefined
1285
+ // 如果删除后只剩一个容器,将该容器span设置为24
1286
+ if (row.length === 1) {
1287
+ row[0].span = 24
1288
+ }
1289
+ this.refreshOrganization()
1290
+ },
1291
+ // 事件编辑器点击完成
1292
+ handleEventEditorOk () {
1293
+ let emitTypeKey = this.eventEditorContent.emitType
1294
+ // 是否是自定义事件触发
1295
+ if (this.eventEditorContent.customEmitType) {
1296
+ emitTypeKey = this.eventEditorContent.customEmitType
1297
+ }
1298
+ // 如果当前是回显事件
1299
+ if (this.eventEditorCurrent) {
1300
+ const targetConfig = lowcodeUtils.getComponentConfig(this.editorPropertiesConfig.id, this.config.page)
1301
+ targetConfig.onEvent[this.eventEditorCurrent.type][this.eventEditorCurrent.index] = { ...this.eventEditorContent }
1302
+ } else {
1303
+ // 当前是新增事件
1304
+ const target = lowcodeUtils.getComponentConfig(this.editorPropertiesConfig.id, this.config.page)
1305
+ // 如果没有onEvent属性则初始化
1306
+ if (!target.onEvent) {
1307
+ target.onEvent = {}
1308
+ }
1309
+ // 如果当前触发类型没有初始化,则初始化
1310
+ if (!target.onEvent[emitTypeKey]) {
1311
+ target.onEvent[emitTypeKey] = []
1312
+ }
1313
+ // 将缓存的事件属性赋值
1314
+ target.onEvent[emitTypeKey].push({
1315
+ ...this.eventEditorContent
1316
+ })
1317
+ }
1318
+ this.showEventEditor = false
1319
+ this.eventEditorContent = {}
1320
+ this.eventEditorCurrent = undefined
1321
+ },
1322
+ // 关闭事件编辑器弹框
1323
+ handleEventEditorCancel () {
1324
+ this.showEventEditor = false
1325
+ this.eventEditorContent = {}
1326
+ this.eventEditorCurrent = undefined
1327
+ },
1328
+ // 事件编辑器中,触发类型改变
1329
+ handleEventEditorTypeChange (type) {
1330
+ this.eventEditorContent.emitType = type
1331
+ this.$forceUpdate()
1332
+ },
1333
+ // 事件编辑器中,目标组件改变
1334
+ handleEventEditorTargetChange (target) {
1335
+ this.eventEditorContent.target = target
1336
+ this.$forceUpdate()
1337
+ },
1338
+ handleEventEditorLifeCycleChange (lifeCycleName) {
1339
+ this.eventEditorContent.lifeCycle = lifeCycleName
1340
+ },
1341
+ // 事件编辑器中,事件类型改变
1342
+ handleEventEditorEventTypeChange (type) {
1343
+ const componentsMap = this.$children[0]._provided.componentsMap
1344
+ this.eventEditorContent.eventType = type
1345
+ this.logicParamTransferDataSource = []
1346
+ // 如果事件为运行Logic将组件加入穿梭框
1347
+ if (type === 'runLogic') {
1348
+ const keys = Object.keys(componentsMap)
1349
+ keys.forEach(key => {
1350
+ const name = lowcodeUtils.getComponentNameById(key, this.config)
1351
+ this.logicParamTransferDataSource.push({
1352
+ key: key,
1353
+ title: name,
1354
+ })
1355
+ })
1356
+ this.eventEditorContent.logicParamTransfer = []
1357
+ }
1358
+ this.$forceUpdate()
1359
+ },
1360
+ // 事件编辑器中,目标组件执行事件类型改变
1361
+ handleEventEditorTargetEventTypeChange (type) {
1362
+ this.eventEditorContent.eventName = type
1363
+ this.$forceUpdate()
1364
+ },
1365
+ // 自定义JS方法弹框确认
1366
+ handleJSEventEditorOk () {
1367
+ this.showJSEventEditor = false
1368
+ },
1369
+ // 自定义JS方法弹框关闭
1370
+ handleJSEventEditorCancel () {
1371
+ this.showJSEventEditor = false
1372
+ },
1373
+ // 添加组件到容器中
1374
+ addComponentToContainer (type) {
1375
+ // 如果没有选中容器
1376
+ if (!this.targetContainer) {
1377
+ this.$message.error('请先选择目标容器!')
1378
+ this.targetContainer = undefined
1379
+ return
1380
+ }
1381
+ // 获取选中的容器
1382
+ const target = lowcodeUtils.getComponentConfig(this.targetContainer.id, this.config.page)
1383
+ // 将容器的类型和id改变
1384
+ target.type = type
1385
+ target.id = target.type + '_' + lowcodeUtils.nanoidWithoutSymbol(6)
1386
+ this.targetContainer = undefined
1387
+ this.refreshOrganization()
1388
+ },
1389
+ // 添加容器
1390
+ addContainer () {
1391
+ // 如果目标不是一个容器
1392
+ if (!this.targetContainer) {
1393
+ // 如果没有指定页面容器,则直接报错
1394
+ if (this.activeMainPage === undefined) {
1395
+ this.$message.error('未选中任何工作空间!')
1396
+ return
1397
+ }
1398
+ // 获取当前选中的页面容器
1399
+ let targetIndex = this.activeMainPage
1400
+ for (let i = 0; i < this.config.page.length; i++) {
1401
+ if (this.config.page[i].id === this.activeMainPage) {
1402
+ targetIndex = i
1403
+ break
1404
+ }
1405
+ }
1406
+ // 如果是page类型,添加两个容器。其他类型添加一个容器
1407
+ if (this.config.page[targetIndex].type === 'page') {
1408
+ // this.config.page[targetIndex].body.push([
1409
+ // {
1410
+ // type: 'container_page',
1411
+ // span: 12,
1412
+ // id: 'container_' + lowcodeUtils.nanoidWithoutSymbol(6),
1413
+ // page: [
1414
+ // {
1415
+ // id: 'container_page_' + lowcodeUtils.nanoidWithoutSymbol(6),
1416
+ // type: 'page',
1417
+ // body: [
1418
+ // [
1419
+ // {
1420
+ // type: 'container',
1421
+ // span: 24,
1422
+ // id: 'container_' + lowcodeUtils.nanoidWithoutSymbol(6)
1423
+ // }
1424
+ // ]
1425
+ // ]
1426
+ // }
1427
+ // ]
1428
+ // },
1429
+ // {
1430
+ // type: 'container_page',
1431
+ // span: 12,
1432
+ // id: 'container_' + lowcodeUtils.nanoidWithoutSymbol(6),
1433
+ // page: [
1434
+ // {
1435
+ // id: 'container_page_' + lowcodeUtils.nanoidWithoutSymbol(6),
1436
+ // type: 'page',
1437
+ // body: [
1438
+ // [
1439
+ // {
1440
+ // type: 'container',
1441
+ // span: 24,
1442
+ // id: 'container_' + lowcodeUtils.nanoidWithoutSymbol(6)
1443
+ // }
1444
+ // ]
1445
+ // ]
1446
+ // }
1447
+ // ]
1448
+ // }
1449
+ // ])
1450
+ this.config.page[targetIndex].body.push([
1451
+ {
1452
+ type: 'container',
1453
+ span: 12,
1454
+ id: 'container_' + lowcodeUtils.nanoidWithoutSymbol(6)
1455
+ },
1456
+ {
1457
+ type: 'container',
1458
+ span: 12,
1459
+ id: 'container_' + lowcodeUtils.nanoidWithoutSymbol(6)
1460
+ }
1461
+ ])
1462
+ } else {
1463
+ this.config.page[targetIndex].body.push([{
1464
+ type: 'container',
1465
+ span: 24,
1466
+ id: 'container_' + lowcodeUtils.nanoidWithoutSymbol(6)
1467
+ }])
1468
+ }
1469
+ } else {
1470
+ // 如果目标是容器
1471
+ const row = lowcodeUtils.getRowConfigByComponentId(this.targetContainer.id, this.config)
1472
+ const targetInRowIndex = lowcodeUtils.getComponentInRowIndex(this.targetContainer.id, this.config)
1473
+ const targetItem = lowcodeUtils.getComponentConfig(this.targetContainer.id, this.config)
1474
+ const maxWidth = targetItem.span
1475
+ // 确认是水平拆分还是垂直拆分
1476
+ this.$confirm({
1477
+ content: '是否为水平拆分',
1478
+ onOk: () => {
1479
+ // 将目标容器一分为二
1480
+ row.splice(targetInRowIndex, 1, {
1481
+ type: 'container',
1482
+ span: Math.floor(maxWidth / 2),
1483
+ id: 'container_' + lowcodeUtils.nanoidWithoutSymbol(6)
1484
+ }, {
1485
+ type: 'container',
1486
+ span: Math.ceil(maxWidth / 2),
1487
+ id: 'container_' + lowcodeUtils.nanoidWithoutSymbol(6)
1488
+ })
1489
+ this.targetContainer = undefined
1490
+ this.refreshOrganization()
1491
+ },
1492
+ onCancel: () => {
1493
+ targetItem.type = 'container_page'
1494
+ targetItem.page = [{
1495
+ id: 'container_page_' + lowcodeUtils.nanoidWithoutSymbol(6),
1496
+ type: 'page',
1497
+ body: [
1498
+ [{
1499
+ type: 'container',
1500
+ span: 24,
1501
+ id: 'container_' + lowcodeUtils.nanoidWithoutSymbol(6)
1502
+ }],
1503
+ [{
1504
+ type: 'container',
1505
+ span: 24,
1506
+ id: 'container_' + lowcodeUtils.nanoidWithoutSymbol(6)
1507
+ }]
1508
+ ]
1509
+ }]
1510
+ this.targetContainer = undefined
1511
+ this.refreshOrganization()
1512
+ }
1513
+ })
1514
+ }
1515
+ this.refreshOrganization()
1516
+ },
1517
+ // 获取所有已注册组件,用于添加至UI库
1518
+ getRegisteredComponents () {
1519
+ return Object.keys(registeredRender)
1520
+ },
1521
+ // 组件属性编辑
1522
+ editorPropertiesInputChange (event, key) {
1523
+ this.renderPreview = false
1524
+ this.renderModalPreview = false
1525
+ this.renderDrawPreview = false
1526
+ // 如果当前有定时器,清除该定时器,并设置新的定时器
1527
+ // 也就是说:每次操作间隔指定时间后才会触发更新
1528
+ // 如果在此期间又进行了操作,则重新开始计时
1529
+ if (this.inputTimeout) {
1530
+ clearTimeout(this.inputTimeout)
1531
+ }
1532
+ this.inputTimeout = setTimeout(() => {
1533
+ const target = lowcodeUtils.getComponentConfig(this.editorPropertiesConfig.id, this.config.page)
1534
+ lowcodeLog('组件属性修改', '触发更新', target.id, true, false)
1535
+ // 拿到组件注册的配置
1536
+ const editorConfig = lowcodeUtils.getEditorConfigById(this.editorPropertiesConfig.id, this.config.page)
1537
+ // 根据类型,将input框中的内容赋值
1538
+ if (editorConfig.properties[key].type === 'object') {
1539
+ target.props[key] = JSON.parse(event.target.value)
1540
+ } else if (editorConfig.properties[key].type === 'string') {
1541
+ target.props[key] = event.target.value
1542
+ } else if (editorConfig.properties[key].type === 'boolean') {
1543
+ const input = event.target.value.toLowerCase()
1544
+ target.props[key] = input === 'true' || input !== '0'
1545
+ }
1546
+ this.renderPreview = true
1547
+ this.renderModalPreview = true
1548
+ this.renderDrawPreview = true
1549
+ }, 1500)
1550
+ },
1551
+ // 切换预览模式
1552
+ previewModeActive () {
1553
+ // TODO 新标签页中预览
1554
+ // const params = {
1555
+ // config: this.config
1556
+ // }
1557
+ // const routeData = this.$router.resolve({
1558
+ // path: '/lowCodeReview',
1559
+ // query: params
1560
+ // })
1561
+ // window.open(routeData.location.path, '_blank')
1562
+ this.preview = true
1563
+ },
1564
+ // 切换编辑模式
1565
+ editModeActive () {
1566
+ this.preview = false
1567
+ },
1568
+ // 选中某个组件
1569
+ clickComponentInEditor (configItem) {
1570
+ // 同步选中架构
1571
+ if (configItem.type === 'container_page') {
1572
+ this.selectTreeNode = 'container_page_' + configItem.page[0].id
1573
+ } else {
1574
+ this.selectTreeNode = configItem.id
1575
+ }
1576
+ this.editorPropertiesConfig = {}
1577
+ // 如果选中的是容器
1578
+ if (configItem.type === 'container') {
1579
+ // 如果已经选中,则反选,selected属性用于改变容器样式
1580
+ if (configItem.selected) {
1581
+ configItem.selected = false
1582
+ this.targetContainer = undefined
1583
+ } else {
1584
+ // 将所有已选中组件取消选择
1585
+ lowcodeUtils.unCheckAll(this.config)
1586
+ // 将目标设置为选定
1587
+ configItem.selected = true
1588
+ this.targetContainer = configItem
1589
+ }
1590
+ return
1591
+ }
1592
+ // 如果选中的是容器页面
1593
+ if (configItem.type === 'container_page') {
1594
+ this.editorPropertiesConfig = configItem
1595
+ this.editorPropertiesConfig.props = {}
1596
+ return
1597
+ }
1598
+ // 如果是组件对象
1599
+ // 拿注册的配置
1600
+ const configInJson = lowcodeUtils.getEditorConfigByType(configItem.type)
1601
+ if (configInJson) {
1602
+ this.editorPropertiesConfig = configItem
1603
+ // 为编辑器变量初始化
1604
+ if (configInJson.properties) {
1605
+ if (!this.editorPropertiesConfig.props) {
1606
+ this.editorPropertiesConfig.props = {}
1607
+ }
1608
+ const editableKeys = Object.keys(configInJson.properties)
1609
+ editableKeys.forEach(editableKey => {
1610
+ // 如果该值并不存在,则初始化
1611
+ if (!this.editorPropertiesConfig.props[editableKey]) {
1612
+ this.editorPropertiesConfig.props[editableKey] = ''
1613
+ } else {
1614
+ if (typeof this.editorPropertiesConfig.props[editableKey] === 'object') {
1615
+ this.editorPropertiesConfig.props[editableKey] = JSON.stringify(this.editorPropertiesConfig.props[editableKey])
1616
+ }
1617
+ }
1618
+ })
1619
+ }
1620
+ // 为编辑器事件初始化
1621
+ if (configInJson.selfEvent) {
1622
+ if (!this.editorPropertiesConfig.selfEvent) {
1623
+ this.editorPropertiesConfig.selfEvent = []
1624
+ configInJson.selfEvent.forEach(everyEvent => {
1625
+ this.editorPropertiesConfig.selfEvent.push(everyEvent)
1626
+ })
1627
+ }
1628
+ }
1629
+ } else {
1630
+ this.editorPropertiesConfig = 'unregistered'
1631
+ }
1632
+ },
1633
+ twink (id) {
1634
+ const allRefs = Object.keys(this.$refs)
1635
+ allRefs.forEach(ref => {
1636
+ this.$refs[ref].twink(id)
1637
+ })
1638
+ },
1639
+ // 点击测试按钮
1640
+ test () {
1641
+ // 输出当前配置,和组件注册Map
1642
+ console.warn('config', this.config)
1643
+ console.warn('map', this.$children[0]._provided.componentsMap)
1644
+ },
1645
+ // 点击导出按钮
1646
+ exportConfig () {
1647
+ console.warn('导出', this.config)
1648
+ this.$emit('exportConfig', this.config)
1649
+ }
1650
+ },
1651
+ mounted () {
1652
+ // 将mixin中已经实现的通用响应方法添加
1653
+ this.supportedEventType = [...lowcodeComponentMixin.supportedEventType]
1654
+ // 深拷贝外侧传来的配置
1655
+ this.config = JSON.parse(JSON.stringify(this.originalConfig))
1656
+ this.config = {
1657
+ page: [
1658
+ {
1659
+ id: 'page_KBjw2i',
1660
+ type: 'page',
1661
+ title: '111',
1662
+ body: [
1663
+ [
1664
+ {
1665
+ type: 'XFormTable',
1666
+ span: 12,
1667
+ id: 'XFormTable_BV6Nwk',
1668
+ selected: false,
1669
+ props: {
1670
+ queryParamsName: '',
1671
+ serviceName: ''
1672
+ },
1673
+ selfEvent: [
1674
+ 'action'
1675
+ ]
1676
+ },
1677
+ {
1678
+ type: 'XAddNativeForm',
1679
+ span: 12,
1680
+ id: 'XAddNativeForm_ekihTp',
1681
+ selected: false,
1682
+ props: {
1683
+ configNameForLowCode: '',
1684
+ systemNameForLowCode: ''
1685
+ },
1686
+ selfEvent: [
1687
+ 'onSubmit'
1688
+ ]
1689
+ }
1690
+ ],
1691
+ [
1692
+ {
1693
+ type: 'XTreeOne',
1694
+ span: 12,
1695
+ id: 'XTreeOne_szu7Al',
1696
+ selected: false
1697
+ },
1698
+ {
1699
+ type: 'XDescriptions',
1700
+ span: 12,
1701
+ id: 'XDescriptions_DTkbEg',
1702
+ selected: false,
1703
+ props: {
1704
+ title: '111',
1705
+ content: {
1706
+ c_f_user_phone: '2323',
1707
+ c_f_total_fee: 33356,
1708
+ c_f_address: '22',
1709
+ c_f_meterlen: 2,
1710
+ c_f_bank_card_number: '23',
1711
+ c_f_create_user: '超级管理员',
1712
+ c_f_customer: '23',
1713
+ c_f_balance: 33356,
1714
+ c_f_create_date: '2024-06-23 21:31:24',
1715
+ c_f_operator_date: '2024-06-23 21:31:24',
1716
+ c_f_total_times: 2,
1717
+ c_f_user_name: '23',
1718
+ c_f_comments: '323',
1719
+ c_id: 39,
1720
+ c_f_operatorid: '15',
1721
+ c_f_operator: '超级管理员',
1722
+ c_f_orgid: '9'
1723
+ },
1724
+ configName: 'Unit_Desc_Config',
1725
+ serviceName: 'af-revenue',
1726
+ getRealData: true
1727
+ },
1728
+ selfEvent: []
1729
+ }
1730
+ ]
1731
+ ]
1732
+ },
1733
+ {
1734
+ id: 'page_FgItf6',
1735
+ type: 'page',
1736
+ title: '22',
1737
+ body: [
1738
+ [
1739
+ {
1740
+ type: 'container',
1741
+ span: 4,
1742
+ id: 'container_ir2gR2',
1743
+ selected: false
1744
+ },
1745
+ {
1746
+ type: 'container_page',
1747
+ span: 10,
1748
+ id: 'container_xIRHGg',
1749
+ selected: true,
1750
+ page: [
1751
+ {
1752
+ id: 'container_page_IgYw9u',
1753
+ type: 'page',
1754
+ body: [
1755
+ [
1756
+ {
1757
+ type: 'container',
1758
+ span: 24,
1759
+ id: 'container_tqVFCL'
1760
+ }
1761
+ ],
1762
+ [
1763
+ {
1764
+ type: 'container',
1765
+ span: 24,
1766
+ id: 'container_i8VXCZ'
1767
+ }
1768
+ ]
1769
+ ]
1770
+ }
1771
+ ]
1772
+ },
1773
+ {
1774
+ type: 'container',
1775
+ span: 10,
1776
+ id: 'container_PT9n3Q',
1777
+ selected: false
1778
+ }
1779
+ ],
1780
+ [
1781
+ {
1782
+ type: 'container',
1783
+ span: 18,
1784
+ id: 'container_q04vQr',
1785
+ selected: false
1786
+ },
1787
+ {
1788
+ type: 'container',
1789
+ span: 6,
1790
+ id: 'container_MKwNvz',
1791
+ selected: false
1792
+ }
1793
+ ]
1794
+ ]
1795
+ }
1796
+ ]
1797
+ }
1798
+ this.refreshOrganization()
1799
+ }
1800
+ }
1801
+ </script>
1802
+
1803
+ <style scoped lang="less">
1804
+ .ui-item:hover {
1805
+ cursor: pointer;
1806
+ }
1807
+
1808
+ .ui-item{
1809
+ width: 100%;
1810
+ height:10%;
1811
+ text-align: center;
1812
+ overflow-wrap: break-word;
1813
+ padding: 7%
1814
+ }
1815
+
1816
+ .singleEvent {
1817
+ border: black dashed 1px;
1818
+ padding: 10%;
1819
+ }
1820
+
1821
+ .edit_icon:hover {
1822
+ cursor: pointer;
1823
+ }
1824
+ </style>