vue2-client 1.9.39 → 1.9.41

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 (324) hide show
  1. package/.env +19 -19
  2. package/.env.gaslink +19 -19
  3. package/.env.his +19 -19
  4. package/.env.revenue +19 -19
  5. package/.eslintrc.js +90 -90
  6. package/CHANGELOG.md +824 -824
  7. package/Components.md +60 -60
  8. package/babel.config.js +21 -21
  9. package/docs/Logic/345/207/275/346/225/260/344/275/277/347/224/250/347/233/270/345/205/263.md +45 -45
  10. package/docs/LowCode/lowcode.md +155 -155
  11. package/docs/LowCode/lowcodeForDeveloper.md +230 -230
  12. package/docs/index.md +30 -30
  13. package/docs//345/207/275/346/225/260/344/275/277/347/224/250/347/233/270/345/205/263.md +136 -136
  14. package/index.js +31 -31
  15. package/jest-transform-stub.js +8 -8
  16. package/jest.config.js +21 -21
  17. package/jest.setup.js +7 -7
  18. package/package.json +102 -102
  19. package/public/his/editor/editor.html +51 -51
  20. package/public/his/editor/mock/bind_data.html +779 -779
  21. package/public/his/editor/mock/data_table.html +40 -40
  22. package/public/his/editor/mock/sign.html +75 -75
  23. package/public/his/editor/vender/JsBarcode.all.js +3669 -3669
  24. package/public/his/editor/vender/date97/My97DatePicker.htm +65 -65
  25. package/public/his/editor/vender/date97/WdatePicker.js +677 -677
  26. package/public/his/editor/vender/date97/calendar.js +4 -4
  27. package/public/his/editor/vender/date97/lang/en.js +13 -13
  28. package/public/his/editor/vender/date97/lang/zh-cn.js +13 -13
  29. package/public/his/editor/vender/date97/lang/zh-tw.js +13 -13
  30. package/public/his/editor/vender/date97/skin/WdatePicker.css +10 -10
  31. package/public/his/editor/vender/date97/skin/default/datepicker.css +328 -328
  32. package/public/his/editor/vender/date97/skin/ext/datepicker.css +308 -308
  33. package/public/his/editor/vender/date97/skin/whyGreen/datepicker.css +255 -255
  34. package/public/his/editor/vender/diff.js +1627 -1627
  35. package/public/his/editor/vender/editor.js +1 -1
  36. package/public/his/editor/vender/fabric.js +31187 -31187
  37. package/public/his/editor/vender/jquery/jquery.base64.js +190 -190
  38. package/public/his/editor/vender/jquery/jquery.js +10872 -10872
  39. package/public/his/editor/vender/jquery/jquery.print.js +255 -255
  40. package/public/his/editor/vender/jquery/zTreeStyle/zTreeStyle.css +96 -96
  41. package/public/his/editor/vender/mui/mui.min.css +4 -4
  42. package/public/his/editor/vender/mui/mui.min.js +5 -5
  43. package/public/his/editor/vender/mui/mui.picker.min.css +6 -6
  44. package/public/his/editor/vender/mui/mui.picker.min.js +6 -6
  45. package/public/his/editor/vender/qrcode.js +7 -7
  46. package/public/his/editor/vender/requirejs/require.js +2145 -2145
  47. package/public/his/editor/vender/signature/jSignature.CompressorSVG.js +518 -518
  48. package/public/his/editor/vender/signature/jSignature.UndoButton.js +164 -164
  49. package/public/his/editor/vender/signature/jSignature.js +1486 -1486
  50. package/public/his/editor/vender/validator.js +5094 -5094
  51. package/public/his/editor/vender/weui/weui.css +5659 -5659
  52. package/public/his/editor/vender/weui/weui.min.css +4 -4
  53. package/public/his/editor/vender/weui/weui.min.js +11 -11
  54. package/public/index.html +27 -27
  55. package/src/App.vue +192 -192
  56. package/src/ReportView.js +19 -19
  57. package/src/assets/img/querySlotDemo.svg +15 -15
  58. package/src/assets/svg/badtwo.svg +1 -1
  59. package/src/assets/svg/goodtwo.svg +1 -1
  60. package/src/base-client/components/common/AMisRender/index.js +3 -3
  61. package/src/base-client/components/common/AMisRender/index.vue +263 -263
  62. package/src/base-client/components/common/AddressSearchCombobox/AddressSearchCombobox.vue +470 -470
  63. package/src/base-client/components/common/AddressSearchCombobox/IcMapIcon.vue +16 -16
  64. package/src/base-client/components/common/AddressSearchCombobox/demo.vue +36 -36
  65. package/src/base-client/components/common/AddressSearchCombobox/ic_map.svg +6 -6
  66. package/src/base-client/components/common/AmapMarker/AmapPointRendering.vue +120 -120
  67. package/src/base-client/components/common/CitySelect/CitySelect.vue +342 -342
  68. package/src/base-client/components/common/CitySelect/index.js +3 -3
  69. package/src/base-client/components/common/CitySelect/index.md +109 -109
  70. package/src/base-client/components/common/CreateQuery/CreateQuery.vue +669 -669
  71. package/src/base-client/components/common/CreateQuery/CreateQueryItem.vue +1014 -1014
  72. package/src/base-client/components/common/CreateQuery/index.js +3 -3
  73. package/src/base-client/components/common/CreateQuery/index.md +42 -42
  74. package/src/base-client/components/common/CreateSimpleFormQuery/CreateSimpleFormQuery.vue +452 -452
  75. package/src/base-client/components/common/CreateSimpleFormQuery/CreateSimpleFormQueryItem.vue +511 -511
  76. package/src/base-client/components/common/CreateSimpleFormQuery/index.js +3 -3
  77. package/src/base-client/components/common/CreateSimpleFormQuery/index.md +42 -42
  78. package/src/base-client/components/common/FormGroupEdit/FormGroupEdit.vue +149 -149
  79. package/src/base-client/components/common/FormGroupEdit/index.js +3 -3
  80. package/src/base-client/components/common/FormGroupEdit/index.md +43 -43
  81. package/src/base-client/components/common/FormGroupQuery/FormGroupQuery.vue +166 -166
  82. package/src/base-client/components/common/FormGroupQuery/index.js +3 -3
  83. package/src/base-client/components/common/FormGroupQuery/index.md +43 -43
  84. package/src/base-client/components/common/JSONToTree/jsontotree.vue +271 -271
  85. package/src/base-client/components/common/LowCodeComponent/LowCodeEditorModal.vue +108 -108
  86. package/src/base-client/components/common/LowCodeComponent/LowCodeEditorPanel.vue +413 -413
  87. package/src/base-client/components/common/LowCodeComponent/LowCodePageOrganization.vue +502 -502
  88. package/src/base-client/components/common/LowCodeComponent/LowCodeRender.vue +728 -728
  89. package/src/base-client/components/common/LowCodeComponent/LowCodeRenderEnter.vue +29 -29
  90. package/src/base-client/components/common/LowCodeComponent/LowCodeUIStore.vue +219 -219
  91. package/src/base-client/components/common/LowCodeComponent/modal/lowCodeAddPageModal.vue +117 -117
  92. package/src/base-client/components/common/LowCodeComponent/modal/lowCodeCustomJSModal.vue +80 -80
  93. package/src/base-client/components/common/LowCodeComponent/modal/lowCodeEventEditorModal.vue +398 -398
  94. package/src/base-client/components/common/LowCodeComponent/modal/lowCodeLifeCycleModal.vue +65 -65
  95. package/src/base-client/components/common/LowCodeComponent/modal/lowCodeLogicCallbackModal.vue +64 -64
  96. package/src/base-client/components/common/LowCodeComponent/modal/lowCodeLogicParamModal.vue +73 -73
  97. package/src/base-client/components/common/LowCodeComponent/modal/lowCodeRunFunctionParamModal.vue +76 -76
  98. package/src/base-client/components/common/PersonSetting/PersonSetting.vue +208 -208
  99. package/src/base-client/components/common/PersonSetting/index.js +3 -3
  100. package/src/base-client/components/common/Tree/Tree.vue +149 -149
  101. package/src/base-client/components/common/Tree/index.js +2 -2
  102. package/src/base-client/components/common/Upload/Upload.vue +239 -239
  103. package/src/base-client/components/common/Upload/index.js +3 -3
  104. package/src/base-client/components/common/XAddForm/XAddForm.vue +105 -105
  105. package/src/base-client/components/common/XAddNativeForm/XAddNativeForm.vue +804 -804
  106. package/src/base-client/components/common/XAddNativeForm/demo.vue +29 -29
  107. package/src/base-client/components/common/XAddNativeForm/index.md +146 -146
  108. package/src/base-client/components/common/XAddNativeFormOA/XAddNativeFormOA.vue +303 -303
  109. package/src/base-client/components/common/XAddNativeFormOA/index.js +3 -3
  110. package/src/base-client/components/common/XAddNativeFormOA/index.md +146 -146
  111. package/src/base-client/components/common/XAddReport/XAddReport.vue +204 -204
  112. package/src/base-client/components/common/XAddReport/index.js +3 -3
  113. package/src/base-client/components/common/XAddReport/index.md +56 -56
  114. package/src/base-client/components/common/XBadge/XBadge.vue +86 -86
  115. package/src/base-client/components/common/XCard/XCard.vue +64 -64
  116. package/src/base-client/components/common/XDataCard/XDataCard.vue +364 -364
  117. package/src/base-client/components/common/XDataCard/index.js +3 -3
  118. package/src/base-client/components/common/XDataCard/index.md +1 -1
  119. package/src/base-client/components/common/XDataDrawer/XDataDrawer.vue +180 -180
  120. package/src/base-client/components/common/XDataDrawer/index.js +3 -3
  121. package/src/base-client/components/common/XDataDrawer/index.md +41 -41
  122. package/src/base-client/components/common/XDescriptions/XDescriptions.vue +169 -169
  123. package/src/base-client/components/common/XDescriptions/XDescriptionsGroup.vue +304 -304
  124. package/src/base-client/components/common/XDescriptions/demo.vue +50 -50
  125. package/src/base-client/components/common/XDescriptions/index.js +3 -3
  126. package/src/base-client/components/common/XDescriptions/index.md +83 -83
  127. package/src/base-client/components/common/XDetailsView/XDetailsView.vue +238 -238
  128. package/src/base-client/components/common/XDetailsView/index.js +3 -3
  129. package/src/base-client/components/common/XForm/XForm.vue +316 -316
  130. package/src/base-client/components/common/XForm/XFormItem.vue +1149 -1156
  131. package/src/base-client/components/common/XForm/XTreeSelect.vue +208 -207
  132. package/src/base-client/components/common/XForm/index.md +178 -178
  133. package/src/base-client/components/common/XFormCol/XFormCol.vue +36 -36
  134. package/src/base-client/components/common/XFormGroup/XFormGroup.vue +254 -254
  135. package/src/base-client/components/common/XFormGroup/demo.vue +40 -40
  136. package/src/base-client/components/common/XFormGroup/index.js +3 -3
  137. package/src/base-client/components/common/XFormGroup/index.md +38 -38
  138. package/src/base-client/components/common/XFormGroupDetails/XFormGroupDetails.vue +72 -72
  139. package/src/base-client/components/common/XFormGroupDetails/index.js +3 -3
  140. package/src/base-client/components/common/XFormTable/XFormTable.vue +643 -646
  141. package/src/base-client/components/common/XFormTable/demo.vue +70 -70
  142. package/src/base-client/components/common/XFormTable/index.md +98 -98
  143. package/src/base-client/components/common/XImportExcel/XImportExcel.vue +162 -162
  144. package/src/base-client/components/common/XLicensePlate/XLicensePlate.vue +193 -193
  145. package/src/base-client/components/common/XLicensePlate/XLicensePlateDemo.vue +48 -48
  146. package/src/base-client/components/common/XReport/XReport.vue +892 -892
  147. package/src/base-client/components/common/XReport/XReportDemo.vue +304 -304
  148. package/src/base-client/components/common/XReport/XReportDesign.vue +463 -463
  149. package/src/base-client/components/common/XReport/XReportJsonRender.vue +381 -381
  150. package/src/base-client/components/common/XReport/XReportTrGroup.vue +808 -808
  151. package/src/base-client/components/common/XReport/index.md +44 -44
  152. package/src/base-client/components/common/XReport/print.js +186 -186
  153. package/src/base-client/components/common/XReportGrid/XReport.vue +937 -937
  154. package/src/base-client/components/common/XReportGrid/XReportDemo.vue +42 -42
  155. package/src/base-client/components/common/XReportGrid/XReportDesign.vue +556 -556
  156. package/src/base-client/components/common/XReportGrid/XReportJsonRender.vue +381 -381
  157. package/src/base-client/components/common/XReportGrid/XReportTrGroup.vue +972 -972
  158. package/src/base-client/components/common/XReportGrid/index.js +3 -3
  159. package/src/base-client/components/common/XReportGrid/index.md +44 -44
  160. package/src/base-client/components/common/XReportGrid/print.js +186 -186
  161. package/src/base-client/components/common/XReportSlot/XReportSlot.vue +110 -110
  162. package/src/base-client/components/common/XReportSlot/index.js +3 -3
  163. package/src/base-client/components/common/XReportSlot/index.md +48 -48
  164. package/src/base-client/components/common/XSimpleDescriptions/XSimpleDescriptions.vue +166 -166
  165. package/src/base-client/components/common/XSimpleDescriptions/index.js +3 -3
  166. package/src/base-client/components/common/XSimpleDescriptions/index.md +7 -7
  167. package/src/base-client/components/common/XStepView/XStepView.vue +252 -252
  168. package/src/base-client/components/common/XStepView/index.js +3 -3
  169. package/src/base-client/components/common/XStepView/index.md +31 -31
  170. package/src/base-client/components/common/XTab/XTab.vue +179 -179
  171. package/src/base-client/components/common/XTab/XTabDemo.vue +22 -22
  172. package/src/base-client/components/common/XTab/index.js +3 -3
  173. package/src/base-client/components/common/XTable/XTable.vue +1132 -1133
  174. package/src/base-client/components/common/XTable/index.md +255 -255
  175. package/src/base-client/components/common/XTree/XTree.vue +423 -423
  176. package/src/base-client/components/common/XTree/XTreePro.vue +434 -434
  177. package/src/base-client/components/common/XTree/index.js +3 -3
  178. package/src/base-client/components/common/XTree/index.md +36 -36
  179. package/src/base-client/components/common/XTreeOne/XTreeOne.vue +113 -113
  180. package/src/base-client/components/common/XTreeOne/XTreeOnePro.vue +128 -128
  181. package/src/base-client/components/common/richTextModal/index.vue +56 -56
  182. package/src/base-client/components/common/richTextModal/richDemo.vue +48 -48
  183. package/src/base-client/components/his/XHisEditor/XHisEditor.vue +203 -203
  184. package/src/base-client/components/his/XHisEditor/index.js +3 -3
  185. package/src/base-client/components/index.js +51 -51
  186. package/src/base-client/components/layout/XPageView/RenderRow.vue +63 -63
  187. package/src/base-client/components/layout/XPageView/XErrorView.vue +11 -11
  188. package/src/base-client/components/layout/XPageView/XPageView.vue +155 -155
  189. package/src/base-client/components/layout/XPageView/index.js +3 -3
  190. package/src/base-client/components/layout/XPageView/index.md +38 -38
  191. package/src/base-client/components/layout/XTreeView/XTreeView.vue +130 -130
  192. package/src/base-client/components/layout/XTreeView/index.js +3 -3
  193. package/src/base-client/components/layout/XTreeView/index.md +46 -46
  194. package/src/base-client/components/system/DictionaryDetailsView/DictionaryDetailsView.vue +232 -232
  195. package/src/base-client/components/system/QueryParamsDetailsView/QueryParamsDetailsView.vue +281 -281
  196. package/src/base-client/plugins/AppData.js +121 -121
  197. package/src/base-client/plugins/Config.js +19 -19
  198. package/src/base-client/plugins/GetLoginInfoService.js +183 -183
  199. package/src/base-client/plugins/tabs-page-plugin.js +39 -39
  200. package/src/bootstrap.js +39 -39
  201. package/src/components/CodeMirror/inedx.vue +118 -118
  202. package/src/components/CodeMirror/setting.js +40 -40
  203. package/src/components/FilePreview/FilePreview.vue +166 -166
  204. package/src/components/NumberInfo/NumberInfo.vue +54 -54
  205. package/src/components/STable/index.js +380 -380
  206. package/src/components/checkbox/ColorCheckbox.vue +157 -157
  207. package/src/components/checkbox/ImgCheckbox.vue +163 -163
  208. package/src/components/exception/ExceptionPage.vue +70 -70
  209. package/src/components/menu/SideMenu.vue +75 -75
  210. package/src/components/menu/menu.js +273 -273
  211. package/src/components/tool/AStepItem.vue +60 -60
  212. package/src/config/CreateQueryConfig.js +322 -322
  213. package/src/config/default/antd.config.js +89 -89
  214. package/src/config/default/setting.config.js +55 -55
  215. package/src/font-style/font.css +4 -4
  216. package/src/layouts/CommonLayout.vue +56 -56
  217. package/src/layouts/GridView.vue +45 -45
  218. package/src/layouts/PageLayout.vue +151 -151
  219. package/src/layouts/SinglePageView.vue +136 -136
  220. package/src/layouts/header/AdminHeader.vue +132 -132
  221. package/src/layouts/header/HeaderNotice.vue +177 -177
  222. package/src/layouts/tabs/TabsHead.vue +189 -189
  223. package/src/layouts/tabs/TabsView.vue +389 -389
  224. package/src/lib.js +1 -1
  225. package/src/main.js +30 -30
  226. package/src/mock/extend/index.js +84 -84
  227. package/src/mock/goods/index.js +108 -108
  228. package/src/pages/AMisDemo/AMisDemo.vue +325 -325
  229. package/src/pages/AMisDemo/AMisDemo2.vue +74 -74
  230. package/src/pages/DefaultExample/index.vue +77 -77
  231. package/src/pages/DynamicStatistics/ChartSelector.vue +331 -331
  232. package/src/pages/DynamicStatistics/DataTabs.vue +83 -83
  233. package/src/pages/DynamicStatistics/DynamicTable.vue +128 -128
  234. package/src/pages/DynamicStatistics/EvaluationArea.vue +69 -69
  235. package/src/pages/DynamicStatistics/QuestionHistoryAndFavorites.vue +591 -591
  236. package/src/pages/DynamicStatistics/SearchBar.vue +192 -192
  237. package/src/pages/DynamicStatistics/index.vue +282 -282
  238. package/src/pages/Example/childIndex.vue +15 -15
  239. package/src/pages/Example/index.vue +30 -30
  240. package/src/pages/NewDynamicStatistics/ChartSelector.vue +331 -331
  241. package/src/pages/NewDynamicStatistics/DataTabs.vue +122 -122
  242. package/src/pages/NewDynamicStatistics/DynamicTable.vue +128 -128
  243. package/src/pages/NewDynamicStatistics/EvaluationArea.vue +69 -69
  244. package/src/pages/NewDynamicStatistics/FavoriteList.vue +51 -51
  245. package/src/pages/NewDynamicStatistics/QuestionHistoryAndFavorites.vue +289 -289
  246. package/src/pages/NewDynamicStatistics/SearchBar.vue +193 -193
  247. package/src/pages/NewDynamicStatistics/index.vue +258 -258
  248. package/src/pages/ReportGrid/index.vue +76 -76
  249. package/src/pages/ServiceReview/index.vue +284 -284
  250. package/src/pages/SubExample/index.vue +26 -26
  251. package/src/pages/WorkflowDetail/WorkFlowDemo.vue +32 -32
  252. package/src/pages/WorkflowDetail/WorkflowDetail.vue +230 -230
  253. package/src/pages/WorkflowDetail/WorkflowPageDetail/LeaveMessage.vue +131 -131
  254. package/src/pages/WorkflowDetail/WorkflowPageDetail/TrimTextTail.vue +23 -23
  255. package/src/pages/WorkflowDetail/WorkflowPageDetail/WorkFlowBaseInformation.vue +302 -302
  256. package/src/pages/WorkflowDetail/WorkflowPageDetail/WorkFlowBaseInformationDetails.vue +276 -276
  257. package/src/pages/WorkflowDetail/WorkflowPageDetail/WorkFlowHandle.vue +864 -864
  258. package/src/pages/WorkflowDetail/WorkflowPageDetail/WorkFlowHandleReso.vue +997 -997
  259. package/src/pages/WorkflowDetail/WorkflowPageDetail/WorkFlowTimeline.vue +222 -222
  260. package/src/pages/WorkflowDetail/WorkflowPageDetail/WorkOrderParentDetails.vue +233 -233
  261. package/src/pages/WorkflowDetail/WorkflowPageDetail/WorkflowDetailResso.vue +261 -261
  262. package/src/pages/WorkflowDetail/WorkflowPageDetail/WorkflowListResolution.vue +248 -248
  263. package/src/pages/WorkflowDetail/WorkflowPageDetail/WorkflowLog.vue +73 -73
  264. package/src/pages/XPageViewExample/index.vue +38 -38
  265. package/src/pages/XReportView/index.vue +64 -64
  266. package/src/pages/XTreeOneProExample/index.vue +67 -67
  267. package/src/pages/login/Login.vue +378 -378
  268. package/src/pages/login/LoginV3.vue +389 -389
  269. package/src/pages/lowCode/lowCodeEditor.vue +1219 -1219
  270. package/src/pages/lowCode/lowCodeRenderPage.vue +43 -43
  271. package/src/pages/resourceManage/orgListManage.vue +98 -98
  272. package/src/pages/system/dictionary/index.vue +44 -44
  273. package/src/pages/system/monitor/loginInfor/index.vue +37 -37
  274. package/src/pages/system/monitor/operLog/index.vue +37 -37
  275. package/src/pages/system/settings/modifyPassword.vue +117 -117
  276. package/src/pages/system/ticket/index.vue +480 -480
  277. package/src/pages/system/ticket/submitTicketSuccess.vue +484 -484
  278. package/src/plugins/EventLogPlugin.js +33 -33
  279. package/src/plugins/FindParentsData.js +17 -17
  280. package/src/router/async/config.async.js +34 -34
  281. package/src/router/async/router.map.js +182 -182
  282. package/src/router/guards.js +264 -264
  283. package/src/router/index.js +27 -27
  284. package/src/router.js +19 -19
  285. package/src/services/api/TicketDetailsViewApi.js +46 -46
  286. package/src/services/api/cas.js +79 -79
  287. package/src/services/api/common.js +329 -329
  288. package/src/services/api/index.js +17 -17
  289. package/src/services/api/restTools.js +67 -67
  290. package/src/services/api/workFlow.js +63 -63
  291. package/src/services/apiService.js +15 -15
  292. package/src/services/user.js +90 -90
  293. package/src/services/v3Api.js +82 -82
  294. package/src/store/modules/account.js +115 -115
  295. package/src/store/modules/index.js +5 -5
  296. package/src/store/modules/lowCode.js +33 -33
  297. package/src/store/modules/setting.js +119 -119
  298. package/src/theme/default/style.less +58 -58
  299. package/src/theme/global.less +159 -159
  300. package/src/utils/authority-utils.js +85 -85
  301. package/src/utils/errorCode.js +6 -6
  302. package/src/utils/formatter.js +80 -80
  303. package/src/utils/htmlToPDF.js +108 -108
  304. package/src/utils/htmlToPDFApi.js +5 -5
  305. package/src/utils/indexedDB.js +263 -263
  306. package/src/utils/login.js +188 -188
  307. package/src/utils/lowcode/lowcodeComponentMixin.js +120 -120
  308. package/src/utils/lowcode/lowcodeLog.js +29 -29
  309. package/src/utils/lowcode/lowcodeUtils.js +373 -373
  310. package/src/utils/lowcode/registerComponentForEditor.js +1 -1
  311. package/src/utils/lowcode/registerComponentForRender.js +11 -11
  312. package/src/utils/map-utils.js +47 -47
  313. package/src/utils/microAppUtils.js +40 -40
  314. package/src/utils/reg.js +95 -95
  315. package/src/utils/request.js +362 -362
  316. package/src/utils/routerUtil.js +450 -450
  317. package/src/utils/runEvalFunction.js +14 -14
  318. package/src/utils/util.js +281 -281
  319. package/test/Amis.spec.js +163 -163
  320. package/test/Tree.spec.js +167 -167
  321. package/test/myDialog.spec.js +46 -46
  322. package/test/v3Api.test.js +1881 -1881
  323. package/vue.config.js +196 -196
  324. package//350/277/201/347/247/273/346/227/245/345/277/227.md +15 -15
@@ -1,972 +1,972 @@
1
- <template>
2
- <a-row :gutter="gutter">
3
- <!-- 预览页展示 -->
4
- <template v-if="display">
5
- <template v-if="!inputColumns">
6
- <a-col
7
- name="trGroup"
8
- v-for="(cell, cellIndex) in columns"
9
- v-if="!cell.dontShowRow"
10
- :key="cellIndex"
11
- :style="determineCellStyle(cell)"
12
- :span="cell.colSpan ? cell.colSpan * 2 : undefined">
13
- <!-- 插槽渲染 -->
14
- <template v-if="cell.type === 'slot'">
15
- <template
16
- v-if="['x-form-table','x-add-native-form','x-tree-pro', 'x-his-editor', 'x-tab', 'x-form-group', 'x-report'].includes(cell.slotType)">
17
- <component
18
- :is="getComponentName(cell.slotConfig, cell.serviceName, cell.slotType)"
19
- :key="cellIndex"
20
- :ref="`dynamicComponent_${ cell.slotRef || cellIndex}`"
21
- :serviceName="cell.serviceName"
22
- :serverName="cell.serviceName"
23
- v-on="getEventHandlers(cell)"
24
- @hook:mounted="(h)=>onComponentMounted(h,cell,cellIndex)"
25
- :queryParamsName="cell.slotConfig"
26
- :configName="cell.slotConfig"
27
- :countVisible="false"
28
- :env="env"
29
- />
30
- </template>
31
- </template>
32
- <!-- button 按钮渲染 -->
33
- <template v-else-if="cell.type === 'button'">
34
- <a-button v-on="getEventHandlers(cell)">
35
- {{ cell.buttonName }}
36
- </a-button>
37
- </template>
38
- <template v-else-if="cell.type === 'column'">
39
- <template v-if="cell.customFunction">
40
- {{ deserializeFunctionAndRun(cell.customFunction, configData[cell.dataIndex], config) }}
41
- </template>
42
- <template v-else>
43
- {{ cell.text }}
44
- </template>
45
- </template>
46
- <!-- 占位 -->
47
- <template v-else-if="cell.type === 'placeHolderColumn'">
48
- </template>
49
- <template v-else-if="cell.type === 'value'">
50
- <template v-if="cell.customFunction === undefined">
51
- {{ cell.value }}
52
- </template>
53
- <template v-else>
54
- {{ deserializeFunctionAndRun(cell.customFunction, cell.value, config) }}
55
- </template>
56
- </template>
57
- <template v-else-if="cell.type === 'input'">
58
- <template v-if="cell.customFunction === undefined">
59
- {{ getDeepObject(configData, cell.dataIndex) }}
60
- </template>
61
- <template v-else>
62
- {{ deserializeFunctionAndRun(cell.customFunction, configData[cell.dataIndex], config) }}
63
- </template>
64
- </template>
65
- <template v-else-if="cell.type === 'inputs'">
66
- <template v-if="cell.customFunction === undefined">
67
- {{ showSubRowValue(cell) }}
68
- </template>
69
- <template v-else>
70
- {{ deserializeFunctionAndRun(cell.customFunction, showSubRowValue(cell), config) }}
71
- </template>
72
- </template>
73
- <template v-else-if="cell.type === 'list'">
74
- <template v-if="listIndex === 0">
75
- <span style="font-weight: bold">{{ cell.listHead }}</span>
76
- </template>
77
- <template v-else-if="cell.listType === 'input'">
78
- {{ getDeepObject(configData, cell.dataIndex)[listIndex] }}
79
- </template>
80
- <template v-else-if="cell.listType === 'value'">
81
- {{ cell.content[listIndex] }}
82
- </template>
83
- <template v-else-if="cell.listType === 'variable'">
84
- {{ configData[cell.dataIndex][listIndex - 1][cell.listDataIndex] }}
85
- </template>
86
- </template>
87
- <template v-else-if="cell.type === 'images'">
88
- <template
89
- v-if="getDeepObject(configData.images, cell.dataIndex) === undefined || getDeepObject(configData.images, cell.dataIndex).length === 0">
90
- <template
91
- v-if="getDeepObject(configData, cell.dataIndex) === undefined || getDeepObject(configData, cell.dataIndex).length === 0">
92
- <span>无</span>
93
- </template>
94
- <template v-else>
95
- <template v-if="typeof getDeepObject(configData, cell.dataIndex) === 'object'">
96
- <div style="display: flex; align-items: end; justify-content: space-evenly; flex-wrap: wrap">
97
- <template v-for="(img,imgIndex) in getDeepObject(configData, cell.dataIndex)">
98
- <template v-if="showImgInCell">
99
- <div :key="imgIndex">
100
- <img :src="img.url" alt="图片"/>
101
- <p>{{ img.name }}</p>
102
- </div>
103
- </template>
104
- <template v-else>
105
- <span :key="imgIndex" style="margin-right: 5%">{{ img.name }}</span>
106
- </template>
107
- </template>
108
- </div>
109
- </template>
110
- <template v-else>
111
- <img :src="getDeepObject(configData, cell.dataIndex)" alt="图片"/>
112
- <p style="margin-right: 5%">{{ formatImgStr(getDeepObject(configData, cell.dataIndex))[0].name }}</p>
113
- </template>
114
- </template>
115
- </template>
116
- <span v-else v-for="(img,imgIndex) in getDeepObject(configData.images, cell.dataIndex)" :key="imgIndex" style="margin-right: 5%">{{ img.name }}</span>
117
- </template>
118
- </a-col>
119
- </template>
120
- <template v-else>
121
- <a-col
122
- v-for="(cell, cellIndex) in columns"
123
- :key="cellIndex"
124
- :class=" calcTDBorder(cell.noBoarder) "
125
- :span="cell.colSpan ? cell.colSpan * 2 : undefined"
126
- :style="determineCellStyle(cell)"
127
- :rowspan="cell.rowSpan ? cell.rowSpan : undefined">
128
- <template v-if="cell.type === 'column'">
129
- {{ cell.text }}
130
- </template>
131
- <template v-else-if="cell.type === 'value'">
132
- <template v-if="cell.customFunction === undefined">
133
- {{ cell.value }}
134
- </template>
135
- <template v-else>
136
- {{ deserializeFunctionAndRun(cell.customFunction, cell.value, config) }}
137
- </template>
138
- </template>
139
- <template v-else-if="cell.type === 'increment'">
140
- <template v-if="cell.customFunction === undefined">
141
- {{ getDeepObject(configData.arr[inputColumnsDefinitionIndex], cell.dataIndex) }}
142
- </template>
143
- <template v-else>
144
- {{
145
- deserializeFunctionAndRun(cell.customFunction, configData.arr[inputColumnsDefinitionIndex][cell.dataIndex], config)
146
- }}
147
- </template>
148
- </template>
149
- <template v-else-if="cell.type === 'input'">
150
- <template v-if="cell.customFunction === undefined">
151
- {{ getDeepObject(configData.arr[inputColumnsDefinitionIndex], cell.dataIndex) }}
152
- </template>
153
- <template v-else>
154
- {{
155
- deserializeFunctionAndRun(cell.customFunction, configData.arr[inputColumnsDefinitionIndex][cell.dataIndex], config)
156
- }}
157
- </template>
158
- </template>
159
- <template v-else-if="cell.type === 'inputs'">
160
- <template v-if="cell.customFunction === undefined">
161
- {{ getDeepObject(configData.arr[inputColumnsDefinitionIndex], cell.dataIndex) }}
162
- </template>
163
- <template v-else>
164
- {{
165
- deserializeFunctionAndRun(cell.customFunction, configData.arr[inputColumnsDefinitionIndex][cell.dataIndex], config)
166
- }}
167
- </template>
168
- </template>
169
- </a-col>
170
- </template>
171
- </template>
172
- <!-- 不是动态行 -->
173
- <template v-else-if="!inputColumns">
174
- <a-col
175
- v-for="(cell, cellIndex) in columns"
176
- :key="cellIndex"
177
- :class=" calcTDBorder(cell.noBoarder) "
178
- :span="cell.colSpan ? cell.colSpan * 2 : undefined"
179
- :style="determineCellStyle(cell)"
180
- :rowspan="cell.rowSpan ? cell.rowSpan : undefined">
181
- <template v-if="cell.type === 'column'">
182
- <template v-if="cell.customFunction">
183
- {{ deserializeFunctionAndRun(cell.customFunction, configData[cell.dataIndex], config) }}
184
- </template>
185
- <template v-else>
186
- {{ cell.text }}
187
- </template>
188
- </template>
189
- <template v-else-if="cell.type === 'placeHolderColumn'">
190
- <!-- 占位 -->
191
- </template>
192
- <template v-else-if="cell.type === 'value'">
193
- {{ cell.value }}
194
- </template>
195
- <template v-else-if="cell.type === 'curDateInput'">
196
- <a-button type="dashed" v-if="configData[cell.dataIndex]">
197
- {{ configData[cell.dataIndex] }}
198
- </a-button>
199
- <a-button
200
- v-if="!configData[cell.dataIndex]"
201
- type="primary"
202
- @click="getNowDate(cell.dataIndex)"
203
- >{{ cell.text || '确认' }}
204
- </a-button>
205
- </template>
206
- <template v-else-if="cell.type === 'input'">
207
- <template v-if="cell.inputReadOnly === true">
208
- <template v-if="cell.dataIndex.indexOf('@@@') !== -1">
209
- <a-input
210
- @change="handleInputDeepChange($event, cell.dataIndex)"
211
- v-model="config.tempData[cell.dataIndex]"
212
- :style="'width:' + (cell.inputWidth ? cell.inputWidth : '100') + '%'"
213
- :disabled="true"/>
214
- </template>
215
- <template v-else>
216
- <a-input
217
- v-model="configData[cell.dataIndex]"
218
- :style="'width:' + (cell.inputWidth ? cell.inputWidth : '100') + '%'"
219
- :disabled="true"/>
220
- </template>
221
- </template>
222
- <template v-else>
223
- <template v-if="cell.dataIndex.indexOf('@@@') !== -1">
224
- <a-input
225
- @change="handleInputDeepChange($event, cell.dataIndex)"
226
- v-model="config.tempData[cell.dataIndex]"
227
- :style="'width:' + (cell.inputWidth ? cell.inputWidth : '100') + '%'"/>
228
- </template>
229
- <template v-else>
230
- <a-input
231
- v-model="configData[cell.dataIndex]"
232
- :style="'width:' + (cell.inputWidth ? cell.inputWidth : '100') + '%'"/>
233
- </template>
234
- </template>
235
- </template>
236
- <template v-else-if="cell.type === 'inputs'">
237
- <template v-if="cell.inputReadOnly === true">
238
- <div class="inputsDiv">
239
- <div class="inputsDivItem" v-for="(num, index) of calcFormatInputNum(cell.format)" :key="index">
240
- <span class="inputsDivItemLabel">{{ displayFormatStartText(cell.format) }}</span>
241
- <template v-if="cell.dataIndex.indexOf('@@@') !== -1">
242
- <a-input
243
- @change="handleInputDeepChange($event, cell.dataIndex)"
244
- v-model="config.tempData[cell.dataIndex][index]"
245
- :style="'width:' + (cell.inputWidth ? cell.inputWidth : '100') + '%'"
246
- :disabled="true"/>
247
- </template>
248
- <template v-else>
249
- <a-input
250
- v-model="configData[cell.dataIndex][index]"
251
- :style="'width:' + (cell.inputWidth ? cell.inputWidth : '100') + '%'"
252
- :disabled="true"/>
253
- </template>
254
- <span class="inputsDivItemLabel">{{ displayFormatText(cell.format, index) }}</span>
255
- </div>
256
- </div>
257
- </template>
258
- <template v-else>
259
- <div class="inputsDiv">
260
- <div class="inputsDivItem" v-for="(num, index) of calcFormatInputNum(cell.format)" :key="index">
261
- <span class="inputsDivItemLabel">{{ displayFormatStartText(cell.format) }}</span>
262
- <template v-if="cell.dataIndex.indexOf('@@@') !== -1">
263
- <a-input
264
- @change="handleInputDeepChange($event, cell.dataIndex)"
265
- v-model="config.tempData[cell.dataIndex][index]"
266
- :style="'width:' + (cell.inputWidth ? cell.inputWidth : '100') + '%'"/>
267
- </template>
268
- <template v-else>
269
- <a-input
270
- v-model="configData[cell.dataIndex][index]"
271
- :style="'width:' + (cell.inputWidth ? cell.inputWidth : '100') + '%'"/>
272
- </template>
273
- <span class="inputsDivItemLabel">{{ displayFormatText(cell.format, index) }}</span>
274
- </div>
275
- </div>
276
- </template>
277
- </template>
278
- <template v-else-if="cell.type === 'list'">
279
- <template v-if="cell.listType === 'input'">
280
- <a-input
281
- v-model="configData[cell.dataIndex][listIndex]"
282
- :style="'width:' + (cell.inputWidth ? cell.inputWidth : '100') + '%'"/>
283
- </template>
284
- <template v-else-if="cell.listType === 'value'">
285
- {{ cell.content[listIndex] }}
286
- </template>
287
- </template>
288
- <template v-else-if="cell.type === 'images'">
289
- <div>
290
- <template v-if="configData.images[cell.dataIndex]?.length > 0">
291
- <upload
292
- :model="uploadParams"
293
- :img-prefix="imgPrefix"
294
- :service-name="serverName"
295
- :images="checkImg(cell.dataIndex, 'configData')"
296
- :outer-container-index="cell.dataIndex"
297
- @setFiles="(...args) => {setImages(args, 'configData')}"
298
- :upload-style="'simple'"
299
- />
300
- </template>
301
- <template v-else>
302
- <upload
303
- :model="uploadParams"
304
- :img-prefix="imgPrefix"
305
- :service-name="serverName"
306
- :images="checkImg(cell.dataIndex, 'config')"
307
- :outer-container-index="cell.dataIndex"
308
- @setFiles="(...args) => {setImages(args, 'config', cell.dataIndex)}"
309
- :upload-style="'simple'"
310
- />
311
- </template>
312
- </div>
313
- </template>
314
- </a-col>
315
- </template>
316
- <!-- 动态行插入按钮 -->
317
- <template v-else-if="inputColumnsButton">
318
- <a-col :span="maxColSpan" :class="calcTDBorder()">
319
- <a-button-group>
320
- <a-button @click="addData(columns[0].dataIndex, columns)">
321
- <a-icon type="plus"/>
322
- </a-button>
323
- <a-button @click="removeData(columns[0].dataIndex)">
324
- <a-icon type="minus"/>
325
- </a-button>
326
- </a-button-group>
327
- </a-col>
328
- </template>
329
- <!-- 其他行 -->
330
- <template v-else>
331
- <a-col
332
- v-for="(cell, cellIndex) in columns"
333
- :key="cellIndex"
334
- :class=" calcTDBorder(cell.noBoarder) "
335
- :span="cell.colSpan ? cell.colSpan * 2 : undefined"
336
- :style="determineCellStyle(cell)"
337
- :rowspan="cell.rowSpan ? cell.rowSpan : undefined">
338
- <template v-if="cell.type === 'column'">
339
- {{ cell.text }}
340
- </template>
341
- <template v-else-if="cell.type === 'value'">
342
- {{ cell.value }}
343
- </template>
344
- <template v-else-if="cell.type === 'curDateInput'">
345
- <a-button type="dashed" v-if="configData.arr[inputColumnsDefinitionIndex][cell.dataIndex]">
346
- {{ configData.arr[inputColumnsDefinitionIndex][cell.dataIndex] }}
347
- </a-button>
348
- <a-button
349
- v-if="!configData.arr[inputColumnsDefinitionIndex][cell.dataIndex]"
350
- type="primary"
351
- @click="getNowDate(inputColumnsDefinitionIndex,cell.dataIndex)"
352
- >{{ cell.text || '确认' }}
353
- </a-button>
354
- </template>
355
- <template v-else-if="cell.type === 'increment'">
356
- {{ configData.arr[inputColumnsDefinitionIndex][cell.dataIndex] }}
357
- </template>
358
- <template v-else-if="cell.type === 'input'">
359
- <template v-if="cell.inputReadOnly === true">
360
- <a-input
361
- v-model="configData.arr[inputColumnsDefinitionIndex][cell.dataIndex]"
362
- :style="'width:' + (cell.inputWidth ? cell.inputWidth : '100') + '%'"
363
- :disabled="true"/>
364
- </template>
365
- <template v-else>
366
- <a-input
367
- v-model="configData.arr[inputColumnsDefinitionIndex][cell.dataIndex]"
368
- :style="'width:' + (cell.inputWidth ? cell.inputWidth : '100') + '%'"/>
369
- </template>
370
- </template>
371
- <template v-else-if="cell.type === 'inputs'">
372
- <template v-if="cell.inputReadOnly === true">
373
- <a-input
374
- v-model="configData.arr[inputColumnsDefinitionIndex][cell.dataIndex]"
375
- :style="'width:' + (cell.inputWidth ? cell.inputWidth : '100') + '%'"
376
- :disabled="true"/>
377
- </template>
378
- <template v-else>
379
- <a-input
380
- v-model="configData.arr[inputColumnsDefinitionIndex][cell.dataIndex]"
381
- :style="'width:' + (cell.inputWidth ? cell.inputWidth : '100') + '%'"/>
382
- </template>
383
- </template>
384
- </a-col>
385
- </template>
386
- </a-row>
387
- </template>
388
-
389
- <script>
390
- import Upload from '@vue2-client/base-client/components/common/Upload'
391
- import { formatDate } from '@vue2-client/utils/util'
392
- import { nanoid } from 'nanoid'
393
- import { executeStrFunctionByContext } from '@vue2-client/utils/runEvalFunction'
394
- import { getConfigByName, runLogic } from '@vue2-client/services/api/common'
395
- import { getMicroData, getWindow, isMicroAppEnv, microDispatch } from '@vue2-client/utils/microAppUtils'
396
-
397
- export default {
398
- name: 'XReportTrGroup',
399
- components: {
400
- Upload,
401
- XFormTable: () => import('@vue2-client/base-client/components/common/XFormTable/XFormTable.vue'),
402
- XAddNativeForm: () => import('@vue2-client/base-client/components/common/XAddNativeForm/XAddNativeForm.vue'),
403
- XTreePro: () => import('@vue2-client/base-client/components/common/XTree/XTreePro.vue'),
404
- XHisEditor: () => import('@vue2-client/base-client/components/his/XHisEditor/XHisEditor.vue'),
405
- XTab: () => import('@vue2-client/base-client/components/common/XTab/XTab.vue'),
406
- XReport: () => import('@vue2-client/base-client/components/common/XReport/XReport.vue')
407
- },
408
- props: {
409
- // 每一行的配置
410
- columns: {
411
- type: Array,
412
- required: true
413
- },
414
- showImgInCell: {
415
- type: Boolean,
416
- default: false
417
- },
418
- config: {
419
- type: Object,
420
- default: function () {
421
- return {}
422
- }
423
- },
424
- // 命名空间
425
- serverName: {
426
- type: String,
427
- default: 'af-system'
428
- },
429
- // 环境
430
- env: {
431
- type: String,
432
- default: 'prod'
433
- },
434
- // 原始配置
435
- configData: {
436
- type: Object,
437
- required: true
438
- },
439
- // 是否为动态行
440
- inputColumns: {
441
- type: Boolean,
442
- default: false
443
- },
444
- // 是否为动态行按钮
445
- inputColumnsButton: {
446
- type: Boolean,
447
- default: false
448
- },
449
- // 动态行的Index
450
- inputColumnsDefinitionIndex: {
451
- type: Number,
452
- default: undefined
453
- },
454
- // 是否为展示行
455
- display: {
456
- type: Boolean,
457
- default: false
458
- },
459
- // list类型的下标,用于遍历列表时,获取对应的数据
460
- listIndex: {
461
- type: Number,
462
- default: undefined
463
- },
464
- // 表格没有上边框
465
- noTopBorder: {
466
- type: Boolean,
467
- default: false
468
- },
469
- // 图片是否使用OSS来保存
470
- useOssForImg: {
471
- type: Boolean,
472
- default: true
473
- },
474
- // 图片上传后添加前缀
475
- imgPrefix: {
476
- type: String,
477
- default: undefined
478
- }
479
- },
480
- data () {
481
- return {
482
- gutter: [16, { xs: 8, sm: 16, md: 24, lg: 32 }], // 设置水槽大小
483
- maxColSpan: 12,
484
- uploadParams: {
485
- type: 'image',
486
- accept: ['*'],
487
- resUploadStock: 1,
488
- pathKey: 'cs'
489
- },
490
- mixinData: {}
491
- // tableConfig: {}
492
- }
493
- },
494
- inject: ['openDialog', 'registerComponent', 'getComponentByName', 'runLogic', 'getMixinData', 'getSelectedId', 'isInAModal', 'getConfigByName', 'getSelectedData', 'getOutEnv'],
495
- methods: {
496
- getWindow,
497
- isMicroAppEnv,
498
- microDispatch,
499
- getMicroData,
500
- onComponentMounted (h, cell, cellIndex) {
501
- if (this.getMixinData && this.getMixinData()) {
502
- this.mixinData = this.getMixinData()
503
- }
504
- if (cell.slotRef) {
505
- this.registerComponent(cell.slotRef, this.$refs[`dynamicComponent_${cell.slotRef || cellIndex}`][0])
506
- }
507
- // 传递给祖先组件
508
- console.log(`插槽组件已经初始化 slotType ${cell.slotType},ref= dynamicComponent_${cell.slotRef || cellIndex} , serviceName = ${cell.serviceName}`)
509
- const shouldInit = cell.shouldInit == null ? true : cell.shouldInit
510
- if (shouldInit) {
511
- if (cell.slotType === 'x-add-native-form') {
512
- // 简易表单需要主动调用初始化方法
513
- getConfigByName(cell.slotConfig, cell.serviceName, async (res) => {
514
- // 如果配置了 表单初始化logic
515
- // 调用 logic 获取参数
516
- let param = { ...this.mixinData }
517
- let selectedId
518
- if (res.paramLogicName) {
519
- if (!!this.getSelectedId) {
520
- selectedId = this.getSelectedId()
521
- if (typeof selectedId !== 'object') {
522
- selectedId = { selectedId: selectedId }
523
- }
524
- }
525
- param = Object.assign(param, await runLogic(res.paramLogicName, selectedId, cell.serviceName))
526
- }
527
- this.$refs[`dynamicComponent_${cell.slotRef || cellIndex}`][0].init({
528
- serviceName: cell.serviceName,
529
- formItems: res.formJson,
530
- showSubmitBtn: !this.isInAModal,
531
- businessType: param.businessType || '新增',
532
- layout: res.xAddFormLayout,
533
- ...res,
534
- fixedAddForm: param,
535
- modifyModelData: {
536
- files: param.files,
537
- images: param.images
538
- }
539
- })
540
- }, this.env === 'dev')
541
- } else if (cell.soltType === 'x-form-group') {
542
- // 简易表单需要主动调用初始化方法
543
- getConfigByName(cell.slotConfig, cell.serviceName, (res) => {
544
- // 如果配置了 表单初始化logic
545
- // 调用 logic 获取参数
546
- const param = { ...this.mixinData }
547
- this.$refs[`dynamicComponent_${cell.slotRef || cellIndex}`][0].init({
548
- ...res,
549
- serviceName: cell.serviceName,
550
- showSubmitBtn: !this.isInAModal,
551
- businessType: param.businessType || '新增',
552
- modifyModelData: param,
553
- showLeftTab: true,
554
- })
555
- }, this.env === 'dev')
556
- }
557
- }
558
- if (cell.slotType === 'x-report') {
559
- const param = { ...this.mixinData }
560
- this.$refs[`dynamicComponent_${cell.slotRef || cellIndex}`][0].init(param)
561
- }
562
- },
563
- getEventHandlers (cell) {
564
- const handlers = {}
565
- if (!cell?.events || cell?.events?.length === 0) {
566
- return handlers
567
- }
568
- cell.events.forEach(event => {
569
- handlers[event.type] = async (...args) => {
570
- console.info('Event handled:', event.type, args)
571
- let func = event.customFunction
572
- if (func && func.startsWith('function')) {
573
- func = func.replace('function', 'async function')
574
- }
575
- const result = await executeStrFunctionByContext(this, func, args)
576
- if (result instanceof Promise) {
577
- result.then((res) => {
578
- if (!res) return
579
- let messageType = 'success'
580
- // 如果传递了组件名字 自动调用刷新
581
- if (res?.name) {
582
- const waitRefreshRef = this.getComponentByName(res.name)
583
- if (waitRefreshRef) {
584
- waitRefreshRef.refresh()
585
- } else {
586
- console.warn(`未找到组件${res.name}无法刷新`)
587
- }
588
- }
589
- // 如果传递消息类型 自动调用消息
590
- if (res?.messageType) {
591
- messageType = res.messageType
592
- }
593
- // 如果传递了提示信息自动调用提示
594
- if (res?.message) {
595
- this.$message[messageType](res?.message)
596
- }
597
- })
598
- }
599
- }
600
- })
601
- return handlers
602
- },
603
- getComponentName (queryParamsName, serviceName, componentName) {
604
- // const config = await getConfigByName(queryParamsName, serviceName)
605
- // const componentName = config.$globalProp.type
606
- return componentName
607
- },
608
- updateImg (data) {
609
- this.$emit('updateImg', data)
610
- },
611
- formatImgStr (str) {
612
- const result = []
613
- if (str !== '') {
614
- const arr = str.split('/')
615
- result.push({
616
- uid: nanoid(6),
617
- url: str,
618
- name: arr[arr.length - 1],
619
- status: 'done'
620
- })
621
- }
622
- this.uploadParams.acceptCount = 1
623
- return result
624
- },
625
- checkImg (index, type) {
626
- let target
627
- if (type === 'configData') {
628
- target = this.configData.images[index]
629
- } else {
630
- target = this.config.tempData[index]
631
- }
632
- if (typeof target !== 'object') {
633
- return this.formatImgStr(target)
634
- }
635
- target.forEach(obj => {
636
- if (obj.uid === undefined) {
637
- obj.uid = obj.id.toString()
638
- }
639
- if (obj.url === undefined) {
640
- if (obj.path) {
641
- obj.url = obj.path
642
- }
643
- }
644
- if (obj.name === undefined) {
645
- const withOutEndFix = obj.url.split('.')[0]
646
- const temp = withOutEndFix.split('/')
647
- obj.name = temp[temp.length - 1]
648
- }
649
- if (obj.status === undefined) {
650
- obj.status = 'done'
651
- }
652
- })
653
- return target
654
- },
655
- // 判断单元格样式
656
- determineCellStyle (cell, color = '#000', borderWidth = '1px') {
657
- // 如果声明了borderColor
658
- if (this.config.style.borderColor) {
659
- color = this.config.style.borderColor
660
- }
661
- // // 如果声明了borderWidth
662
- // if (this.config.style.borderWidth) {
663
- // borderWidth = this.config.style.borderWidth
664
- // }
665
- // // 普通带边框单元格
666
- // const withBorder = {
667
- // border: borderWidth + ' solid ' + color,
668
- // padding: '8px'
669
- // }
670
- // // 只有左右边框的单元格
671
- // const noBorder = {
672
- // borderLeft: borderWidth + ' solid ' + color,
673
- // borderRight: borderWidth + ' solid ' + color,
674
- // padding: '8px'
675
- // }
676
- // // 只没有上边框的单元格
677
- // const NoTopBorder = {
678
- // borderTopStyle: 'none',
679
- // borderLeft: borderWidth + ' solid ' + color,
680
- // borderRight: borderWidth + ' solid ' + color,
681
- // borderBottom: borderWidth + ' solid ' + color,
682
- // padding: '8px'
683
- // }
684
- let result = {}
685
- // 如果表格也声明了样式,用表格样式将样式覆盖
686
- if (cell.style) {
687
- if (cell.noBorder) {
688
- result = { ...cell.style }
689
- } else {
690
- if (this.noTopBorder) {
691
- result = { ...cell.style }
692
- } else {
693
- result = { ...cell.style }
694
- }
695
- }
696
- return result
697
- }
698
- return result
699
- },
700
- // 表格中数据key含有@@@,需要手动触发更新
701
- handleInputDeepChange () {
702
- this.$forceUpdate()
703
- },
704
- // 路径中含有@@@的key,将其解析,并返回其数据
705
- getDeepObject (obj, strPath) {
706
- if (!strPath) {
707
- return ''
708
- }
709
- const arr = strPath.split('@@@')
710
- let result = obj[arr[0]]
711
- arr.shift()
712
- try {
713
- while (arr.length > 0) {
714
- result = result[arr[0]]
715
- arr.shift()
716
- }
717
- } catch (e) {
718
- result = undefined
719
- }
720
- return result
721
- },
722
- // 获取当前日期
723
- getNowDate (index1, index2) {
724
- if (index2) {
725
- // @click="getNowDate(configData.arr[inputColumnsDefinitionIndex][cell.dataIndex])"
726
- this.configData.arr[index1][index2] = formatDate('now')
727
- } else {
728
- this.configData[index1] = formatDate('now')
729
- }
730
- this.configData = Object.assign({}, this.configData)
731
- },
732
- // 反序列化函数并执行
733
- deserializeFunctionAndRun (functionStr, value) {
734
- // eslint-disable-next-line no-eval
735
- const fun = eval('(' + functionStr + ')')
736
- return fun(value, this.config)
737
- },
738
- // 基础上传组件,图片改动后触发
739
- setImages (args, type, index = undefined) {
740
- // 如果基础上传组件在初始化完成后,就调用emit了setImage,此时图片并没有变化,直接返回
741
- if (args[2] === 'created') {
742
- return
743
- }
744
- if (type === 'configData') {
745
- this.configData.images[args[1]] = args[0]
746
- } else {
747
- this.config.tempData[args[1]] = args[0]
748
- if (index) {
749
- this.$emit('updateImg', this.config.tempData[index])
750
- }
751
- }
752
- },
753
- // 动态行删除
754
- removeData (index) {
755
- if (this.configData[index].length === 0) {
756
- this.$message.warn('已经没有更多了')
757
- return
758
- }
759
- this.configData[index].pop()
760
- },
761
- // 添加一行
762
- addData (index, row) {
763
- // 获取定义
764
- const defs = row[0].definition
765
-
766
- // 获取外层对象名
767
- const dataName = row[0].dataIndex
768
- const temp = {}
769
-
770
- defs.forEach(def => {
771
- // 找到数组中最后一个数据的值
772
- let lastDataNo = 0
773
- if (this.configData[dataName][this.configData[dataName].length - 1]) {
774
- lastDataNo = this.configData[dataName][this.configData[dataName].length - 1][def.dataIndex]
775
- }
776
-
777
- // 如果没有值,检查是否声明了初始值
778
- if (lastDataNo === 0 && def.initialValue) {
779
- lastDataNo = def.initialValue
780
- }
781
-
782
- // 检查是否有步长
783
- let step = 1
784
- if (def.step) {
785
- step = def.step
786
- }
787
-
788
- // 如果单元格类型为increment,则进行自增
789
- if (def.type === 'increment') {
790
- temp[def.dataIndex] = lastDataNo + step
791
- }
792
- })
793
- this.configData[index].push(temp)
794
- },
795
- // 根据format计算需要多少个输入框
796
- calcFormatInputNum (formatStr) {
797
- let count = 0
798
- for (let i = 0; i < formatStr.length; i++) {
799
- if (formatStr[i] === '{') {
800
- count++
801
- }
802
- }
803
- return count
804
- },
805
- // 根据format计算输入框之后的文字显示
806
- displayFormatText (formatStr, num) {
807
- let start = 0
808
- let count = 0
809
- num++
810
- for (let i = 0; i < formatStr.length; i++) {
811
- if (formatStr[i] === '}') {
812
- start = i
813
- count++
814
- }
815
- if (count === num) {
816
- for (let j = start + 1; j < formatStr.length; j++) {
817
- if (formatStr[j] === '{') {
818
- return formatStr.slice(start + 1, j)
819
- }
820
- if (j === formatStr.length - 1 && formatStr[j] !== '}') {
821
- return formatStr[j]
822
- }
823
- }
824
- }
825
- }
826
- },
827
- calcTDBorder (cellNoBorder = false) {
828
- if (cellNoBorder) {
829
- return 'tdNoBorder'
830
- } else {
831
- if (this.noTopBorder) {
832
- return 'tdWithNoTopBorder'
833
- } else {
834
- return 'tdWithBorder'
835
- }
836
- }
837
- },
838
- // 根据format计算输入框之前的文字显示
839
- displayFormatStartText (formatStr) {
840
- let count = 0
841
- for (let i = 0; i < formatStr.length; i++) {
842
- if (formatStr[i] === '{') {
843
- break
844
- } else {
845
- count++
846
- }
847
- }
848
- return formatStr.slice(0, count)
849
- },
850
- // 拼接被自动拆分的单元格内容
851
- showSubRowValue (cell) {
852
- const dataName = cell.dataIndex
853
- const formatArr = []
854
- const dataArr = []
855
-
856
- // 从config中取出所有数据,根据dataIndex的开头内容进行拼接
857
- this.config.columns.forEach(row => row.forEach(cell => {
858
- if (cell.dataIndex && cell.dataIndex.startsWith(dataName)) {
859
- formatArr.push(cell.format)
860
- dataArr.push(this.configData[cell.dataIndex])
861
- }
862
- }))
863
-
864
- const text = []
865
- const data = []
866
-
867
- formatArr.forEach(word => {
868
- const temp = word.split('{}')
869
- temp.forEach(char => {
870
- if (char !== '') {
871
- text.push(char)
872
- }
873
- })
874
- })
875
-
876
- dataArr.forEach(item => {
877
- item.forEach(num => {
878
- data.push(num)
879
- })
880
- })
881
-
882
- let result = ''
883
- for (let i = 0; i < data.length; i++) {
884
- result += data[i]
885
- result += text[i]
886
- }
887
-
888
- return result
889
- },
890
- // 把用户定义的组件,传递到整个杉格中,方便调用
891
- passComponentNamesToAncestor (refs) {
892
- console.log('组件的keys', Object.entries(refs), refs)
893
- // 遍历所有 refs
894
- Object.entries(refs).forEach(([refKey, refValue]) => {
895
- // 检查 ref 是否以 dynamicComponent_ 开头
896
- if (refKey.startsWith('dynamicComponent_')) {
897
- console.log('组件名存在')
898
- const componentRef = refValue[0]
899
- if (componentRef) {
900
- // 去掉前缀并获取组件名字
901
- const index = refKey.replace('dynamicComponent_', '') // 去掉前缀
902
- console.log('注册组件', index)
903
- // 传递给祖先组件
904
- this.registerComponent(index, componentRef)
905
- }
906
- }
907
- })
908
- }
909
- },
910
- beforeMount () {
911
- if (this.useOssForImg) {
912
- this.uploadParams.resUploadMode = 'oss'
913
- }
914
- },
915
- mounted () {
916
- },
917
- }
918
-
919
- </script>
920
-
921
- <style scoped lang="less">
922
- .inputsDiv {
923
- display: flex;
924
- justify-content: space-between;
925
-
926
- .inputsDivItem {
927
- display: flex;
928
- align-items: center;
929
- padding: 0 4px;
930
- white-space: nowrap;
931
-
932
- .inputsDivItemLabel {
933
- padding: 0 4px;
934
- }
935
- }
936
- }
937
-
938
- .tdNoBorder {
939
- border-left: 1px solid #000;
940
- border-right: 1px solid #000;
941
- padding: 8px;
942
- }
943
-
944
- .tdWithBorder {
945
- border: 1px solid #000;
946
- padding: 8px;
947
- }
948
-
949
- .tdWithNoTopBorder {
950
- border-top-style: none;
951
- border-left: 1px solid #000;
952
- border-right: 1px solid #000;
953
- border-bottom: 1px solid #000;
954
- padding: 8px;
955
- }
956
-
957
- .grid-content {
958
- border-radius: 4px;
959
- min-height: 36px;
960
- text-align: center;
961
- color: #fff;
962
- background-color: #606266;
963
- }
964
-
965
- .bg-purple {
966
- background: #9254de;
967
- }
968
-
969
- .bg-purple-light {
970
- background: #b37feb;
971
- }
972
- </style>
1
+ <template>
2
+ <a-row :gutter="gutter">
3
+ <!-- 预览页展示 -->
4
+ <template v-if="display">
5
+ <template v-if="!inputColumns">
6
+ <a-col
7
+ name="trGroup"
8
+ v-for="(cell, cellIndex) in columns"
9
+ v-if="!cell.dontShowRow"
10
+ :key="cellIndex"
11
+ :style="determineCellStyle(cell)"
12
+ :span="cell.colSpan ? cell.colSpan * 2 : undefined">
13
+ <!-- 插槽渲染 -->
14
+ <template v-if="cell.type === 'slot'">
15
+ <template
16
+ v-if="['x-form-table','x-add-native-form','x-tree-pro', 'x-his-editor', 'x-tab', 'x-form-group', 'x-report'].includes(cell.slotType)">
17
+ <component
18
+ :is="getComponentName(cell.slotConfig, cell.serviceName, cell.slotType)"
19
+ :key="cellIndex"
20
+ :ref="`dynamicComponent_${ cell.slotRef || cellIndex}`"
21
+ :serviceName="cell.serviceName"
22
+ :serverName="cell.serviceName"
23
+ v-on="getEventHandlers(cell)"
24
+ @hook:mounted="(h)=>onComponentMounted(h,cell,cellIndex)"
25
+ :queryParamsName="cell.slotConfig"
26
+ :configName="cell.slotConfig"
27
+ :countVisible="false"
28
+ :env="env"
29
+ />
30
+ </template>
31
+ </template>
32
+ <!-- button 按钮渲染 -->
33
+ <template v-else-if="cell.type === 'button'">
34
+ <a-button v-on="getEventHandlers(cell)">
35
+ {{ cell.buttonName }}
36
+ </a-button>
37
+ </template>
38
+ <template v-else-if="cell.type === 'column'">
39
+ <template v-if="cell.customFunction">
40
+ {{ deserializeFunctionAndRun(cell.customFunction, configData[cell.dataIndex], config) }}
41
+ </template>
42
+ <template v-else>
43
+ {{ cell.text }}
44
+ </template>
45
+ </template>
46
+ <!-- 占位 -->
47
+ <template v-else-if="cell.type === 'placeHolderColumn'">
48
+ </template>
49
+ <template v-else-if="cell.type === 'value'">
50
+ <template v-if="cell.customFunction === undefined">
51
+ {{ cell.value }}
52
+ </template>
53
+ <template v-else>
54
+ {{ deserializeFunctionAndRun(cell.customFunction, cell.value, config) }}
55
+ </template>
56
+ </template>
57
+ <template v-else-if="cell.type === 'input'">
58
+ <template v-if="cell.customFunction === undefined">
59
+ {{ getDeepObject(configData, cell.dataIndex) }}
60
+ </template>
61
+ <template v-else>
62
+ {{ deserializeFunctionAndRun(cell.customFunction, configData[cell.dataIndex], config) }}
63
+ </template>
64
+ </template>
65
+ <template v-else-if="cell.type === 'inputs'">
66
+ <template v-if="cell.customFunction === undefined">
67
+ {{ showSubRowValue(cell) }}
68
+ </template>
69
+ <template v-else>
70
+ {{ deserializeFunctionAndRun(cell.customFunction, showSubRowValue(cell), config) }}
71
+ </template>
72
+ </template>
73
+ <template v-else-if="cell.type === 'list'">
74
+ <template v-if="listIndex === 0">
75
+ <span style="font-weight: bold">{{ cell.listHead }}</span>
76
+ </template>
77
+ <template v-else-if="cell.listType === 'input'">
78
+ {{ getDeepObject(configData, cell.dataIndex)[listIndex] }}
79
+ </template>
80
+ <template v-else-if="cell.listType === 'value'">
81
+ {{ cell.content[listIndex] }}
82
+ </template>
83
+ <template v-else-if="cell.listType === 'variable'">
84
+ {{ configData[cell.dataIndex][listIndex - 1][cell.listDataIndex] }}
85
+ </template>
86
+ </template>
87
+ <template v-else-if="cell.type === 'images'">
88
+ <template
89
+ v-if="getDeepObject(configData.images, cell.dataIndex) === undefined || getDeepObject(configData.images, cell.dataIndex).length === 0">
90
+ <template
91
+ v-if="getDeepObject(configData, cell.dataIndex) === undefined || getDeepObject(configData, cell.dataIndex).length === 0">
92
+ <span>无</span>
93
+ </template>
94
+ <template v-else>
95
+ <template v-if="typeof getDeepObject(configData, cell.dataIndex) === 'object'">
96
+ <div style="display: flex; align-items: end; justify-content: space-evenly; flex-wrap: wrap">
97
+ <template v-for="(img,imgIndex) in getDeepObject(configData, cell.dataIndex)">
98
+ <template v-if="showImgInCell">
99
+ <div :key="imgIndex">
100
+ <img :src="img.url" alt="图片"/>
101
+ <p>{{ img.name }}</p>
102
+ </div>
103
+ </template>
104
+ <template v-else>
105
+ <span :key="imgIndex" style="margin-right: 5%">{{ img.name }}</span>
106
+ </template>
107
+ </template>
108
+ </div>
109
+ </template>
110
+ <template v-else>
111
+ <img :src="getDeepObject(configData, cell.dataIndex)" alt="图片"/>
112
+ <p style="margin-right: 5%">{{ formatImgStr(getDeepObject(configData, cell.dataIndex))[0].name }}</p>
113
+ </template>
114
+ </template>
115
+ </template>
116
+ <span v-else v-for="(img,imgIndex) in getDeepObject(configData.images, cell.dataIndex)" :key="imgIndex" style="margin-right: 5%">{{ img.name }}</span>
117
+ </template>
118
+ </a-col>
119
+ </template>
120
+ <template v-else>
121
+ <a-col
122
+ v-for="(cell, cellIndex) in columns"
123
+ :key="cellIndex"
124
+ :class=" calcTDBorder(cell.noBoarder) "
125
+ :span="cell.colSpan ? cell.colSpan * 2 : undefined"
126
+ :style="determineCellStyle(cell)"
127
+ :rowspan="cell.rowSpan ? cell.rowSpan : undefined">
128
+ <template v-if="cell.type === 'column'">
129
+ {{ cell.text }}
130
+ </template>
131
+ <template v-else-if="cell.type === 'value'">
132
+ <template v-if="cell.customFunction === undefined">
133
+ {{ cell.value }}
134
+ </template>
135
+ <template v-else>
136
+ {{ deserializeFunctionAndRun(cell.customFunction, cell.value, config) }}
137
+ </template>
138
+ </template>
139
+ <template v-else-if="cell.type === 'increment'">
140
+ <template v-if="cell.customFunction === undefined">
141
+ {{ getDeepObject(configData.arr[inputColumnsDefinitionIndex], cell.dataIndex) }}
142
+ </template>
143
+ <template v-else>
144
+ {{
145
+ deserializeFunctionAndRun(cell.customFunction, configData.arr[inputColumnsDefinitionIndex][cell.dataIndex], config)
146
+ }}
147
+ </template>
148
+ </template>
149
+ <template v-else-if="cell.type === 'input'">
150
+ <template v-if="cell.customFunction === undefined">
151
+ {{ getDeepObject(configData.arr[inputColumnsDefinitionIndex], cell.dataIndex) }}
152
+ </template>
153
+ <template v-else>
154
+ {{
155
+ deserializeFunctionAndRun(cell.customFunction, configData.arr[inputColumnsDefinitionIndex][cell.dataIndex], config)
156
+ }}
157
+ </template>
158
+ </template>
159
+ <template v-else-if="cell.type === 'inputs'">
160
+ <template v-if="cell.customFunction === undefined">
161
+ {{ getDeepObject(configData.arr[inputColumnsDefinitionIndex], cell.dataIndex) }}
162
+ </template>
163
+ <template v-else>
164
+ {{
165
+ deserializeFunctionAndRun(cell.customFunction, configData.arr[inputColumnsDefinitionIndex][cell.dataIndex], config)
166
+ }}
167
+ </template>
168
+ </template>
169
+ </a-col>
170
+ </template>
171
+ </template>
172
+ <!-- 不是动态行 -->
173
+ <template v-else-if="!inputColumns">
174
+ <a-col
175
+ v-for="(cell, cellIndex) in columns"
176
+ :key="cellIndex"
177
+ :class=" calcTDBorder(cell.noBoarder) "
178
+ :span="cell.colSpan ? cell.colSpan * 2 : undefined"
179
+ :style="determineCellStyle(cell)"
180
+ :rowspan="cell.rowSpan ? cell.rowSpan : undefined">
181
+ <template v-if="cell.type === 'column'">
182
+ <template v-if="cell.customFunction">
183
+ {{ deserializeFunctionAndRun(cell.customFunction, configData[cell.dataIndex], config) }}
184
+ </template>
185
+ <template v-else>
186
+ {{ cell.text }}
187
+ </template>
188
+ </template>
189
+ <template v-else-if="cell.type === 'placeHolderColumn'">
190
+ <!-- 占位 -->
191
+ </template>
192
+ <template v-else-if="cell.type === 'value'">
193
+ {{ cell.value }}
194
+ </template>
195
+ <template v-else-if="cell.type === 'curDateInput'">
196
+ <a-button type="dashed" v-if="configData[cell.dataIndex]">
197
+ {{ configData[cell.dataIndex] }}
198
+ </a-button>
199
+ <a-button
200
+ v-if="!configData[cell.dataIndex]"
201
+ type="primary"
202
+ @click="getNowDate(cell.dataIndex)"
203
+ >{{ cell.text || '确认' }}
204
+ </a-button>
205
+ </template>
206
+ <template v-else-if="cell.type === 'input'">
207
+ <template v-if="cell.inputReadOnly === true">
208
+ <template v-if="cell.dataIndex.indexOf('@@@') !== -1">
209
+ <a-input
210
+ @change="handleInputDeepChange($event, cell.dataIndex)"
211
+ v-model="config.tempData[cell.dataIndex]"
212
+ :style="'width:' + (cell.inputWidth ? cell.inputWidth : '100') + '%'"
213
+ :disabled="true"/>
214
+ </template>
215
+ <template v-else>
216
+ <a-input
217
+ v-model="configData[cell.dataIndex]"
218
+ :style="'width:' + (cell.inputWidth ? cell.inputWidth : '100') + '%'"
219
+ :disabled="true"/>
220
+ </template>
221
+ </template>
222
+ <template v-else>
223
+ <template v-if="cell.dataIndex.indexOf('@@@') !== -1">
224
+ <a-input
225
+ @change="handleInputDeepChange($event, cell.dataIndex)"
226
+ v-model="config.tempData[cell.dataIndex]"
227
+ :style="'width:' + (cell.inputWidth ? cell.inputWidth : '100') + '%'"/>
228
+ </template>
229
+ <template v-else>
230
+ <a-input
231
+ v-model="configData[cell.dataIndex]"
232
+ :style="'width:' + (cell.inputWidth ? cell.inputWidth : '100') + '%'"/>
233
+ </template>
234
+ </template>
235
+ </template>
236
+ <template v-else-if="cell.type === 'inputs'">
237
+ <template v-if="cell.inputReadOnly === true">
238
+ <div class="inputsDiv">
239
+ <div class="inputsDivItem" v-for="(num, index) of calcFormatInputNum(cell.format)" :key="index">
240
+ <span class="inputsDivItemLabel">{{ displayFormatStartText(cell.format) }}</span>
241
+ <template v-if="cell.dataIndex.indexOf('@@@') !== -1">
242
+ <a-input
243
+ @change="handleInputDeepChange($event, cell.dataIndex)"
244
+ v-model="config.tempData[cell.dataIndex][index]"
245
+ :style="'width:' + (cell.inputWidth ? cell.inputWidth : '100') + '%'"
246
+ :disabled="true"/>
247
+ </template>
248
+ <template v-else>
249
+ <a-input
250
+ v-model="configData[cell.dataIndex][index]"
251
+ :style="'width:' + (cell.inputWidth ? cell.inputWidth : '100') + '%'"
252
+ :disabled="true"/>
253
+ </template>
254
+ <span class="inputsDivItemLabel">{{ displayFormatText(cell.format, index) }}</span>
255
+ </div>
256
+ </div>
257
+ </template>
258
+ <template v-else>
259
+ <div class="inputsDiv">
260
+ <div class="inputsDivItem" v-for="(num, index) of calcFormatInputNum(cell.format)" :key="index">
261
+ <span class="inputsDivItemLabel">{{ displayFormatStartText(cell.format) }}</span>
262
+ <template v-if="cell.dataIndex.indexOf('@@@') !== -1">
263
+ <a-input
264
+ @change="handleInputDeepChange($event, cell.dataIndex)"
265
+ v-model="config.tempData[cell.dataIndex][index]"
266
+ :style="'width:' + (cell.inputWidth ? cell.inputWidth : '100') + '%'"/>
267
+ </template>
268
+ <template v-else>
269
+ <a-input
270
+ v-model="configData[cell.dataIndex][index]"
271
+ :style="'width:' + (cell.inputWidth ? cell.inputWidth : '100') + '%'"/>
272
+ </template>
273
+ <span class="inputsDivItemLabel">{{ displayFormatText(cell.format, index) }}</span>
274
+ </div>
275
+ </div>
276
+ </template>
277
+ </template>
278
+ <template v-else-if="cell.type === 'list'">
279
+ <template v-if="cell.listType === 'input'">
280
+ <a-input
281
+ v-model="configData[cell.dataIndex][listIndex]"
282
+ :style="'width:' + (cell.inputWidth ? cell.inputWidth : '100') + '%'"/>
283
+ </template>
284
+ <template v-else-if="cell.listType === 'value'">
285
+ {{ cell.content[listIndex] }}
286
+ </template>
287
+ </template>
288
+ <template v-else-if="cell.type === 'images'">
289
+ <div>
290
+ <template v-if="configData.images[cell.dataIndex]?.length > 0">
291
+ <upload
292
+ :model="uploadParams"
293
+ :img-prefix="imgPrefix"
294
+ :service-name="serverName"
295
+ :images="checkImg(cell.dataIndex, 'configData')"
296
+ :outer-container-index="cell.dataIndex"
297
+ @setFiles="(...args) => {setImages(args, 'configData')}"
298
+ :upload-style="'simple'"
299
+ />
300
+ </template>
301
+ <template v-else>
302
+ <upload
303
+ :model="uploadParams"
304
+ :img-prefix="imgPrefix"
305
+ :service-name="serverName"
306
+ :images="checkImg(cell.dataIndex, 'config')"
307
+ :outer-container-index="cell.dataIndex"
308
+ @setFiles="(...args) => {setImages(args, 'config', cell.dataIndex)}"
309
+ :upload-style="'simple'"
310
+ />
311
+ </template>
312
+ </div>
313
+ </template>
314
+ </a-col>
315
+ </template>
316
+ <!-- 动态行插入按钮 -->
317
+ <template v-else-if="inputColumnsButton">
318
+ <a-col :span="maxColSpan" :class="calcTDBorder()">
319
+ <a-button-group>
320
+ <a-button @click="addData(columns[0].dataIndex, columns)">
321
+ <a-icon type="plus"/>
322
+ </a-button>
323
+ <a-button @click="removeData(columns[0].dataIndex)">
324
+ <a-icon type="minus"/>
325
+ </a-button>
326
+ </a-button-group>
327
+ </a-col>
328
+ </template>
329
+ <!-- 其他行 -->
330
+ <template v-else>
331
+ <a-col
332
+ v-for="(cell, cellIndex) in columns"
333
+ :key="cellIndex"
334
+ :class=" calcTDBorder(cell.noBoarder) "
335
+ :span="cell.colSpan ? cell.colSpan * 2 : undefined"
336
+ :style="determineCellStyle(cell)"
337
+ :rowspan="cell.rowSpan ? cell.rowSpan : undefined">
338
+ <template v-if="cell.type === 'column'">
339
+ {{ cell.text }}
340
+ </template>
341
+ <template v-else-if="cell.type === 'value'">
342
+ {{ cell.value }}
343
+ </template>
344
+ <template v-else-if="cell.type === 'curDateInput'">
345
+ <a-button type="dashed" v-if="configData.arr[inputColumnsDefinitionIndex][cell.dataIndex]">
346
+ {{ configData.arr[inputColumnsDefinitionIndex][cell.dataIndex] }}
347
+ </a-button>
348
+ <a-button
349
+ v-if="!configData.arr[inputColumnsDefinitionIndex][cell.dataIndex]"
350
+ type="primary"
351
+ @click="getNowDate(inputColumnsDefinitionIndex,cell.dataIndex)"
352
+ >{{ cell.text || '确认' }}
353
+ </a-button>
354
+ </template>
355
+ <template v-else-if="cell.type === 'increment'">
356
+ {{ configData.arr[inputColumnsDefinitionIndex][cell.dataIndex] }}
357
+ </template>
358
+ <template v-else-if="cell.type === 'input'">
359
+ <template v-if="cell.inputReadOnly === true">
360
+ <a-input
361
+ v-model="configData.arr[inputColumnsDefinitionIndex][cell.dataIndex]"
362
+ :style="'width:' + (cell.inputWidth ? cell.inputWidth : '100') + '%'"
363
+ :disabled="true"/>
364
+ </template>
365
+ <template v-else>
366
+ <a-input
367
+ v-model="configData.arr[inputColumnsDefinitionIndex][cell.dataIndex]"
368
+ :style="'width:' + (cell.inputWidth ? cell.inputWidth : '100') + '%'"/>
369
+ </template>
370
+ </template>
371
+ <template v-else-if="cell.type === 'inputs'">
372
+ <template v-if="cell.inputReadOnly === true">
373
+ <a-input
374
+ v-model="configData.arr[inputColumnsDefinitionIndex][cell.dataIndex]"
375
+ :style="'width:' + (cell.inputWidth ? cell.inputWidth : '100') + '%'"
376
+ :disabled="true"/>
377
+ </template>
378
+ <template v-else>
379
+ <a-input
380
+ v-model="configData.arr[inputColumnsDefinitionIndex][cell.dataIndex]"
381
+ :style="'width:' + (cell.inputWidth ? cell.inputWidth : '100') + '%'"/>
382
+ </template>
383
+ </template>
384
+ </a-col>
385
+ </template>
386
+ </a-row>
387
+ </template>
388
+
389
+ <script>
390
+ import Upload from '@vue2-client/base-client/components/common/Upload'
391
+ import { formatDate } from '@vue2-client/utils/util'
392
+ import { nanoid } from 'nanoid'
393
+ import { executeStrFunctionByContext } from '@vue2-client/utils/runEvalFunction'
394
+ import { getConfigByName, runLogic } from '@vue2-client/services/api/common'
395
+ import { getMicroData, getWindow, isMicroAppEnv, microDispatch } from '@vue2-client/utils/microAppUtils'
396
+
397
+ export default {
398
+ name: 'XReportTrGroup',
399
+ components: {
400
+ Upload,
401
+ XFormTable: () => import('@vue2-client/base-client/components/common/XFormTable/XFormTable.vue'),
402
+ XAddNativeForm: () => import('@vue2-client/base-client/components/common/XAddNativeForm/XAddNativeForm.vue'),
403
+ XTreePro: () => import('@vue2-client/base-client/components/common/XTree/XTreePro.vue'),
404
+ XHisEditor: () => import('@vue2-client/base-client/components/his/XHisEditor/XHisEditor.vue'),
405
+ XTab: () => import('@vue2-client/base-client/components/common/XTab/XTab.vue'),
406
+ XReport: () => import('@vue2-client/base-client/components/common/XReport/XReport.vue')
407
+ },
408
+ props: {
409
+ // 每一行的配置
410
+ columns: {
411
+ type: Array,
412
+ required: true
413
+ },
414
+ showImgInCell: {
415
+ type: Boolean,
416
+ default: false
417
+ },
418
+ config: {
419
+ type: Object,
420
+ default: function () {
421
+ return {}
422
+ }
423
+ },
424
+ // 命名空间
425
+ serverName: {
426
+ type: String,
427
+ default: 'af-system'
428
+ },
429
+ // 环境
430
+ env: {
431
+ type: String,
432
+ default: 'prod'
433
+ },
434
+ // 原始配置
435
+ configData: {
436
+ type: Object,
437
+ required: true
438
+ },
439
+ // 是否为动态行
440
+ inputColumns: {
441
+ type: Boolean,
442
+ default: false
443
+ },
444
+ // 是否为动态行按钮
445
+ inputColumnsButton: {
446
+ type: Boolean,
447
+ default: false
448
+ },
449
+ // 动态行的Index
450
+ inputColumnsDefinitionIndex: {
451
+ type: Number,
452
+ default: undefined
453
+ },
454
+ // 是否为展示行
455
+ display: {
456
+ type: Boolean,
457
+ default: false
458
+ },
459
+ // list类型的下标,用于遍历列表时,获取对应的数据
460
+ listIndex: {
461
+ type: Number,
462
+ default: undefined
463
+ },
464
+ // 表格没有上边框
465
+ noTopBorder: {
466
+ type: Boolean,
467
+ default: false
468
+ },
469
+ // 图片是否使用OSS来保存
470
+ useOssForImg: {
471
+ type: Boolean,
472
+ default: true
473
+ },
474
+ // 图片上传后添加前缀
475
+ imgPrefix: {
476
+ type: String,
477
+ default: undefined
478
+ }
479
+ },
480
+ data () {
481
+ return {
482
+ gutter: [16, { xs: 8, sm: 16, md: 24, lg: 32 }], // 设置水槽大小
483
+ maxColSpan: 12,
484
+ uploadParams: {
485
+ type: 'image',
486
+ accept: ['*'],
487
+ resUploadStock: 1,
488
+ pathKey: 'cs'
489
+ },
490
+ mixinData: {}
491
+ // tableConfig: {}
492
+ }
493
+ },
494
+ inject: ['openDialog', 'registerComponent', 'getComponentByName', 'runLogic', 'getMixinData', 'getSelectedId', 'isInAModal', 'getConfigByName', 'getSelectedData', 'getOutEnv'],
495
+ methods: {
496
+ getWindow,
497
+ isMicroAppEnv,
498
+ microDispatch,
499
+ getMicroData,
500
+ onComponentMounted (h, cell, cellIndex) {
501
+ if (this.getMixinData && this.getMixinData()) {
502
+ this.mixinData = this.getMixinData()
503
+ }
504
+ if (cell.slotRef) {
505
+ this.registerComponent(cell.slotRef, this.$refs[`dynamicComponent_${cell.slotRef || cellIndex}`][0])
506
+ }
507
+ // 传递给祖先组件
508
+ console.log(`插槽组件已经初始化 slotType ${cell.slotType},ref= dynamicComponent_${cell.slotRef || cellIndex} , serviceName = ${cell.serviceName}`)
509
+ const shouldInit = cell.shouldInit == null ? true : cell.shouldInit
510
+ if (shouldInit) {
511
+ if (cell.slotType === 'x-add-native-form') {
512
+ // 简易表单需要主动调用初始化方法
513
+ getConfigByName(cell.slotConfig, cell.serviceName, async (res) => {
514
+ // 如果配置了 表单初始化logic
515
+ // 调用 logic 获取参数
516
+ let param = { ...this.mixinData }
517
+ let selectedId
518
+ if (res.paramLogicName) {
519
+ if (!!this.getSelectedId) {
520
+ selectedId = this.getSelectedId()
521
+ if (typeof selectedId !== 'object') {
522
+ selectedId = { selectedId: selectedId }
523
+ }
524
+ }
525
+ param = Object.assign(param, await runLogic(res.paramLogicName, selectedId, cell.serviceName))
526
+ }
527
+ this.$refs[`dynamicComponent_${cell.slotRef || cellIndex}`][0].init({
528
+ serviceName: cell.serviceName,
529
+ formItems: res.formJson,
530
+ showSubmitBtn: !this.isInAModal,
531
+ businessType: param.businessType || '新增',
532
+ layout: res.xAddFormLayout,
533
+ ...res,
534
+ fixedAddForm: param,
535
+ modifyModelData: {
536
+ files: param.files,
537
+ images: param.images
538
+ }
539
+ })
540
+ }, this.env === 'dev')
541
+ } else if (cell.soltType === 'x-form-group') {
542
+ // 简易表单需要主动调用初始化方法
543
+ getConfigByName(cell.slotConfig, cell.serviceName, (res) => {
544
+ // 如果配置了 表单初始化logic
545
+ // 调用 logic 获取参数
546
+ const param = { ...this.mixinData }
547
+ this.$refs[`dynamicComponent_${cell.slotRef || cellIndex}`][0].init({
548
+ ...res,
549
+ serviceName: cell.serviceName,
550
+ showSubmitBtn: !this.isInAModal,
551
+ businessType: param.businessType || '新增',
552
+ modifyModelData: param,
553
+ showLeftTab: true,
554
+ })
555
+ }, this.env === 'dev')
556
+ }
557
+ }
558
+ if (cell.slotType === 'x-report') {
559
+ const param = { ...this.mixinData }
560
+ this.$refs[`dynamicComponent_${cell.slotRef || cellIndex}`][0].init(param)
561
+ }
562
+ },
563
+ getEventHandlers (cell) {
564
+ const handlers = {}
565
+ if (!cell?.events || cell?.events?.length === 0) {
566
+ return handlers
567
+ }
568
+ cell.events.forEach(event => {
569
+ handlers[event.type] = async (...args) => {
570
+ console.info('Event handled:', event.type, args)
571
+ let func = event.customFunction
572
+ if (func && func.startsWith('function')) {
573
+ func = func.replace('function', 'async function')
574
+ }
575
+ const result = await executeStrFunctionByContext(this, func, args)
576
+ if (result instanceof Promise) {
577
+ result.then((res) => {
578
+ if (!res) return
579
+ let messageType = 'success'
580
+ // 如果传递了组件名字 自动调用刷新
581
+ if (res?.name) {
582
+ const waitRefreshRef = this.getComponentByName(res.name)
583
+ if (waitRefreshRef) {
584
+ waitRefreshRef.refresh()
585
+ } else {
586
+ console.warn(`未找到组件${res.name}无法刷新`)
587
+ }
588
+ }
589
+ // 如果传递消息类型 自动调用消息
590
+ if (res?.messageType) {
591
+ messageType = res.messageType
592
+ }
593
+ // 如果传递了提示信息自动调用提示
594
+ if (res?.message) {
595
+ this.$message[messageType](res?.message)
596
+ }
597
+ })
598
+ }
599
+ }
600
+ })
601
+ return handlers
602
+ },
603
+ getComponentName (queryParamsName, serviceName, componentName) {
604
+ // const config = await getConfigByName(queryParamsName, serviceName)
605
+ // const componentName = config.$globalProp.type
606
+ return componentName
607
+ },
608
+ updateImg (data) {
609
+ this.$emit('updateImg', data)
610
+ },
611
+ formatImgStr (str) {
612
+ const result = []
613
+ if (str !== '') {
614
+ const arr = str.split('/')
615
+ result.push({
616
+ uid: nanoid(6),
617
+ url: str,
618
+ name: arr[arr.length - 1],
619
+ status: 'done'
620
+ })
621
+ }
622
+ this.uploadParams.acceptCount = 1
623
+ return result
624
+ },
625
+ checkImg (index, type) {
626
+ let target
627
+ if (type === 'configData') {
628
+ target = this.configData.images[index]
629
+ } else {
630
+ target = this.config.tempData[index]
631
+ }
632
+ if (typeof target !== 'object') {
633
+ return this.formatImgStr(target)
634
+ }
635
+ target.forEach(obj => {
636
+ if (obj.uid === undefined) {
637
+ obj.uid = obj.id.toString()
638
+ }
639
+ if (obj.url === undefined) {
640
+ if (obj.path) {
641
+ obj.url = obj.path
642
+ }
643
+ }
644
+ if (obj.name === undefined) {
645
+ const withOutEndFix = obj.url.split('.')[0]
646
+ const temp = withOutEndFix.split('/')
647
+ obj.name = temp[temp.length - 1]
648
+ }
649
+ if (obj.status === undefined) {
650
+ obj.status = 'done'
651
+ }
652
+ })
653
+ return target
654
+ },
655
+ // 判断单元格样式
656
+ determineCellStyle (cell, color = '#000', borderWidth = '1px') {
657
+ // 如果声明了borderColor
658
+ if (this.config.style.borderColor) {
659
+ color = this.config.style.borderColor
660
+ }
661
+ // // 如果声明了borderWidth
662
+ // if (this.config.style.borderWidth) {
663
+ // borderWidth = this.config.style.borderWidth
664
+ // }
665
+ // // 普通带边框单元格
666
+ // const withBorder = {
667
+ // border: borderWidth + ' solid ' + color,
668
+ // padding: '8px'
669
+ // }
670
+ // // 只有左右边框的单元格
671
+ // const noBorder = {
672
+ // borderLeft: borderWidth + ' solid ' + color,
673
+ // borderRight: borderWidth + ' solid ' + color,
674
+ // padding: '8px'
675
+ // }
676
+ // // 只没有上边框的单元格
677
+ // const NoTopBorder = {
678
+ // borderTopStyle: 'none',
679
+ // borderLeft: borderWidth + ' solid ' + color,
680
+ // borderRight: borderWidth + ' solid ' + color,
681
+ // borderBottom: borderWidth + ' solid ' + color,
682
+ // padding: '8px'
683
+ // }
684
+ let result = {}
685
+ // 如果表格也声明了样式,用表格样式将样式覆盖
686
+ if (cell.style) {
687
+ if (cell.noBorder) {
688
+ result = { ...cell.style }
689
+ } else {
690
+ if (this.noTopBorder) {
691
+ result = { ...cell.style }
692
+ } else {
693
+ result = { ...cell.style }
694
+ }
695
+ }
696
+ return result
697
+ }
698
+ return result
699
+ },
700
+ // 表格中数据key含有@@@,需要手动触发更新
701
+ handleInputDeepChange () {
702
+ this.$forceUpdate()
703
+ },
704
+ // 路径中含有@@@的key,将其解析,并返回其数据
705
+ getDeepObject (obj, strPath) {
706
+ if (!strPath) {
707
+ return ''
708
+ }
709
+ const arr = strPath.split('@@@')
710
+ let result = obj[arr[0]]
711
+ arr.shift()
712
+ try {
713
+ while (arr.length > 0) {
714
+ result = result[arr[0]]
715
+ arr.shift()
716
+ }
717
+ } catch (e) {
718
+ result = undefined
719
+ }
720
+ return result
721
+ },
722
+ // 获取当前日期
723
+ getNowDate (index1, index2) {
724
+ if (index2) {
725
+ // @click="getNowDate(configData.arr[inputColumnsDefinitionIndex][cell.dataIndex])"
726
+ this.configData.arr[index1][index2] = formatDate('now')
727
+ } else {
728
+ this.configData[index1] = formatDate('now')
729
+ }
730
+ this.configData = Object.assign({}, this.configData)
731
+ },
732
+ // 反序列化函数并执行
733
+ deserializeFunctionAndRun (functionStr, value) {
734
+ // eslint-disable-next-line no-eval
735
+ const fun = eval('(' + functionStr + ')')
736
+ return fun(value, this.config)
737
+ },
738
+ // 基础上传组件,图片改动后触发
739
+ setImages (args, type, index = undefined) {
740
+ // 如果基础上传组件在初始化完成后,就调用emit了setImage,此时图片并没有变化,直接返回
741
+ if (args[2] === 'created') {
742
+ return
743
+ }
744
+ if (type === 'configData') {
745
+ this.configData.images[args[1]] = args[0]
746
+ } else {
747
+ this.config.tempData[args[1]] = args[0]
748
+ if (index) {
749
+ this.$emit('updateImg', this.config.tempData[index])
750
+ }
751
+ }
752
+ },
753
+ // 动态行删除
754
+ removeData (index) {
755
+ if (this.configData[index].length === 0) {
756
+ this.$message.warn('已经没有更多了')
757
+ return
758
+ }
759
+ this.configData[index].pop()
760
+ },
761
+ // 添加一行
762
+ addData (index, row) {
763
+ // 获取定义
764
+ const defs = row[0].definition
765
+
766
+ // 获取外层对象名
767
+ const dataName = row[0].dataIndex
768
+ const temp = {}
769
+
770
+ defs.forEach(def => {
771
+ // 找到数组中最后一个数据的值
772
+ let lastDataNo = 0
773
+ if (this.configData[dataName][this.configData[dataName].length - 1]) {
774
+ lastDataNo = this.configData[dataName][this.configData[dataName].length - 1][def.dataIndex]
775
+ }
776
+
777
+ // 如果没有值,检查是否声明了初始值
778
+ if (lastDataNo === 0 && def.initialValue) {
779
+ lastDataNo = def.initialValue
780
+ }
781
+
782
+ // 检查是否有步长
783
+ let step = 1
784
+ if (def.step) {
785
+ step = def.step
786
+ }
787
+
788
+ // 如果单元格类型为increment,则进行自增
789
+ if (def.type === 'increment') {
790
+ temp[def.dataIndex] = lastDataNo + step
791
+ }
792
+ })
793
+ this.configData[index].push(temp)
794
+ },
795
+ // 根据format计算需要多少个输入框
796
+ calcFormatInputNum (formatStr) {
797
+ let count = 0
798
+ for (let i = 0; i < formatStr.length; i++) {
799
+ if (formatStr[i] === '{') {
800
+ count++
801
+ }
802
+ }
803
+ return count
804
+ },
805
+ // 根据format计算输入框之后的文字显示
806
+ displayFormatText (formatStr, num) {
807
+ let start = 0
808
+ let count = 0
809
+ num++
810
+ for (let i = 0; i < formatStr.length; i++) {
811
+ if (formatStr[i] === '}') {
812
+ start = i
813
+ count++
814
+ }
815
+ if (count === num) {
816
+ for (let j = start + 1; j < formatStr.length; j++) {
817
+ if (formatStr[j] === '{') {
818
+ return formatStr.slice(start + 1, j)
819
+ }
820
+ if (j === formatStr.length - 1 && formatStr[j] !== '}') {
821
+ return formatStr[j]
822
+ }
823
+ }
824
+ }
825
+ }
826
+ },
827
+ calcTDBorder (cellNoBorder = false) {
828
+ if (cellNoBorder) {
829
+ return 'tdNoBorder'
830
+ } else {
831
+ if (this.noTopBorder) {
832
+ return 'tdWithNoTopBorder'
833
+ } else {
834
+ return 'tdWithBorder'
835
+ }
836
+ }
837
+ },
838
+ // 根据format计算输入框之前的文字显示
839
+ displayFormatStartText (formatStr) {
840
+ let count = 0
841
+ for (let i = 0; i < formatStr.length; i++) {
842
+ if (formatStr[i] === '{') {
843
+ break
844
+ } else {
845
+ count++
846
+ }
847
+ }
848
+ return formatStr.slice(0, count)
849
+ },
850
+ // 拼接被自动拆分的单元格内容
851
+ showSubRowValue (cell) {
852
+ const dataName = cell.dataIndex
853
+ const formatArr = []
854
+ const dataArr = []
855
+
856
+ // 从config中取出所有数据,根据dataIndex的开头内容进行拼接
857
+ this.config.columns.forEach(row => row.forEach(cell => {
858
+ if (cell.dataIndex && cell.dataIndex.startsWith(dataName)) {
859
+ formatArr.push(cell.format)
860
+ dataArr.push(this.configData[cell.dataIndex])
861
+ }
862
+ }))
863
+
864
+ const text = []
865
+ const data = []
866
+
867
+ formatArr.forEach(word => {
868
+ const temp = word.split('{}')
869
+ temp.forEach(char => {
870
+ if (char !== '') {
871
+ text.push(char)
872
+ }
873
+ })
874
+ })
875
+
876
+ dataArr.forEach(item => {
877
+ item.forEach(num => {
878
+ data.push(num)
879
+ })
880
+ })
881
+
882
+ let result = ''
883
+ for (let i = 0; i < data.length; i++) {
884
+ result += data[i]
885
+ result += text[i]
886
+ }
887
+
888
+ return result
889
+ },
890
+ // 把用户定义的组件,传递到整个杉格中,方便调用
891
+ passComponentNamesToAncestor (refs) {
892
+ console.log('组件的keys', Object.entries(refs), refs)
893
+ // 遍历所有 refs
894
+ Object.entries(refs).forEach(([refKey, refValue]) => {
895
+ // 检查 ref 是否以 dynamicComponent_ 开头
896
+ if (refKey.startsWith('dynamicComponent_')) {
897
+ console.log('组件名存在')
898
+ const componentRef = refValue[0]
899
+ if (componentRef) {
900
+ // 去掉前缀并获取组件名字
901
+ const index = refKey.replace('dynamicComponent_', '') // 去掉前缀
902
+ console.log('注册组件', index)
903
+ // 传递给祖先组件
904
+ this.registerComponent(index, componentRef)
905
+ }
906
+ }
907
+ })
908
+ }
909
+ },
910
+ beforeMount () {
911
+ if (this.useOssForImg) {
912
+ this.uploadParams.resUploadMode = 'oss'
913
+ }
914
+ },
915
+ mounted () {
916
+ },
917
+ }
918
+
919
+ </script>
920
+
921
+ <style scoped lang="less">
922
+ .inputsDiv {
923
+ display: flex;
924
+ justify-content: space-between;
925
+
926
+ .inputsDivItem {
927
+ display: flex;
928
+ align-items: center;
929
+ padding: 0 4px;
930
+ white-space: nowrap;
931
+
932
+ .inputsDivItemLabel {
933
+ padding: 0 4px;
934
+ }
935
+ }
936
+ }
937
+
938
+ .tdNoBorder {
939
+ border-left: 1px solid #000;
940
+ border-right: 1px solid #000;
941
+ padding: 8px;
942
+ }
943
+
944
+ .tdWithBorder {
945
+ border: 1px solid #000;
946
+ padding: 8px;
947
+ }
948
+
949
+ .tdWithNoTopBorder {
950
+ border-top-style: none;
951
+ border-left: 1px solid #000;
952
+ border-right: 1px solid #000;
953
+ border-bottom: 1px solid #000;
954
+ padding: 8px;
955
+ }
956
+
957
+ .grid-content {
958
+ border-radius: 4px;
959
+ min-height: 36px;
960
+ text-align: center;
961
+ color: #fff;
962
+ background-color: #606266;
963
+ }
964
+
965
+ .bg-purple {
966
+ background: #9254de;
967
+ }
968
+
969
+ .bg-purple-light {
970
+ background: #b37feb;
971
+ }
972
+ </style>