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,1156 +1,1149 @@
1
- <template>
2
- <!-- 输入框 -->
3
- <x-form-col
4
- v-if="attr.type === 'input' && show"
5
- :flex="attr.flex">
6
- <a-form-model-item
7
- :ref="attr.model"
8
- :label="showLabel?attr.name:undefined"
9
- :labelCol="layout === 'inline' && attr.occupyCol ? labelAndWrapperCol[attr.occupyCol].labelCol:undefined"
10
- :wrapperCol="layout === 'inline'&& attr.occupyCol ? labelAndWrapperCol[attr.occupyCol].wrapperCol:undefined"
11
- :style="layout === 'inline'&& attr.occupyCol && attr.occupyCol > 1? {width:`calc(100% - ${attr.occupyCol * 1.533}rem)`}:{}"
12
- :prop="attr.prop ? attr.prop : attr.model">
13
- <!-- 如果配置了后置按钮插槽 -->
14
- <a-input-group
15
- v-if="(attr.inputOnAfterName && attr.inputOnAfterFunc) || (attr.inputOnAfterIcon && attr.inputOnAfterIconFunc)"
16
- style="display: flex; width: 100%;"
17
- compact>
18
- <a-input
19
- v-model="form[attr.model]"
20
- :read-only="readOnly"
21
- :disabled="disabled && !readOnly"
22
- :whitespace="true"
23
- style="flex: 1; width: auto; min-width: 0;"
24
- @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
25
- :suffix="attr.inputSuffix && mode !== '新增' ? attr.inputSuffix : ''"
26
- @blur="attr.inputOnBlurFunc && emitFunc(attr.inputOnBlurFunc,attr)"
27
- @keyup.enter="attr.inputOnEnterFunc && emitFunc(attr.inputOnEnterFunc, attr)"
28
- :placeholder="attr.placeholder ? attr.placeholder : '请输入'+attr.name.replace(/\s*/g, '')"
29
- :ref="`${attr.model}input`"/>
30
- <a-button
31
- v-if="attr.inputOnAfterName && attr.inputOnAfterFunc"
32
- style="flex: 1; width: auto; min-width: 4rem;max-width: 6rem"
33
- type="primary"
34
- @click="emitFunc(attr.inputOnAfterFunc,form[attr.model])">
35
- {{ attr.inputOnAfterName }}
36
- </a-button>
37
- <!-- 仅可以配置 一个按钮 以及 一个图标插槽 -->
38
- <a-button
39
- style="width: 2rem; flex-shrink: 0;"
40
- v-if="attr.inputOnAfterIcon"
41
- :type="attr.inputOnAfterIcon && attr.inputOnAfterName ? 'primary' :''"
42
- :icon="attr.inputOnAfterIcon || 'question'"
43
- @click="emitFunc(attr.inputOnAfterIconFunc,form[attr.model])">
44
- </a-button>
45
- </a-input-group>
46
- <a-input-number
47
- v-else-if="attr.numberInput && !readOnly"
48
- v-model="form[attr.model]"
49
- :whitespace="true"
50
- :disabled="disabled && !readOnly"
51
- style="width:100%"
52
- @blur="attr.inputOnBlurFunc && emitFunc(attr.inputOnBlurFunc,attr)"
53
- @keyup.enter="attr.inputOnEnterFunc && emitFunc(attr.inputOnEnterFunc, attr)"
54
- :suffix="attr.inputSuffix && mode !== '新增' ? attr.inputSuffix : ''"
55
- :placeholder="attr.placeholder ? attr.placeholder : '请输入'+attr.name.replace(/\s*/g, '')"
56
- :ref="`${attr.model}input`"/>
57
- <a-input
58
- v-else
59
- v-model="form[attr.model]"
60
- :whitespace="true"
61
- :read-only="readOnly"
62
- :disabled="disabled && !readOnly"
63
- :suffix="attr.inputSuffix && mode !== '新增' ? attr.inputSuffix : ''"
64
- style="width:100%"
65
- @blur="attr.inputOnBlurFunc && emitFunc(attr.inputOnBlurFunc,attr)"
66
- @keyup.enter="attr.inputOnEnterFunc && emitFunc(attr.inputOnEnterFunc, attr)"
67
- :placeholder="attr.placeholder ? attr.placeholder : '请输入'+attr.name.replace(/\s*/g, '')"
68
- :ref="`${attr.model}input`"/>
69
-
70
- </a-form-model-item>
71
- </x-form-col>
72
- <!-- 下拉框 -->
73
- <x-form-col
74
- v-else-if="(attr.type === 'select' || (attr.type === 'rate' && mode==='查询')) && show"
75
- :flex="attr.flex">
76
- <a-form-model-item
77
- :ref="attr.model"
78
- :label="showLabel?attr.name:undefined"
79
- :prop="attr.prop ? attr.prop : attr.model">
80
- <a-select
81
- v-if="!attr.lazyLoad || attr.lazyLoad === 'false'"
82
- v-model="form[attr.model]"
83
- :disabled="disabled"
84
- @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
85
- :filter-option="filterOption"
86
- :getPopupContainer=" triggerNode => { return triggerNode.parentNode } "
87
- :placeholder="attr.placeholder ? attr.placeholder : '请选择'"
88
- show-search
89
- >
90
- <a-select-option
91
- v-if="mode === '查询'"
92
- key="999999"
93
- value="">全部
94
- </a-select-option>
95
- <template v-if="attr.keys">
96
- <a-select-option
97
- v-for="(item,index) in attr.keys"
98
- :key="index.value"
99
- :value="item.value">
100
- {{ item.label }}
101
- </a-select-option>
102
- </template>
103
- <template v-else>
104
- <template
105
- v-if="attr.keyName.indexOf('logic@') !== -1 || attr.keyName.indexOf('config@') !== -1
106
- ||attr.keyName.indexOf('search@') !== -1 || attr.keyName.indexOf('search@') !== -1">
107
- <a-select-option
108
- v-for="(item,index) in option"
109
- :key="index.value"
110
- :value="item.value">
111
- <template v-if="attr.keyName.indexOf('config@') !== -1 && item.status">
112
- <!-- 徽标(badge) -->
113
- <a-badge v-if="item.status !== 'gary'" :color="item.status" :text="item.label"/>
114
- <a-badge v-else color="#D9D9D9" :text="item.label"/>
115
- </template>
116
- <template v-else>
117
- {{ item.label }}
118
- </template>
119
- </a-select-option>
120
- </template>
121
- <template
122
- v-else-if="attr.keyName.indexOf('async ') !== -1 || attr.keyName.indexOf('function ') !== -1">
123
- <a-select-option
124
- v-for="(item,index) in optionForFunc"
125
- :key="index.value"
126
- :value="item.value">
127
- <template>
128
- {{ item.label }}
129
- </template>
130
- </a-select-option>
131
- </template>
132
- <template v-else>
133
- <a-select-option
134
- v-for="item in $appdata.getDictionaryList(attr.keyName)"
135
- :key="item.value"
136
- :value="item.value">
137
- <!-- 徽标(badge) -->
138
- <x-badge
139
- :badge-key="attr.keyName"
140
- :replaceText="item.text"
141
- :value="item.value"
142
- :service-name="serviceName"
143
- :env="env"/>
144
- </a-select-option>
145
- </template>
146
- </template>
147
- </a-select>
148
- <a-select
149
- v-else
150
- v-model="form[attr.model]"
151
- :disabled="disabled"
152
- @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
153
- :filter-option="filterOption"
154
- :getPopupContainer=" triggerNode => { return triggerNode.parentNode } "
155
- :placeholder="attr.placeholder ? attr.placeholder : '搜索' + attr.name"
156
- show-search
157
- @search="fetchFunction"
158
- >
159
- <a-spin v-if="searching" slot="notFoundContent" size="small"/>
160
- <a-select-option
161
- v-if="mode === '查询'"
162
- key="999999"
163
- value="">全部
164
- </a-select-option>
165
- <a-select-option
166
- v-for="(item,index) in option"
167
- :key="index"
168
- :value="item.value">{{ item.label }}
169
- </a-select-option>
170
- </a-select>
171
- </a-form-model-item>
172
- </x-form-col>
173
- <!-- 多选框 -->
174
- <x-form-col
175
- v-else-if="attr.type === 'checkbox' && show"
176
- :flex="attr.flex">
177
- <a-form-model-item
178
- :ref="attr.model"
179
- :label="showLabel?attr.name:undefined"
180
- :prop="attr.prop ? attr.prop : attr.model">
181
- <a-select
182
- v-if="!attr.lazyLoad || attr.lazyLoad === 'false'"
183
- v-model="form[attr.model]"
184
- :disabled="disabled"
185
- :filter-option="filterOption"
186
- :getPopupContainer=" triggerNode => { return triggerNode.parentNode } "
187
- :placeholder="attr.placeholder ? attr.placeholder : '请选择'"
188
- @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
189
- mode="multiple"
190
- show-search
191
- allowClear
192
- >
193
- <template v-if="attr.keys">
194
- <a-select-option
195
- v-for="(item,index) in attr.keys"
196
- :key="index"
197
- :value="item.value">
198
- {{ item.label }}
199
- </a-select-option>
200
- </template>
201
- <template v-else>
202
- <template
203
- v-if="attr.keyName.indexOf('logic@') !== -1 || attr.keyName.indexOf('config@') !== -1
204
- ||attr.keyName.indexOf('search@') !== -1 || attr.keyName.indexOf('search@') !== -1">
205
- <a-select-option
206
- v-for="(item,index) in option"
207
- :key="index"
208
- :value="item.value">{{ item.label }}
209
- </a-select-option>
210
- </template>
211
- <template v-else>
212
- <a-select-option
213
- v-for="item in $appdata.getDictionaryList(attr.keyName)"
214
- :key="item.value"
215
- :value="item.value">{{ item.text }}
216
- </a-select-option>
217
- </template>
218
- </template>
219
- </a-select>
220
- <a-select
221
- v-else
222
- v-model="form[attr.model]"
223
- :disabled="disabled"
224
- :filter-option="filterOption"
225
- :getPopupContainer=" triggerNode => { return triggerNode.parentNode } "
226
- :placeholder="attr.placeholder ? attr.placeholder : '搜索' + attr.name"
227
- mode="multiple"
228
- @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
229
- show-search
230
- allowClear
231
- @search="fetchFunction"
232
- >
233
- <a-spin v-if="searching" slot="notFoundContent" size="small"/>
234
- <a-select-option
235
- v-for="(item,index) in option"
236
- :key="index"
237
- :value="item.value">{{ item.label }}
238
- </a-select-option>
239
- </a-select>
240
- </a-form-model-item>
241
- </x-form-col>
242
- <!-- 单选框 -->
243
- <x-form-col
244
- v-else-if="attr.type === 'radio' && show"
245
- :flex="attr.flex">
246
- <a-form-model-item
247
- :ref="attr.model"
248
- :label="showLabel?attr.name:undefined"
249
- :prop="attr.prop ? attr.prop : attr.model">
250
- <a-radio-group
251
- v-model="form[attr.model]"
252
- @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
253
- >
254
- <template v-if="attr.keys">
255
- <a-radio v-for="(item,index) in attr.keys" :key="index" :value="item.value">
256
- {{ item.label }}
257
- </a-radio>
258
- </template>
259
- <template v-else>
260
- <template
261
- v-if="attr.keyName.indexOf('logic@') !== -1 || attr.keyName.indexOf('config@') !== -1
262
- ||attr.keyName.indexOf('search@') !== -1 || attr.keyName.indexOf('search@') !== -1">
263
- <a-radio v-for="(item,index) in option" :key="index" :value="item.value">
264
- {{ item.label }}
265
- </a-radio>
266
- </template>
267
- <template v-else>
268
- <a-radio v-for="(item,index) in $appdata.getDictionaryList(attr.keyName)" :key="index" :value="item.value">
269
- {{ item.text }}
270
- </a-radio>
271
- </template>
272
- </template>
273
- </a-radio-group>
274
- </a-form-model-item>
275
- </x-form-col>
276
- <!-- 日期范围选择器 -->
277
- <x-form-col
278
- v-else-if="attr.type === 'rangePicker' && show"
279
- :flex="attr.flex">
280
- <a-form-model-item
281
- :ref="attr.model"
282
- :label="showLabel?attr.name:undefined"
283
- :prop="attr.prop ? attr.prop : attr.model">
284
- <a-date-picker
285
- @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
286
- v-if="mode === '新增/修改'"
287
- v-model="form[attr.model]"
288
- :disabled="disabled"
289
- :show-time="true"
290
- style="width: 100%;"
291
- valueFormat="YYYY-MM-DD HH:mm:ss"/>
292
- <a-range-picker
293
- v-else
294
- @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
295
- v-model="form[attr.model]"
296
- :disabled="disabled"
297
- :show-time="true"
298
- valueFormat="YYYY-MM-DD HH:mm:ss"
299
- style="width: 100%;"
300
- />
301
- </a-form-model-item>
302
- </x-form-col>
303
- <!-- 月份选择器 -->
304
- <x-form-col
305
- v-else-if="attr.type === 'monthPicker' && show"
306
- :flex="attr.flex">
307
- <a-form-model-item
308
- :ref="attr.model"
309
- :label="showLabel?attr.name:undefined"
310
- :prop="attr.prop ? attr.prop : attr.model">
311
- <a-month-picker
312
- @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
313
- v-model="form[attr.model]"
314
- :disabled="disabled"
315
- :show-time="true"
316
- valueFormat="YYYY-MM"
317
- style="width: 100%;"
318
- />
319
- </a-form-model-item>
320
- </x-form-col>
321
- <!-- 年份选择器 -->
322
- <x-form-col
323
- v-else-if="attr.type === 'yearPicker' && show"
324
- :flex="attr.flex">
325
- <a-form-model-item
326
- :ref="attr.model"
327
- :label="showLabel?attr.name:undefined"
328
- :prop="attr.prop ? attr.prop : attr.model">
329
- <a-date-picker
330
- @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
331
- v-model="form[attr.model]"
332
- :disabled="disabled"
333
- format="YYYY"
334
- mode="year"
335
- v-decorator="['year']"
336
- placeholder="请选择年份"
337
- :open="yearShowOne"
338
- style="width: 100%;"
339
- @openChange="openChangeOne"
340
- @panelChange="panelChangeOne"/>
341
- </a-form-model-item>
342
- </x-form-col>
343
- <!-- 单日选择器 -->
344
- <x-form-col
345
- v-else-if="attr.type === 'datePicker' && show"
346
- :flex="attr.flex">
347
- <a-form-model-item
348
- :ref="attr.model"
349
- :label="showLabel?attr.name:undefined"
350
- :prop="attr.prop ? attr.prop : attr.model">
351
- <a-range-picker
352
- @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
353
- v-if="mode === '查询' && attr.queryType === 'BETWEEN' "
354
- v-model="form[attr.model]"
355
- :disabled="disabled"
356
- :show-time="true"
357
- style="width: 100%;"
358
- format="YYYY-MM-DD"
359
- valueFormat="YYYY-MM-DD HH:mm:ss"/>
360
- <a-date-picker
361
- @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
362
- v-else-if="mode === '查询'"
363
- v-model="form[attr.model]"
364
- :disabled="disabled"
365
- style="width: 100%;"
366
- valueFormat="YYYY-MM-DD"/>
367
- <a-date-picker
368
- v-else
369
- @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
370
- v-model="form[attr.model]"
371
- :disabled="disabled"
372
- style="width: 100%;"
373
- :show-time="{ defaultValue: moment('00:00:00', 'HH:mm:ss') }"
374
- valueFormat="YYYY-MM-DD HH:mm:ss"/>
375
- </a-form-model-item>
376
- </x-form-col>
377
- <!-- 文本域 -->
378
- <a-col
379
- v-else-if="attr.type === 'textarea' && show"
380
- :style="layout === 'inline'?{width:'calc(100% - 60px)'}:{}"
381
- :xs="24"
382
- :sm="24"
383
- :md="24"
384
- :lg="24"
385
- :xl="24"
386
- :xxl="24">
387
- <a-form-model-item
388
- :labelCol="layout === 'inline'?{span:2}:undefined"
389
- :wrapperCol="layout === 'inline'?{span:22}:undefined"
390
- :ref="attr.model"
391
- :label="showLabel?attr.name:undefined"
392
- :prop="attr.prop ? attr.prop : attr.model">
393
- <a-textarea
394
- v-model="form[attr.model]"
395
- style="width: 100%;"
396
- :disabled="disabled"
397
- :placeholder="attr.placeholder ? attr.placeholder : '请输入'+attr.name.replace(/\s*/g, '')"
398
- :rows="4"/>
399
- </a-form-model-item>
400
- </a-col>
401
- <!-- 文件上传 -->
402
- <a-col
403
- v-else-if="(attr.type === 'file' || attr.type === 'image') && show"
404
- :style="layout === 'inline'?{width:'calc(100% - 60px)'}:{}"
405
- :xs="24"
406
- :sm="24"
407
- :md="24"
408
- :lg="24"
409
- :xl="24"
410
- :xxl="24">
411
- <a-form-model-item
412
- :labelCol="layout === 'inline'?{span:2}:undefined"
413
- :wrapperCol="layout === 'inline'?{span:22}:undefined"
414
- :ref="attr.model"
415
- :label="showLabel?attr.name:undefined"
416
- :prop="attr.prop ? attr.prop : attr.model">
417
- <upload
418
- :files="files"
419
- :images="images"
420
- :model="attr"
421
- :uploadStyle="attr.uploadStyle"
422
- :service-name="serviceName"
423
- @setFiles="setFiles"></upload>
424
- </a-form-model-item>
425
- </a-col>
426
- <!-- 省市区选择框 -->
427
- <x-form-col
428
- v-else-if="attr.type === 'citySelect' && show"
429
- :flex="attr.flex">
430
- <a-form-model-item
431
- :ref="attr.model"
432
- :label="showLabel?attr.name:undefined"
433
- :prop="attr.prop ? attr.prop : attr.model">
434
- <citySelect
435
- @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
436
- ref="citySelect"
437
- v-model="form[attr.model]"
438
- :contexts="attr.contexts"
439
- :value-type="attr.valueType"
440
- :default-value="form[attr.model]"></citySelect>
441
- </a-form-model-item>
442
- </x-form-col>
443
- <!-- 地点搜索框 -->
444
- <x-form-col
445
- v-else-if="attr.type === 'addressSearch' && show"
446
- :flex="attr.flex">
447
- <a-form-model-item
448
- :ref="attr.model"
449
- :label="showLabel?attr.name:undefined"
450
- :prop="attr.prop ? attr.prop : attr.model"
451
- :labelCol="layout === 'inline' && attr.occupyCol ? labelAndWrapperCol[attr.occupyCol].labelCol:undefined"
452
- :wrapperCol="layout === 'inline'&& attr.occupyCol ? labelAndWrapperCol[attr.occupyCol].wrapperCol:undefined"
453
- :style="layout === 'inline'&& attr.occupyCol && attr.occupyCol > 1? {width:`calc(100% - ${attr.occupyCol * 1.533}rem)`}:{}">
454
- <address-search-combobox
455
- :emitFunc="emitFunc"
456
- :attr="attr"
457
- :read-only="readOnly"
458
- v-model="searchResult"
459
- :resultKeys="{ address: attr.model, coords: `${attr.model}_lng_lat` }"
460
- ref="addressSearchCombobox"
461
- searchResultType="Object"
462
- @onSelect="addressSearchComboboxSelect"
463
- @onDivisionsChange="onDivisionsChange"
464
- ></address-search-combobox>
465
- </a-form-model-item>
466
- </x-form-col>
467
- <!-- 富文本 -->
468
- <x-form-col
469
- v-else-if="attr.type === 'richText' && show"
470
- :flex="attr.flex">
471
- <a-form-model-item :ref="attr.model" :prop="attr.prop ? attr.prop : attr.model">
472
- <RichTextModal ref="richTextModal" style="height: 500px"></RichTextModal>
473
- </a-form-model-item>
474
- </x-form-col>
475
- <!-- 人员选择框 -->
476
- <x-form-col
477
- v-else-if="attr.type === 'personSetting' && show"
478
- :flex="attr.flex">
479
- <a-form-model-item
480
- :ref="attr.model"
481
- :label="showLabel?attr.name:undefined"
482
- :prop="attr.prop ? attr.prop : attr.model">
483
- <PersonSetting v-model="form[attr.model]"></PersonSetting>
484
- </a-form-model-item>
485
- </x-form-col>
486
- <!-- 树形选择框 -->
487
- <x-form-col
488
- v-else-if="attr.type === 'treeSelect' && show"
489
- :flex="attr.flex">
490
- <x-tree-select
491
- @onChange="attr.dataChangeFunc && debouncedDataChangeFunc()"
492
- v-model="form[attr.model]"
493
- :attr="attr"
494
- ref="xTreeSelect">
495
- </x-tree-select>
496
- </x-form-col>
497
- <!-- 评分框 -->
498
- <x-form-col
499
- v-else-if="attr.type === 'rate' && show"
500
- :flex="attr.flex">
501
- <a-form-model-item
502
- :ref="attr.model"
503
- :label="showLabel?attr.name:undefined"
504
- :prop="attr.prop ? attr.prop : attr.model">
505
- <a-rate
506
- v-model="form[attr.model]"
507
- @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
508
- />
509
- </a-form-model-item>
510
- </x-form-col>
511
- <!-- 区间选择器 -->
512
- <x-form-col
513
- v-else-if="attr.type === 'intervalPicker' && show"
514
- :flex="attr.flex">
515
- <a-form-model-item
516
- :ref="attr.model"
517
- :label="showLabel?attr.name:undefined"
518
- :prop="attr.prop ? attr.prop : attr.model">
519
- <a-input
520
- v-if="mode === '新增/修改'"
521
- v-model="form[attr.model]"
522
- :whitespace="true"
523
- :read-only="readOnly"
524
- :disabled="disabled && !readOnly"
525
- style="width:100%"
526
- @blur="attr.inputOnBlurFunc && emitFunc(attr.inputOnBlurFunc,attr)"
527
- :placeholder="attr.placeholder ? attr.placeholder : '请输入'+attr.name.replace(/\s*/g, '')"
528
- :ref="`${attr.model}input`"/>
529
- <a-input-group v-else compact>
530
- <a-input
531
- v-model="form[attr.model][0]"
532
- class="intervalPicker-begin"
533
- placeholder="起始值"/>
534
- <a-input
535
- class="intervalPicker-center"
536
- style="backgroundColor: #fff"
537
- placeholder="~"
538
- disabled
539
- />
540
- <a-input
541
- v-model="form[attr.model][1]"
542
- class="intervalPicker-end"
543
- placeholder="结束值"/>
544
- </a-input-group>
545
- </a-form-model-item>
546
- </x-form-col>
547
- <!-- 车牌号选择 -->
548
- <x-form-col
549
- v-else-if="attr.type === 'licensePlate' && show"
550
- :flex="attr.flex">
551
- <a-form-model-item
552
- :ref="attr.model"
553
- :label="showLabel?attr.name:undefined"
554
- :style="layout === 'inline'&& attr.occupyCol && attr.occupyCol > 1? {width:`calc(100% - ${attr.occupyCol * 1.533}rem)`}:{}"
555
- :prop="attr.prop ? attr.prop : attr.model">
556
- <!-- 如果配置了后置按钮插槽 -->
557
- <a-input
558
- v-if="mode ==='查询'"
559
- v-model="form[attr.model]"
560
- :whitespace="true"
561
- :read-only="readOnly"
562
- :disabled="disabled && !readOnly"
563
- style="width:100%"
564
- @blur="attr.inputOnBlurFunc && emitFunc(attr.inputOnBlurFunc,attr)"
565
- :placeholder="attr.placeholder ? attr.placeholder : '请输入'+attr.name.replace(/\s*/g, '')"
566
- :ref="`${attr.model}input`"/>
567
- <x-license-plate
568
- v-else
569
- v-model="form[attr.model]"
570
- @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
571
- ></x-license-plate>
572
- </a-form-model-item>
573
- </x-form-col>
574
- </template>
575
- <script>
576
-
577
- import { debounce } from 'ant-design-vue/lib/vc-table/src/utils'
578
- import XFormCol from '@vue2-client/base-client/components/common/XFormCol'
579
- import XBadge from '@vue2-client/base-client/components/common/XBadge'
580
- import CitySelect from '@vue2-client/base-client/components/common/CitySelect'
581
- import PersonSetting from '@vue2-client/base-client/components/common/PersonSetting'
582
- import AddressSearchCombobox from '@vue2-client/base-client/components/common/AddressSearchCombobox'
583
- import Upload from '@vue2-client/base-client/components/common/Upload'
584
- import moment from 'moment'
585
- import { upload, getConfigByName, runLogic, getConfigByNameAsync } from '@vue2-client/services/api/common'
586
- import util, { uuid } from '.././../../../utils/util'
587
- import XTreeSelect from '@vue2-client/base-client/components/common/XForm/XTreeSelect'
588
- import { searchToListOption, searchToOption } from '@vue2-client/services/v3Api'
589
- import { mapState } from 'vuex'
590
- import { executeStrFunction } from '@vue2-client/utils/runEvalFunction'
591
- import RichTextModal from '../richTextModal/index.vue'
592
- import XLicensePlate from '@vue2-client/base-client/components/common/XLicensePlate/XLicensePlate.vue'
593
-
594
- export default {
595
- name: 'XFormItem',
596
- components: {
597
- XLicensePlate,
598
- XTreeSelect,
599
- XFormCol,
600
- XBadge,
601
- CitySelect,
602
- PersonSetting,
603
- AddressSearchCombobox,
604
- Upload,
605
- RichTextModal
606
- },
607
- data () {
608
- // 检索去抖
609
- this.fetchFunction = debounce(this.fetchFunction, 800)
610
- return {
611
- option: [],
612
- // 最后检索版本
613
- lastFetchId: 0,
614
- // 检索中
615
- searching: false,
616
- searchResult: '',
617
- yearShowOne: false,
618
- optionForFunc: [],
619
- // 控制当前表单项是否展示
620
- show: true,
621
- labelAndWrapperCol: [{
622
- labelCol: undefined,
623
- wrapperCol: undefined
624
- },
625
- {
626
- labelCol: undefined,
627
- wrapperCol: undefined
628
- },
629
- {
630
- labelCol: { span: 3 },
631
- wrapperCol: { span: 21 }
632
- },
633
- {
634
- labelCol: { span: 2 },
635
- wrapperCol: { span: 22 }
636
- }],
637
- // moment
638
- moment
639
- }
640
- },
641
- props: {
642
- attr: {
643
- type: Object,
644
- default:
645
- () => {
646
- return {}
647
- }
648
- },
649
- form: {
650
- type: Object,
651
- required:
652
- true
653
- },
654
- disabled: {
655
- type: Boolean,
656
- default:
657
- () => {
658
- return false
659
- }
660
- },
661
- readOnly: {
662
- type: Boolean,
663
- default:
664
- () => {
665
- return false
666
- }
667
- },
668
- mode: {
669
- type: String,
670
- default:
671
- () => {
672
- return '查询'
673
- }
674
- },
675
- files: {
676
- type: Array,
677
- default:
678
- () => {
679
- return []
680
- }
681
- },
682
- images: {
683
- type: Array,
684
- default:
685
- () => {
686
- return []
687
- }
688
- },
689
- serviceName: {
690
- type: String,
691
- default:
692
- undefined
693
- },
694
- // 调用logic获取数据源的追加参数
695
- getDataParams: {
696
- type: Object,
697
- default:
698
- undefined
699
- },
700
- // 布局
701
- layout: {
702
- type: String,
703
- default:
704
- 'horizontal'
705
- },
706
- // 环境
707
- env: {
708
- type: String,
709
- default:
710
- () => {
711
- return 'prod'
712
- }
713
- },
714
- // 设置表单值
715
- setForm: {
716
- type: Function,
717
- default: (val) => {
718
- console.log(val)
719
- }
720
- },
721
- showLabel: {
722
- type: Boolean,
723
- default:
724
- () => {
725
- return true
726
- }
727
- }
728
- },
729
- async created () {
730
- this.init()
731
- if (this.attr.keyName && (this.attr?.keyName?.toString().indexOf('async ') !== -1 || this.attr?.keyName?.toString()?.indexOf('function') !== -1)) {
732
- this.debouncedUpdateOptions = debounce(this.updateOptions, 200)
733
- }
734
- if (this.attr.dataChangeFunc) {
735
- this.debouncedDataChangeFunc = debounce(this.dataChangeFunc, 200)
736
- }
737
- if (this.attr.showFormItemFunc) {
738
- this.debouncedShowFormItemFunc = debounce(this.showFormItemFunc, 100)
739
- // 执行一次
740
- debounce(this.showFormItemFunc, 100)()
741
- }
742
- if (this.attr.showQueryFormItemFunc) {
743
- this.debouncedShowQueryFormItemFunc = debounce(this.showQueryFormItemFunc, 100)
744
- // 执行一次
745
- debounce(this.showQueryFormItemFunc, 100)()
746
- }
747
- // 人员联动框增加监听
748
- if (this?.attr?.keyName?.toString()?.startsWith('search@根据表单项[') && this?.attr?.keyName?.toString().endsWith(']联动人员')) {
749
- this.debouncedUserLinkFunc = debounce(() => this.updateResOptions('人员'), 200)
750
- }
751
- if (this?.attr?.keyName?.toString()?.startsWith('search@根据表单项[') && this?.attr?.keyName?.toString().endsWith(']联动部门')) {
752
- this.debouncedDepLinkFunc = debounce(() => this.updateResOptions('部门'), 200)
753
- }
754
- },
755
- computed: {
756
- ...mapState('account', { currUser: 'user' })
757
- },
758
- watch: {
759
- attr: {
760
- handler () {
761
- this.init()
762
- },
763
- deep: true
764
- },
765
- form: {
766
- handler (newVal, oldVal) {
767
- // 如果是从函数获取 options
768
- if (this.attr.keyName && (this.attr.keyName.toString().indexOf('async ') !== -1 || this.attr.keyName.toString().indexOf('function') !== -1)) {
769
- this.debouncedUpdateOptions()
770
- }
771
- // 如果有自定义是否展示表单项函数
772
- if (this.attr.showFormItemFunc) {
773
- this.debouncedShowFormItemFunc()
774
- }
775
- // 如果有自定义是否展示查询表单项函数
776
- if (this.attr.showQueryFormItemFunc) {
777
- this.debouncedShowQueryFormItemFunc()
778
- }
779
- // 地址搜索框赋值
780
- if (this.attr.type === 'addressSearch') {
781
- this.$refs.addressSearchCombobox.addressInput = this.form[this.attr.model]
782
- }
783
- // 数据源来自人员联动时更新数据
784
- if (this?.attr?.keyName?.toString()?.startsWith('search@根据表单项[') && this?.attr?.keyName?.toString().endsWith(']联动人员')) {
785
- this.debouncedUserLinkFunc()
786
- }
787
- // 数据源来自人员联动时更新数据
788
- if (this?.attr?.keyName?.toString()?.startsWith('search@根据表单项[') && this?.attr?.keyName?.toString().endsWith(']联动部门')) {
789
- this.debouncedDepLinkFunc()
790
- }
791
- },
792
- deep: true
793
- }
794
- },
795
- methods: {
796
- focusInput () {
797
- if (this.attr.defaultFocus) {
798
- this.$nextTick(h => {
799
- const el = this.$refs[`${this.attr.model}input`]?.$el
800
- let inputEl
801
- if (el) {
802
- if (el.tagName.toLowerCase() === 'input') {
803
- inputEl = el
804
- } else {
805
- inputEl = el.querySelector('input')
806
- }
807
- }
808
- if (inputEl) {
809
- inputEl.focus()
810
- if (inputEl.type === 'number') {
811
- if (inputEl.valueAsNumber) {
812
- inputEl.setSelectionRange(0, inputEl.valueAsNumber.toString().length)
813
- }
814
- } else {
815
- if (inputEl.value) {
816
- inputEl.setSelectionRange(0, inputEl.value.length)
817
- }
818
- }
819
- }
820
- })
821
- }
822
- },
823
- // 更新人员下拉框数据
824
- async updateResOptions (type) {
825
- if (this?.attr?.keyName?.toString()?.startsWith('search@根据表单项[') && this?.attr?.keyName?.toString()?.endsWith(`]联动${type}`)) {
826
- const searchData = { source: `获取${type}`, userid: this.currUser.id }
827
- const startIndex = this.attr.keyName.indexOf('[') + 1
828
- const endIndex = this.attr.keyName.indexOf(']', startIndex)
829
- const fromModel = this.attr.keyName.substring(startIndex, endIndex).replace('.', '_')
830
- const formModelData = this.form[fromModel]
831
- if (fromModel?.length && formModelData?.length) {
832
- await searchToListOption(searchData, res => {
833
- this.getDataCallback(
834
- res.filter(h => {
835
- if (fromModel.indexOf('org') > -1) {
836
- return formModelData?.includes(h.orgid || h.f_organization_id || h.parentid)
837
- } else {
838
- return formModelData?.includes(h?.parentid)
839
- }
840
- }
841
- )
842
- )
843
- })
844
- }
845
- }
846
- },
847
- // js 函数作为数据源
848
- async updateOptions () {
849
- if (this.attr.keyName && (this.attr.keyName.indexOf('async ') !== -1 || this.attr.keyName.indexOf('function ') !== -1)) {
850
- this.optionForFunc = await executeStrFunction(this.attr.keyName, [this.form, runLogic, this.mode, getConfigByNameAsync])
851
- }
852
- },
853
- async dataChangeFunc () {
854
- if (this.attr.dataChangeFunc) {
855
- await executeStrFunction(this.attr.dataChangeFunc, [this.form, this.setForm, this.attr, util, this.mode, runLogic, getConfigByNameAsync])
856
- }
857
- },
858
- async showFormItemFunc () {
859
- if (this.attr.showFormItemFunc) {
860
- const obj = executeStrFunction(this.attr.showFormItemFunc, [this.form, this.setForm, this.attr, util, this.mode])
861
- // 判断是 bool 还是 obj 兼容
862
- if (typeof obj === 'boolean') {
863
- this.show = obj
864
- } else if (obj && typeof obj === 'object') {
865
- // obj 是一个对象,并且不是数组
866
- this.show = obj?.show
867
- this.readOnly = obj?.readOnly
868
- }
869
- } else {
870
- this.show = true
871
- }
872
- },
873
- async showQueryFormItemFunc () {
874
- if (this.attr.showQueryFormItemFunc) {
875
- const obj = executeStrFunction(this.attr.showQueryFormItemFunc, [this.form, this.setForm, this.attr, util, this.mode])
876
- // 判断是 bool 还是 obj 兼容
877
- if (typeof obj === 'boolean') {
878
- this.show = obj
879
- } else if (obj && typeof obj === 'object') {
880
- // obj 是一个对象,并且不是数组
881
- this.show = obj?.show
882
- this.readOnly = obj?.readOnly
883
- }
884
- } else {
885
- this.show = true
886
- }
887
- },
888
- init () {
889
- if (this.mode === '新增/修改' && !this.attr.flex) {
890
- if (['horizontal', 'vertical'].includes(this.layout)) {
891
- // 新增修改表单 horizontal 模式下默认为一行
892
- this.attr.flex = {
893
- xs: 24,
894
- sm: 24,
895
- md: 24,
896
- lg: 24,
897
- xl: 24,
898
- xxl: 24
899
- }
900
- } else {
901
- if (['input', 'addressSearch'] && this.attr.occupyCol) {
902
- // 如果是 input 看是否配置了 占用列配置
903
- this.attr.flex = {
904
- xs: 8 * this.attr.occupyCol,
905
- sm: 8 * this.attr.occupyCol,
906
- md: 8 * this.attr.occupyCol,
907
- lg: 8 * this.attr.occupyCol,
908
- xl: 8 * this.attr.occupyCol,
909
- xxl: 8 * this.attr.occupyCol
910
- }
911
- } else {
912
- // 新增修改表单 vertical 模式下默认为1列
913
- this.attr.flex = {
914
- xs: 24,
915
- sm: 24,
916
- md: 24,
917
- lg: 12,
918
- xl: 8,
919
- xxl: 8
920
- }
921
- }
922
- }
923
- } else {
924
- this.attr.flex = {
925
- xs: 24,
926
- sm: 24,
927
- md: 24,
928
- lg: 8,
929
- xl: 6,
930
- xxl: 6
931
- }
932
- }
933
- if (this.attr.type === 'radio') {
934
- this.initRadioValue()
935
- } else if (this.attr.type === 'richText') {
936
- this.initRichText()
937
- } else if (this.attr.keyName && typeof this.attr.keyName === 'string') {
938
- if (this.attr.keyName.indexOf('logic@') !== -1) {
939
- this.getData({}, res => this.getDataCallback(res))
940
- } else if (this.attr.keyName.indexOf('search@') !== -1) {
941
- // `tool.getFullTree(this.getRights().where(row.getType()==$organization$))`
942
- // 判断是否根据角色查询
943
- let source = this.attr.keyName.substring(7)
944
- const userid = this.currUser.id
945
- let roleName = 'roleName'
946
- if (source.startsWith('根据角色[') && source.endsWith(']获取人员')) {
947
- const startIndex = source.indexOf('[') + 1
948
- const endIndex = source.indexOf(']', startIndex)
949
- roleName = source.substring(startIndex, endIndex)
950
- source = '根据角色获取人员'
951
- }
952
- const searchData = { source, userid, roleName }
953
- // 判断是否根据某个表单项联动 仅返回列表结构并筛选
954
- if (source.startsWith('根据表单项[') && source.endsWith(']联动人员')) {
955
- this.updateResOptions('人员')
956
- } else if (source.startsWith('根据表单项[') && source.endsWith(']联动部门')) {
957
- this.updateResOptions('部门')
958
- } else if (this.attr.type === 'select' || this.attr.type === 'checkbox') {
959
- // 仅获取最内层数据
960
- searchToListOption(searchData, res => this.getDataCallback(res))
961
- } else {
962
- // 其他资源通用逻辑
963
- searchToOption(searchData, res => this.getDataCallback(res))
964
- }
965
- } else if (this.attr.keyName.indexOf('config@') !== -1) {
966
- const configName = this.attr.keyName.substring(7)
967
- getConfigByName(configName, this.serviceName, res => {
968
- this.getDataCallback(res.value)
969
- }, this.env === 'dev')
970
- } else if (this.attr.keyName.indexOf('async ') !== -1 || this.attr.keyName.indexOf('function ') !== -1) {
971
- this.updateOptions()
972
- }
973
- }
974
- this.focusInput()
975
- },
976
- addressSearchComboboxSelect (data) {
977
- this.form = Object.assign(this.form, JSON.parse(data))
978
- },
979
- onDivisionsChange (data) {
980
- this.emitFunc('addressSearchComboboxSelect', {
981
- key: this.attr.model,
982
- value: data
983
- })
984
- },
985
- getDataCallback (res) {
986
- this.option = res
987
- if (this.attr.type === 'treeSelect') {
988
- this.$refs.xTreeSelect.init({
989
- option: this.option,
990
- form: this.form,
991
- queryType: this.attr.queryType,
992
- name: this.attr.name,
993
- model: this.attr.model,
994
- mode: this.mode,
995
- disabled: this.disabled
996
- })
997
- } else if (this.attr.type === 'radio') {
998
- this.initRadioValue()
999
- }
1000
- },
1001
- initRadioValue () {
1002
- const model = this.attr.model
1003
- if (this.mode === '新增/修改' && this.attr.type === 'radio' && !this.form[model] && !this.attr.prop) {
1004
- if (this.attr.keys && this.attr.keys.length > 0) {
1005
- this.form[model] = this.attr.keys[0].value
1006
- } else if (this.option && this.option.length > 0) {
1007
- this.form[model] = this.option[0].value
1008
- } else if (this.attr.keyName) {
1009
- const list = this.$appdata.getDictionaryList(this.attr.keyName)
1010
- if (list.length > 0) {
1011
- this.form[model] = list[0].value
1012
- }
1013
- }
1014
- }
1015
- },
1016
- async initRichText () {
1017
- const logicName = this.attr.keyName
1018
- if (logicName) {
1019
- this.getData({}, async res => {
1020
- try {
1021
- const response = await fetch(res.url) // 等待 fetch 完成
1022
- if (response.ok) {
1023
- const data = await response.text() // 等待解析为文本内容
1024
- const richText = JSON.parse(data)
1025
- this.$refs.richTextModal.init({
1026
- richText: richText
1027
- })
1028
- } else {
1029
- this.$message.error('富文本读取失败,请求结果:' + response.statusText)
1030
- }
1031
- } catch (error) {
1032
- this.$message.error('富文本读取失败,请求结果:' + error)
1033
- }
1034
- })
1035
- }
1036
- },
1037
- async getRichValue () {
1038
- if (this.$refs.richTextModal) {
1039
- const richText = this.$refs.richTextModal.getValue()
1040
- console.log('>>>> richText: ', richText)
1041
- const fileContent = JSON.stringify(richText)
1042
- const fileName = uuid() + '.txt'
1043
- // 创建一个 Blob 对象,类型为 text/plain
1044
- const blob = new Blob([fileContent], { type: 'text/plain' })
1045
- // 创建一个 File 对象(可选,但有助于保持一致性,因为 File 继承自 Blob)
1046
- const file = new File([blob], fileName, { type: blob.type })
1047
- // 组装上传数据
1048
- const headers = {
1049
- 'Content-Type': 'multipart/form-data',
1050
- }
1051
- const formData = new FormData()
1052
- formData.append('avatar', file)
1053
- formData.append('resUploadMode', 'server')
1054
- formData.append('pathKey', 'Default')
1055
- formData.append('formType', 'file')
1056
- formData.append('useType', 'Default')
1057
- formData.append('filename', fileName)
1058
- formData.append('filesize', (blob.size / 1024 / 1024).toFixed(4))
1059
- formData.append('f_operator', this.currUser ? this.currUser.username : '')
1060
-
1061
- // 上传文件
1062
- await upload(formData, this.serviceName, { headers, timeout: 600 * 1000 }, this.env === 'dev').then(res => {
1063
- this.form[this.attr.model] = res.data.id
1064
- this.form.t_f_path = res.data.f_downloadpath
1065
- }).catch(error => {
1066
- // 处理上传错误
1067
- console.error(error)
1068
- })
1069
- }
1070
- },
1071
- openChangeOne (status) {
1072
- if (status) {
1073
- this.yearShowOne = true
1074
- }
1075
- },
1076
- // 得到年份选择器的值
1077
- panelChangeOne (value) {
1078
- this.yearShowOne = false
1079
- this.form[this.attr.model] = value.format('YYYY')
1080
- },
1081
- // 文件框时设置上传组件的值
1082
- setFiles (fileIds) {
1083
- if (!this.form[this.attr.model]) {
1084
- this.form[this.attr.model] = []
1085
- }
1086
- this.form[this.attr.model] = [...fileIds]
1087
- },
1088
- // 懒加载检索方法
1089
- fetchFunction (value) {
1090
- this.lastFetchId += 1
1091
- const fetchId = this.lastFetchId
1092
- this.option = []
1093
- this.searching = true
1094
- this.getData({
1095
- word: value
1096
- }, res => {
1097
- if (fetchId !== this.lastFetchId) {
1098
- return
1099
- }
1100
- this.option = res
1101
- this.searching = false
1102
- })
1103
- },
1104
- // 获取数据
1105
- getData (value, callbackFun) {
1106
- if (value !== '') {
1107
- const logicName = this.attr.keyName
1108
- const logic = logicName.substring(6)
1109
- // 调用logic前设置参数
1110
- if (this.getDataParams && this.getDataParams[this.attr.model]) {
1111
- Object.assign(value, this.getDataParams[this.attr.model])
1112
- }
1113
- runLogic(logic, Object.assign(value, {
1114
- orgId: this.currUser.orgid,
1115
- userId: this.currUser.id
1116
- }), this.serviceName, this.env === 'dev').then(res => {
1117
- callbackFun(res)
1118
- }).catch(e => {
1119
- callbackFun([])
1120
- console.error('获取数据失败:' + e)
1121
- })
1122
- }
1123
- },
1124
- filterOption (input, option) {
1125
- const child = option.componentOptions.children[0]
1126
- if (child.text) {
1127
- return child.text.toLowerCase().indexOf(input.toLowerCase()) >= 0
1128
- } else if (child.elm.innerText) {
1129
- return child.elm.innerText.toLowerCase().indexOf(input.toLowerCase()) >= 0
1130
- } else {
1131
- return child.child.value.toLowerCase().indexOf(input.toLowerCase()) >= 0
1132
- }
1133
- },
1134
- emitFunc (func, data) {
1135
- this.$emit('x-form-item-emit-func', func, data)
1136
- }
1137
- }
1138
- }
1139
- </script>
1140
-
1141
- <style lang="less" scoped>
1142
- .intervalPicker-begin {
1143
- width: calc(50% - 14px);
1144
- }
1145
-
1146
- .intervalPicker-center {
1147
- width: 30px;
1148
- border-left: 0;
1149
- pointer-events: none;
1150
- }
1151
-
1152
- .intervalPicker-end {
1153
- width: calc(50% - 14px);
1154
- border-left: 0;
1155
- }
1156
- </style>
1
+ <template>
2
+ <!-- 输入框 -->
3
+ <x-form-col
4
+ v-if="attr.type === 'input' && show"
5
+ :flex="attr.flex">
6
+ <a-form-model-item
7
+ :ref="attr.model"
8
+ :label="showLabel?attr.name:undefined"
9
+ :labelCol="layout === 'inline' && attr.occupyCol ? labelAndWrapperCol[attr.occupyCol].labelCol:undefined"
10
+ :wrapperCol="layout === 'inline'&& attr.occupyCol ? labelAndWrapperCol[attr.occupyCol].wrapperCol:undefined"
11
+ :style="layout === 'inline'&& attr.occupyCol && attr.occupyCol > 1? {width:`calc(100% - ${attr.occupyCol * 1.533}rem)`}:{}"
12
+ :prop="attr.prop ? attr.prop : attr.model">
13
+ <!-- 如果配置了后置按钮插槽 -->
14
+ <a-input-group
15
+ v-if="(attr.inputOnAfterName && attr.inputOnAfterFunc) || (attr.inputOnAfterIcon && attr.inputOnAfterIconFunc)"
16
+ style="display: flex; width: 100%;"
17
+ compact>
18
+ <a-input
19
+ v-model="form[attr.model]"
20
+ :read-only="readOnly"
21
+ :disabled="disabled && !readOnly"
22
+ :whitespace="true"
23
+ style="flex: 1; width: auto; min-width: 0;"
24
+ @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
25
+ :suffix="attr.inputSuffix && mode !== '新增' ? attr.inputSuffix : ''"
26
+ @blur="attr.inputOnBlurFunc && emitFunc(attr.inputOnBlurFunc,attr)"
27
+ @keyup.enter="attr.inputOnEnterFunc && emitFunc(attr.inputOnEnterFunc, attr)"
28
+ :placeholder="attr.placeholder ? attr.placeholder : '请输入'+attr.name.replace(/\s*/g, '')"
29
+ :ref="`${attr.model}input`"/>
30
+ <a-button
31
+ v-if="attr.inputOnAfterName && attr.inputOnAfterFunc"
32
+ style="flex: 1; width: auto; min-width: 4rem;max-width: 6rem"
33
+ type="primary"
34
+ @click="emitFunc(attr.inputOnAfterFunc,form[attr.model])">
35
+ {{ attr.inputOnAfterName }}
36
+ </a-button>
37
+ <!-- 仅可以配置 一个按钮 以及 一个图标插槽 -->
38
+ <a-button
39
+ style="width: 2rem; flex-shrink: 0;"
40
+ v-if="attr.inputOnAfterIcon"
41
+ :type="attr.inputOnAfterIcon && attr.inputOnAfterName ? 'primary' :''"
42
+ :icon="attr.inputOnAfterIcon || 'question'"
43
+ @click="emitFunc(attr.inputOnAfterIconFunc,form[attr.model])">
44
+ </a-button>
45
+ </a-input-group>
46
+ <a-input-number
47
+ v-else-if="attr.numberInput && !readOnly"
48
+ v-model="form[attr.model]"
49
+ :whitespace="true"
50
+ :disabled="disabled && !readOnly"
51
+ style="width:100%"
52
+ @blur="attr.inputOnBlurFunc && emitFunc(attr.inputOnBlurFunc,attr)"
53
+ @keyup.enter="attr.inputOnEnterFunc && emitFunc(attr.inputOnEnterFunc, attr)"
54
+ :suffix="attr.inputSuffix && mode !== '新增' ? attr.inputSuffix : ''"
55
+ :placeholder="attr.placeholder ? attr.placeholder : '请输入'+attr.name.replace(/\s*/g, '')"
56
+ :ref="`${attr.model}input`"/>
57
+ <a-input
58
+ v-else
59
+ v-model="form[attr.model]"
60
+ :whitespace="true"
61
+ :read-only="readOnly"
62
+ :disabled="disabled && !readOnly"
63
+ :suffix="attr.inputSuffix && mode !== '新增' ? attr.inputSuffix : ''"
64
+ style="width:100%"
65
+ @blur="attr.inputOnBlurFunc && emitFunc(attr.inputOnBlurFunc,attr)"
66
+ @keyup.enter="attr.inputOnEnterFunc && emitFunc(attr.inputOnEnterFunc, attr)"
67
+ :placeholder="attr.placeholder ? attr.placeholder : '请输入'+attr.name.replace(/\s*/g, '')"
68
+ :ref="`${attr.model}input`"/>
69
+
70
+ </a-form-model-item>
71
+ </x-form-col>
72
+ <!-- 下拉框 -->
73
+ <x-form-col
74
+ v-else-if="(attr.type === 'select' || (attr.type === 'rate' && mode==='查询')) && show"
75
+ :flex="attr.flex">
76
+ <a-form-model-item
77
+ :ref="attr.model"
78
+ :label="showLabel?attr.name:undefined"
79
+ :prop="attr.prop ? attr.prop : attr.model">
80
+ <a-select
81
+ v-if="!attr.lazyLoad || attr.lazyLoad === 'false'"
82
+ v-model="form[attr.model]"
83
+ :disabled="disabled"
84
+ @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
85
+ :filter-option="filterOption"
86
+ :getPopupContainer=" triggerNode => { return triggerNode.parentNode } "
87
+ :placeholder="attr.placeholder ? attr.placeholder : '请选择'"
88
+ show-search
89
+ >
90
+ <a-select-option
91
+ v-if="mode === '查询'"
92
+ key="999999"
93
+ value="">全部
94
+ </a-select-option>
95
+ <template v-if="attr.keys">
96
+ <a-select-option
97
+ v-for="(item,index) in attr.keys"
98
+ :key="index.value"
99
+ :value="item.value">
100
+ {{ item.label }}
101
+ </a-select-option>
102
+ </template>
103
+ <template v-else>
104
+ <template
105
+ v-if="attr.keyName.indexOf('logic@') !== -1 || attr.keyName.indexOf('config@') !== -1
106
+ ||attr.keyName.indexOf('search@') !== -1 || attr.keyName.indexOf('search@') !== -1">
107
+ <a-select-option
108
+ v-for="(item,index) in option"
109
+ :key="index.value"
110
+ :value="item.value">
111
+ <template v-if="attr.keyName.indexOf('config@') !== -1 && item.status">
112
+ <!-- 徽标(badge) -->
113
+ <a-badge v-if="item.status !== 'gary'" :color="item.status" :text="item.label"/>
114
+ <a-badge v-else color="#D9D9D9" :text="item.label"/>
115
+ </template>
116
+ <template v-else>
117
+ {{ item.label }}
118
+ </template>
119
+ </a-select-option>
120
+ </template>
121
+ <template
122
+ v-else-if="attr.keyName.indexOf('async ') !== -1 || attr.keyName.indexOf('function ') !== -1">
123
+ <a-select-option
124
+ v-for="(item,index) in optionForFunc"
125
+ :key="index.value"
126
+ :value="item.value">
127
+ <template>
128
+ {{ item.label }}
129
+ </template>
130
+ </a-select-option>
131
+ </template>
132
+ <template v-else>
133
+ <a-select-option
134
+ v-for="item in $appdata.getDictionaryList(attr.keyName)"
135
+ :key="item.value"
136
+ :value="item.value">
137
+ <!-- 徽标(badge) -->
138
+ <x-badge
139
+ :badge-key="attr.keyName"
140
+ :replaceText="item.text"
141
+ :value="item.value"
142
+ :service-name="serviceName"
143
+ :env="env"/>
144
+ </a-select-option>
145
+ </template>
146
+ </template>
147
+ </a-select>
148
+ <a-select
149
+ v-else
150
+ v-model="form[attr.model]"
151
+ :disabled="disabled"
152
+ @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
153
+ :filter-option="filterOption"
154
+ :getPopupContainer=" triggerNode => { return triggerNode.parentNode } "
155
+ :placeholder="attr.placeholder ? attr.placeholder : '搜索' + attr.name"
156
+ show-search
157
+ @search="fetchFunction"
158
+ >
159
+ <a-spin v-if="searching" slot="notFoundContent" size="small"/>
160
+ <a-select-option
161
+ v-if="mode === '查询'"
162
+ key="999999"
163
+ value="">全部
164
+ </a-select-option>
165
+ <a-select-option
166
+ v-for="(item,index) in option"
167
+ :key="index"
168
+ :value="item.value">{{ item.label }}
169
+ </a-select-option>
170
+ </a-select>
171
+ </a-form-model-item>
172
+ </x-form-col>
173
+ <!-- 多选框 -->
174
+ <x-form-col
175
+ v-else-if="attr.type === 'checkbox' && show"
176
+ :flex="attr.flex">
177
+ <a-form-model-item
178
+ :ref="attr.model"
179
+ :label="showLabel?attr.name:undefined"
180
+ :prop="attr.prop ? attr.prop : attr.model">
181
+ <a-select
182
+ v-if="!attr.lazyLoad || attr.lazyLoad === 'false'"
183
+ v-model="form[attr.model]"
184
+ :disabled="disabled"
185
+ :filter-option="filterOption"
186
+ :getPopupContainer=" triggerNode => { return triggerNode.parentNode } "
187
+ :placeholder="attr.placeholder ? attr.placeholder : '请选择'"
188
+ @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
189
+ mode="multiple"
190
+ show-search
191
+ allowClear
192
+ >
193
+ <template v-if="attr.keys">
194
+ <a-select-option
195
+ v-for="(item,index) in attr.keys"
196
+ :key="index"
197
+ :value="item.value">
198
+ {{ item.label }}
199
+ </a-select-option>
200
+ </template>
201
+ <template v-else>
202
+ <template
203
+ v-if="attr.keyName.indexOf('logic@') !== -1 || attr.keyName.indexOf('config@') !== -1
204
+ ||attr.keyName.indexOf('search@') !== -1 || attr.keyName.indexOf('search@') !== -1">
205
+ <a-select-option
206
+ v-for="(item,index) in option"
207
+ :key="index"
208
+ :value="item.value">{{ item.label }}
209
+ </a-select-option>
210
+ </template>
211
+ <template v-else>
212
+ <a-select-option
213
+ v-for="item in $appdata.getDictionaryList(attr.keyName)"
214
+ :key="item.value"
215
+ :value="item.value">{{ item.text }}
216
+ </a-select-option>
217
+ </template>
218
+ </template>
219
+ </a-select>
220
+ <a-select
221
+ v-else
222
+ v-model="form[attr.model]"
223
+ :disabled="disabled"
224
+ :filter-option="filterOption"
225
+ :getPopupContainer=" triggerNode => { return triggerNode.parentNode } "
226
+ :placeholder="attr.placeholder ? attr.placeholder : '搜索' + attr.name"
227
+ mode="multiple"
228
+ @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
229
+ show-search
230
+ allowClear
231
+ @search="fetchFunction"
232
+ >
233
+ <a-spin v-if="searching" slot="notFoundContent" size="small"/>
234
+ <a-select-option
235
+ v-for="(item,index) in option"
236
+ :key="index"
237
+ :value="item.value">{{ item.label }}
238
+ </a-select-option>
239
+ </a-select>
240
+ </a-form-model-item>
241
+ </x-form-col>
242
+ <!-- 单选框 -->
243
+ <x-form-col
244
+ v-else-if="attr.type === 'radio' && show"
245
+ :flex="attr.flex">
246
+ <a-form-model-item
247
+ :ref="attr.model"
248
+ :label="showLabel?attr.name:undefined"
249
+ :prop="attr.prop ? attr.prop : attr.model">
250
+ <a-radio-group
251
+ v-model="form[attr.model]"
252
+ @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
253
+ >
254
+ <template v-if="attr.keys">
255
+ <a-radio v-for="(item,index) in attr.keys" :key="index" :value="item.value">
256
+ {{ item.label }}
257
+ </a-radio>
258
+ </template>
259
+ <template v-else>
260
+ <template
261
+ v-if="attr.keyName.indexOf('logic@') !== -1 || attr.keyName.indexOf('config@') !== -1
262
+ ||attr.keyName.indexOf('search@') !== -1 || attr.keyName.indexOf('search@') !== -1">
263
+ <a-radio v-for="(item,index) in option" :key="index" :value="item.value">
264
+ {{ item.label }}
265
+ </a-radio>
266
+ </template>
267
+ <template v-else>
268
+ <a-radio v-for="(item,index) in $appdata.getDictionaryList(attr.keyName)" :key="index" :value="item.value">
269
+ {{ item.text }}
270
+ </a-radio>
271
+ </template>
272
+ </template>
273
+ </a-radio-group>
274
+ </a-form-model-item>
275
+ </x-form-col>
276
+ <!-- 日期范围选择器 -->
277
+ <x-form-col
278
+ v-else-if="attr.type === 'rangePicker' && show"
279
+ :flex="attr.flex">
280
+ <a-form-model-item
281
+ :ref="attr.model"
282
+ :label="showLabel?attr.name:undefined"
283
+ :prop="attr.prop ? attr.prop : attr.model">
284
+ <a-date-picker
285
+ @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
286
+ v-if="mode === '新增/修改'"
287
+ v-model="form[attr.model]"
288
+ :disabled="disabled"
289
+ :show-time="true"
290
+ style="width: 100%;"
291
+ valueFormat="YYYY-MM-DD HH:mm:ss"/>
292
+ <a-range-picker
293
+ v-else
294
+ @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
295
+ v-model="form[attr.model]"
296
+ :disabled="disabled"
297
+ :show-time="true"
298
+ valueFormat="YYYY-MM-DD HH:mm:ss"
299
+ style="width: 100%;"
300
+ />
301
+ </a-form-model-item>
302
+ </x-form-col>
303
+ <!-- 月份选择器 -->
304
+ <x-form-col
305
+ v-else-if="attr.type === 'monthPicker' && show"
306
+ :flex="attr.flex">
307
+ <a-form-model-item
308
+ :ref="attr.model"
309
+ :label="showLabel?attr.name:undefined"
310
+ :prop="attr.prop ? attr.prop : attr.model">
311
+ <a-month-picker
312
+ @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
313
+ v-model="form[attr.model]"
314
+ :disabled="disabled"
315
+ :show-time="true"
316
+ valueFormat="YYYY-MM"
317
+ style="width: 100%;"
318
+ />
319
+ </a-form-model-item>
320
+ </x-form-col>
321
+ <!-- 年份选择器 -->
322
+ <x-form-col
323
+ v-else-if="attr.type === 'yearPicker' && show"
324
+ :flex="attr.flex">
325
+ <a-form-model-item
326
+ :ref="attr.model"
327
+ :label="showLabel?attr.name:undefined"
328
+ :prop="attr.prop ? attr.prop : attr.model">
329
+ <a-date-picker
330
+ @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
331
+ v-model="form[attr.model]"
332
+ :disabled="disabled"
333
+ format="YYYY"
334
+ mode="year"
335
+ v-decorator="['year']"
336
+ placeholder="请选择年份"
337
+ :open="yearShowOne"
338
+ style="width: 100%;"
339
+ @openChange="openChangeOne"
340
+ @panelChange="panelChangeOne"/>
341
+ </a-form-model-item>
342
+ </x-form-col>
343
+ <!-- 单日选择器 -->
344
+ <x-form-col
345
+ v-else-if="attr.type === 'datePicker' && show"
346
+ :flex="attr.flex">
347
+ <a-form-model-item
348
+ :ref="attr.model"
349
+ :label="showLabel?attr.name:undefined"
350
+ :prop="attr.prop ? attr.prop : attr.model">
351
+ <a-range-picker
352
+ @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
353
+ v-if="mode === '查询' && attr.queryType === 'BETWEEN' "
354
+ v-model="form[attr.model]"
355
+ :disabled="disabled"
356
+ :show-time="true"
357
+ style="width: 100%;"
358
+ format="YYYY-MM-DD"
359
+ valueFormat="YYYY-MM-DD HH:mm:ss"/>
360
+ <a-date-picker
361
+ @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
362
+ v-else-if="mode === '查询'"
363
+ v-model="form[attr.model]"
364
+ :disabled="disabled"
365
+ style="width: 100%;"
366
+ valueFormat="YYYY-MM-DD"/>
367
+ <a-date-picker
368
+ v-else
369
+ @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
370
+ v-model="form[attr.model]"
371
+ :disabled="disabled"
372
+ style="width: 100%;"
373
+ :show-time="{ defaultValue: moment('00:00:00', 'HH:mm:ss') }"
374
+ valueFormat="YYYY-MM-DD HH:mm:ss"/>
375
+ </a-form-model-item>
376
+ </x-form-col>
377
+ <!-- 文本域 -->
378
+ <a-col
379
+ v-else-if="attr.type === 'textarea' && show"
380
+ :style="layout === 'inline'?{width:'calc(100% - 60px)'}:{}"
381
+ :xs="24"
382
+ :sm="24"
383
+ :md="24"
384
+ :lg="24"
385
+ :xl="24"
386
+ :xxl="24">
387
+ <a-form-model-item
388
+ :labelCol="layout === 'inline'?{span:2}:undefined"
389
+ :wrapperCol="layout === 'inline'?{span:22}:undefined"
390
+ :ref="attr.model"
391
+ :label="showLabel?attr.name:undefined"
392
+ :prop="attr.prop ? attr.prop : attr.model">
393
+ <a-textarea
394
+ v-model="form[attr.model]"
395
+ style="width: 100%;"
396
+ :disabled="disabled"
397
+ :placeholder="attr.placeholder ? attr.placeholder : '请输入'+attr.name.replace(/\s*/g, '')"
398
+ :rows="4"/>
399
+ </a-form-model-item>
400
+ </a-col>
401
+ <!-- 文件上传 -->
402
+ <a-col
403
+ v-else-if="(attr.type === 'file' || attr.type === 'image') && show"
404
+ :style="layout === 'inline'?{width:'calc(100% - 60px)'}:{}"
405
+ :xs="24"
406
+ :sm="24"
407
+ :md="24"
408
+ :lg="24"
409
+ :xl="24"
410
+ :xxl="24">
411
+ <a-form-model-item
412
+ :labelCol="layout === 'inline'?{span:2}:undefined"
413
+ :wrapperCol="layout === 'inline'?{span:22}:undefined"
414
+ :ref="attr.model"
415
+ :label="showLabel?attr.name:undefined"
416
+ :prop="attr.prop ? attr.prop : attr.model">
417
+ <upload
418
+ :files="files"
419
+ :images="images"
420
+ :model="attr"
421
+ :uploadStyle="attr.uploadStyle"
422
+ :service-name="serviceName"
423
+ @setFiles="setFiles"></upload>
424
+ </a-form-model-item>
425
+ </a-col>
426
+ <!-- 省市区选择框 -->
427
+ <x-form-col
428
+ v-else-if="attr.type === 'citySelect' && show"
429
+ :flex="attr.flex">
430
+ <a-form-model-item
431
+ :ref="attr.model"
432
+ :label="showLabel?attr.name:undefined"
433
+ :prop="attr.prop ? attr.prop : attr.model">
434
+ <citySelect
435
+ @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
436
+ ref="citySelect"
437
+ v-model="form[attr.model]"
438
+ :contexts="attr.contexts"
439
+ :value-type="attr.valueType"
440
+ :default-value="form[attr.model]"></citySelect>
441
+ </a-form-model-item>
442
+ </x-form-col>
443
+ <!-- 地点搜索框 -->
444
+ <x-form-col
445
+ v-else-if="attr.type === 'addressSearch' && show"
446
+ :flex="attr.flex">
447
+ <a-form-model-item
448
+ :ref="attr.model"
449
+ :label="showLabel?attr.name:undefined"
450
+ :prop="attr.prop ? attr.prop : attr.model"
451
+ :labelCol="layout === 'inline' && attr.occupyCol ? labelAndWrapperCol[attr.occupyCol].labelCol:undefined"
452
+ :wrapperCol="layout === 'inline'&& attr.occupyCol ? labelAndWrapperCol[attr.occupyCol].wrapperCol:undefined"
453
+ :style="layout === 'inline'&& attr.occupyCol && attr.occupyCol > 1? {width:`calc(100% - ${attr.occupyCol * 1.533}rem)`}:{}">
454
+ <address-search-combobox
455
+ :emitFunc="emitFunc"
456
+ :attr="attr"
457
+ :read-only="readOnly"
458
+ v-model="searchResult"
459
+ :resultKeys="{ address: attr.model, coords: `${attr.model}_lng_lat` }"
460
+ ref="addressSearchCombobox"
461
+ searchResultType="Object"
462
+ @onSelect="addressSearchComboboxSelect"
463
+ @onDivisionsChange="onDivisionsChange"
464
+ ></address-search-combobox>
465
+ </a-form-model-item>
466
+ </x-form-col>
467
+ <!-- 富文本 -->
468
+ <x-form-col
469
+ v-else-if="attr.type === 'richText' && show"
470
+ :flex="attr.flex">
471
+ <a-form-model-item :ref="attr.model" :prop="attr.prop ? attr.prop : attr.model">
472
+ <RichTextModal ref="richTextModal" style="height: 500px"></RichTextModal>
473
+ </a-form-model-item>
474
+ </x-form-col>
475
+ <!-- 人员选择框 -->
476
+ <x-form-col
477
+ v-else-if="attr.type === 'personSetting' && show"
478
+ :flex="attr.flex">
479
+ <a-form-model-item
480
+ :ref="attr.model"
481
+ :label="showLabel?attr.name:undefined"
482
+ :prop="attr.prop ? attr.prop : attr.model">
483
+ <PersonSetting v-model="form[attr.model]"></PersonSetting>
484
+ </a-form-model-item>
485
+ </x-form-col>
486
+ <!-- 树形选择框 -->
487
+ <x-form-col
488
+ v-else-if="attr.type === 'treeSelect' && show"
489
+ :flex="attr.flex">
490
+ <x-tree-select
491
+ @onChange="attr.dataChangeFunc && debouncedDataChangeFunc()"
492
+ v-model="form[attr.model]"
493
+ :attr="attr"
494
+ ref="xTreeSelect">
495
+ </x-tree-select>
496
+ </x-form-col>
497
+ <!-- 评分框 -->
498
+ <x-form-col
499
+ v-else-if="attr.type === 'rate' && show"
500
+ :flex="attr.flex">
501
+ <a-form-model-item
502
+ :ref="attr.model"
503
+ :label="showLabel?attr.name:undefined"
504
+ :prop="attr.prop ? attr.prop : attr.model">
505
+ <a-rate
506
+ v-model="form[attr.model]"
507
+ @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
508
+ />
509
+ </a-form-model-item>
510
+ </x-form-col>
511
+ <!-- 区间选择器 -->
512
+ <x-form-col
513
+ v-else-if="attr.type === 'intervalPicker' && show"
514
+ :flex="attr.flex">
515
+ <a-form-model-item
516
+ :ref="attr.model"
517
+ :label="showLabel?attr.name:undefined"
518
+ :prop="attr.prop ? attr.prop : attr.model">
519
+ <a-input
520
+ v-if="mode === '新增/修改'"
521
+ v-model="form[attr.model]"
522
+ :whitespace="true"
523
+ :read-only="readOnly"
524
+ :disabled="disabled && !readOnly"
525
+ style="width:100%"
526
+ @blur="attr.inputOnBlurFunc && emitFunc(attr.inputOnBlurFunc,attr)"
527
+ :placeholder="attr.placeholder ? attr.placeholder : '请输入'+attr.name.replace(/\s*/g, '')"
528
+ :ref="`${attr.model}input`"/>
529
+ <a-input-group v-else compact>
530
+ <a-input
531
+ v-model="form[attr.model][0]"
532
+ class="intervalPicker-begin"
533
+ placeholder="起始值"/>
534
+ <a-input
535
+ class="intervalPicker-center"
536
+ style="backgroundColor: #fff"
537
+ placeholder="~"
538
+ disabled
539
+ />
540
+ <a-input
541
+ v-model="form[attr.model][1]"
542
+ class="intervalPicker-end"
543
+ placeholder="结束值"/>
544
+ </a-input-group>
545
+ </a-form-model-item>
546
+ </x-form-col>
547
+ <!-- 车牌号选择 -->
548
+ <x-form-col
549
+ v-else-if="attr.type === 'licensePlate' && show"
550
+ :flex="attr.flex">
551
+ <a-form-model-item
552
+ :ref="attr.model"
553
+ :label="showLabel?attr.name:undefined"
554
+ :style="layout === 'inline'&& attr.occupyCol && attr.occupyCol > 1? {width:`calc(100% - ${attr.occupyCol * 1.533}rem)`}:{}"
555
+ :prop="attr.prop ? attr.prop : attr.model">
556
+ <!-- 如果配置了后置按钮插槽 -->
557
+ <a-input
558
+ v-if="mode ==='查询'"
559
+ v-model="form[attr.model]"
560
+ :whitespace="true"
561
+ :read-only="readOnly"
562
+ :disabled="disabled && !readOnly"
563
+ style="width:100%"
564
+ @blur="attr.inputOnBlurFunc && emitFunc(attr.inputOnBlurFunc,attr)"
565
+ :placeholder="attr.placeholder ? attr.placeholder : '请输入'+attr.name.replace(/\s*/g, '')"
566
+ :ref="`${attr.model}input`"/>
567
+ <x-license-plate
568
+ v-else
569
+ v-model="form[attr.model]"
570
+ @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
571
+ ></x-license-plate>
572
+ </a-form-model-item>
573
+ </x-form-col>
574
+ </template>
575
+ <script>
576
+
577
+ import { debounce } from 'ant-design-vue/lib/vc-table/src/utils'
578
+ import XFormCol from '@vue2-client/base-client/components/common/XFormCol'
579
+ import XBadge from '@vue2-client/base-client/components/common/XBadge'
580
+ import CitySelect from '@vue2-client/base-client/components/common/CitySelect'
581
+ import PersonSetting from '@vue2-client/base-client/components/common/PersonSetting'
582
+ import AddressSearchCombobox from '@vue2-client/base-client/components/common/AddressSearchCombobox'
583
+ import Upload from '@vue2-client/base-client/components/common/Upload'
584
+ import moment from 'moment'
585
+ import { upload, getConfigByName, runLogic, getConfigByNameAsync } from '@vue2-client/services/api/common'
586
+ import util, { uuid } from '.././../../../utils/util'
587
+ import XTreeSelect from '@vue2-client/base-client/components/common/XForm/XTreeSelect'
588
+ import { searchToListOption, searchToOption } from '@vue2-client/services/v3Api'
589
+ import { mapState } from 'vuex'
590
+ import { executeStrFunction } from '@vue2-client/utils/runEvalFunction'
591
+ import RichTextModal from '../richTextModal/index.vue'
592
+ import XLicensePlate from '@vue2-client/base-client/components/common/XLicensePlate/XLicensePlate.vue'
593
+
594
+ export default {
595
+ name: 'XFormItem',
596
+ components: {
597
+ XLicensePlate,
598
+ XTreeSelect,
599
+ XFormCol,
600
+ XBadge,
601
+ CitySelect,
602
+ PersonSetting,
603
+ AddressSearchCombobox,
604
+ Upload,
605
+ RichTextModal
606
+ },
607
+ data () {
608
+ // 检索去抖
609
+ this.fetchFunction = debounce(this.fetchFunction, 800)
610
+ return {
611
+ option: [],
612
+ // 最后检索版本
613
+ lastFetchId: 0,
614
+ // 检索中
615
+ searching: false,
616
+ searchResult: '',
617
+ yearShowOne: false,
618
+ optionForFunc: [],
619
+ // 控制当前表单项是否展示
620
+ show: true,
621
+ labelAndWrapperCol: [{
622
+ labelCol: undefined,
623
+ wrapperCol: undefined
624
+ },
625
+ {
626
+ labelCol: undefined,
627
+ wrapperCol: undefined
628
+ },
629
+ {
630
+ labelCol: { span: 3 },
631
+ wrapperCol: { span: 21 }
632
+ },
633
+ {
634
+ labelCol: { span: 2 },
635
+ wrapperCol: { span: 22 }
636
+ }],
637
+ // moment
638
+ moment
639
+ }
640
+ },
641
+ props: {
642
+ attr: {
643
+ type: Object,
644
+ default:
645
+ () => {
646
+ return {}
647
+ }
648
+ },
649
+ form: {
650
+ type: Object,
651
+ required:
652
+ true
653
+ },
654
+ disabled: {
655
+ type: Boolean,
656
+ default:
657
+ () => {
658
+ return false
659
+ }
660
+ },
661
+ readOnly: {
662
+ type: Boolean,
663
+ default:
664
+ () => {
665
+ return false
666
+ }
667
+ },
668
+ mode: {
669
+ type: String,
670
+ default:
671
+ () => {
672
+ return '查询'
673
+ }
674
+ },
675
+ files: {
676
+ type: Array,
677
+ default:
678
+ () => {
679
+ return []
680
+ }
681
+ },
682
+ images: {
683
+ type: Array,
684
+ default:
685
+ () => {
686
+ return []
687
+ }
688
+ },
689
+ serviceName: {
690
+ type: String,
691
+ default:
692
+ undefined
693
+ },
694
+ // 调用logic获取数据源的追加参数
695
+ getDataParams: {
696
+ type: Object,
697
+ default:
698
+ undefined
699
+ },
700
+ // 布局
701
+ layout: {
702
+ type: String,
703
+ default:
704
+ 'horizontal'
705
+ },
706
+ // 环境
707
+ env: {
708
+ type: String,
709
+ default:
710
+ () => {
711
+ return 'prod'
712
+ }
713
+ },
714
+ // 设置表单值
715
+ setForm: {
716
+ type: Function,
717
+ default: (val) => {
718
+ console.log(val)
719
+ }
720
+ },
721
+ showLabel: {
722
+ type: Boolean,
723
+ default:
724
+ () => {
725
+ return true
726
+ }
727
+ }
728
+ },
729
+ async created () {
730
+ this.init()
731
+ if (this.attr.keyName && (this.attr?.keyName?.toString().indexOf('async ') !== -1 || this.attr?.keyName?.toString()?.indexOf('function') !== -1)) {
732
+ this.debouncedUpdateOptions = debounce(this.updateOptions, 200)
733
+ }
734
+ if (this.attr.dataChangeFunc) {
735
+ this.debouncedDataChangeFunc = debounce(this.dataChangeFunc, 200)
736
+ }
737
+ if (this.attr.showFormItemFunc) {
738
+ this.debouncedShowFormItemFunc = debounce(this.showFormItemFunc, 100)
739
+ // 执行一次
740
+ debounce(this.showFormItemFunc, 100)()
741
+ }
742
+ if (this.attr.showQueryFormItemFunc) {
743
+ this.debouncedShowQueryFormItemFunc = debounce(this.showQueryFormItemFunc, 100)
744
+ // 执行一次
745
+ debounce(this.showQueryFormItemFunc, 100)()
746
+ }
747
+ // 人员联动框增加监听
748
+ if (this?.attr?.keyName?.toString()?.startsWith('search@根据表单项[') && this?.attr?.keyName?.toString().endsWith(']联动人员')) {
749
+ this.debouncedUserLinkFunc = debounce(() => this.updateResOptions('人员'), 200)
750
+ }
751
+ if (this?.attr?.keyName?.toString()?.startsWith('search@根据表单项[') && this?.attr?.keyName?.toString().endsWith(']联动部门')) {
752
+ this.debouncedDepLinkFunc = debounce(() => this.updateResOptions('部门'), 200)
753
+ }
754
+ },
755
+ computed: {
756
+ ...mapState('account', { currUser: 'user' })
757
+ },
758
+ watch: {
759
+ attr: {
760
+ handler () {
761
+ this.init()
762
+ },
763
+ deep: true
764
+ },
765
+ form: {
766
+ handler (newVal, oldVal) {
767
+ // 如果是从函数获取 options
768
+ if (this.attr.keyName && (this.attr.keyName.toString().indexOf('async ') !== -1 || this.attr.keyName.toString().indexOf('function') !== -1)) {
769
+ this.debouncedUpdateOptions()
770
+ }
771
+ // 如果有自定义是否展示表单项函数
772
+ if (this.attr.showFormItemFunc) {
773
+ this.debouncedShowFormItemFunc()
774
+ }
775
+ // 如果有自定义是否展示查询表单项函数
776
+ if (this.attr.showQueryFormItemFunc) {
777
+ this.debouncedShowQueryFormItemFunc()
778
+ }
779
+ // 地址搜索框赋值
780
+ if (this.attr.type === 'addressSearch') {
781
+ this.$refs.addressSearchCombobox.addressInput = this.form[this.attr.model]
782
+ }
783
+ // 数据源来自人员联动时更新数据
784
+ if (this?.attr?.keyName?.toString()?.startsWith('search@根据表单项[') && this?.attr?.keyName?.toString().endsWith(']联动人员')) {
785
+ this.debouncedUserLinkFunc()
786
+ }
787
+ // 数据源来自人员联动时更新数据
788
+ if (this?.attr?.keyName?.toString()?.startsWith('search@根据表单项[') && this?.attr?.keyName?.toString().endsWith(']联动部门')) {
789
+ this.debouncedDepLinkFunc()
790
+ }
791
+ },
792
+ deep: true
793
+ }
794
+ },
795
+ methods: {
796
+ focusInput () {
797
+ if (this.attr.defaultFocus) {
798
+ this.$nextTick(h => {
799
+ const el = this.$refs[`${this.attr.model}input`]?.$el
800
+ let inputEl
801
+ if (el) {
802
+ if (el.tagName.toLowerCase() === 'input') {
803
+ inputEl = el
804
+ } else {
805
+ inputEl = el.querySelector('input')
806
+ }
807
+ }
808
+ if (inputEl) {
809
+ inputEl.focus()
810
+ if (inputEl.type === 'number') {
811
+ if (inputEl.valueAsNumber) {
812
+ inputEl.setSelectionRange(0, inputEl.valueAsNumber.toString().length)
813
+ }
814
+ } else {
815
+ if (inputEl.value) {
816
+ inputEl.setSelectionRange(0, inputEl.value.length)
817
+ }
818
+ }
819
+ }
820
+ })
821
+ }
822
+ },
823
+ // 更新人员下拉框数据
824
+ async updateResOptions (type) {
825
+ if (this?.attr?.keyName?.toString()?.startsWith('search@根据表单项[') && this?.attr?.keyName?.toString()?.endsWith(`]联动${type}`)) {
826
+ const searchData = { source: `获取${type}`, userid: this.currUser.id }
827
+ const startIndex = this.attr.keyName.indexOf('[') + 1
828
+ const endIndex = this.attr.keyName.indexOf(']', startIndex)
829
+ const fromModel = this.attr.keyName.substring(startIndex, endIndex).replace('.', '_')
830
+ const formModelData = this.form[fromModel]
831
+ if (fromModel?.length && formModelData?.length) {
832
+ await searchToListOption(searchData, res => {
833
+ this.getDataCallback(
834
+ res.filter(h => {
835
+ if (fromModel.indexOf('org') > -1) {
836
+ return formModelData?.includes(h.orgid || h.f_organization_id || h.parentid)
837
+ } else {
838
+ return formModelData?.includes(h?.parentid)
839
+ }
840
+ }
841
+ )
842
+ )
843
+ })
844
+ }
845
+ }
846
+ },
847
+ // js 函数作为数据源
848
+ async updateOptions () {
849
+ if (this.attr.keyName && (this.attr.keyName.indexOf('async ') !== -1 || this.attr.keyName.indexOf('function ') !== -1)) {
850
+ this.optionForFunc = await executeStrFunction(this.attr.keyName, [this.form, runLogic, this.mode, getConfigByNameAsync])
851
+ }
852
+ },
853
+ async dataChangeFunc () {
854
+ if (this.attr.dataChangeFunc) {
855
+ await executeStrFunction(this.attr.dataChangeFunc, [this.form, this.setForm, this.attr, util, this.mode, runLogic, getConfigByNameAsync])
856
+ }
857
+ },
858
+ async showFormItemFunc () {
859
+ if (this.attr.showFormItemFunc) {
860
+ const obj = executeStrFunction(this.attr.showFormItemFunc, [this.form, this.setForm, this.attr, util, this.mode])
861
+ // 判断是 bool 还是 obj 兼容
862
+ if (typeof obj === 'boolean') {
863
+ this.show = obj
864
+ } else if (obj && typeof obj === 'object') {
865
+ // obj 是一个对象,并且不是数组
866
+ this.show = obj?.show
867
+ this.readOnly = obj?.readOnly
868
+ }
869
+ } else {
870
+ this.show = true
871
+ }
872
+ },
873
+ async showQueryFormItemFunc () {
874
+ if (this.attr.showQueryFormItemFunc) {
875
+ const obj = executeStrFunction(this.attr.showQueryFormItemFunc, [this.form, this.setForm, this.attr, util, this.mode])
876
+ // 判断是 bool 还是 obj 兼容
877
+ if (typeof obj === 'boolean') {
878
+ this.show = obj
879
+ } else if (obj && typeof obj === 'object') {
880
+ // obj 是一个对象,并且不是数组
881
+ this.show = obj?.show
882
+ this.readOnly = obj?.readOnly
883
+ }
884
+ } else {
885
+ this.show = true
886
+ }
887
+ },
888
+ init () {
889
+ if (this.mode === '新增/修改' && !this.attr.flex) {
890
+ if (['horizontal', 'vertical'].includes(this.layout)) {
891
+ // 新增修改表单 horizontal 模式下默认为一行
892
+ this.attr.flex = {
893
+ xs: 24,
894
+ sm: 24,
895
+ md: 24,
896
+ lg: 24,
897
+ xl: 24,
898
+ xxl: 24
899
+ }
900
+ } else {
901
+ if (['input', 'addressSearch'] && this.attr.occupyCol) {
902
+ // 如果是 input 看是否配置了 占用列配置
903
+ this.attr.flex = {
904
+ xs: 8 * this.attr.occupyCol,
905
+ sm: 8 * this.attr.occupyCol,
906
+ md: 8 * this.attr.occupyCol,
907
+ lg: 8 * this.attr.occupyCol,
908
+ xl: 8 * this.attr.occupyCol,
909
+ xxl: 8 * this.attr.occupyCol
910
+ }
911
+ } else {
912
+ // 新增修改表单 vertical 模式下默认为1列
913
+ this.attr.flex = {
914
+ xs: 24,
915
+ sm: 24,
916
+ md: 24,
917
+ lg: 12,
918
+ xl: 8,
919
+ xxl: 8
920
+ }
921
+ }
922
+ }
923
+ } else {
924
+ this.attr.flex = {
925
+ xs: 24,
926
+ sm: 24,
927
+ md: 24,
928
+ lg: 8,
929
+ xl: 6,
930
+ xxl: 6
931
+ }
932
+ }
933
+ if (this.attr.type === 'richText') {
934
+ this.initRichText()
935
+ } else if (this.attr.keyName && typeof this.attr.keyName === 'string') {
936
+ if (this.attr.keyName.indexOf('logic@') !== -1) {
937
+ this.getData({}, res => this.getDataCallback(res))
938
+ } else if (this.attr.keyName.indexOf('search@') !== -1) {
939
+ // `tool.getFullTree(this.getRights().where(row.getType()==$organization$))`
940
+ // 判断是否根据角色查询
941
+ let source = this.attr.keyName.substring(7)
942
+ const userid = this.currUser.id
943
+ let roleName = 'roleName'
944
+ if (source.startsWith('根据角色[') && source.endsWith(']获取人员')) {
945
+ const startIndex = source.indexOf('[') + 1
946
+ const endIndex = source.indexOf(']', startIndex)
947
+ roleName = source.substring(startIndex, endIndex)
948
+ source = '根据角色获取人员'
949
+ }
950
+ const searchData = { source, userid, roleName }
951
+ // 判断是否根据某个表单项联动 仅返回列表结构并筛选
952
+ if (source.startsWith('根据表单项[') && source.endsWith(']联动人员')) {
953
+ this.updateResOptions('人员')
954
+ } else if (source.startsWith('根据表单项[') && source.endsWith(']联动部门')) {
955
+ this.updateResOptions('部门')
956
+ } else if (this.attr.type === 'select' || this.attr.type === 'checkbox') {
957
+ // 仅获取最内层数据
958
+ searchToListOption(searchData, res => this.getDataCallback(res))
959
+ } else {
960
+ // 其他资源通用逻辑
961
+ searchToOption(searchData, res => this.getDataCallback(res))
962
+ }
963
+ } else if (this.attr.keyName.indexOf('config@') !== -1) {
964
+ const configName = this.attr.keyName.substring(7)
965
+ getConfigByName(configName, this.serviceName, res => {
966
+ this.getDataCallback(res.value)
967
+ }, this.env === 'dev')
968
+ } else if (this.attr.keyName.indexOf('async ') !== -1 || this.attr.keyName.indexOf('function ') !== -1) {
969
+ this.updateOptions()
970
+ }
971
+ }
972
+ this.focusInput()
973
+ },
974
+ addressSearchComboboxSelect (data) {
975
+ this.form = Object.assign(this.form, JSON.parse(data))
976
+ },
977
+ onDivisionsChange (data) {
978
+ this.emitFunc('addressSearchComboboxSelect', {
979
+ key: this.attr.model,
980
+ value: data
981
+ })
982
+ },
983
+ getDataCallback (res) {
984
+ this.option = res
985
+ if (this.attr.type === 'treeSelect') {
986
+ this.$refs.xTreeSelect.init({
987
+ option: this.option,
988
+ form: this.form,
989
+ queryType: this.attr.queryType,
990
+ name: this.attr.name,
991
+ model: this.attr.model,
992
+ mode: this.mode,
993
+ disabled: this.disabled
994
+ })
995
+ } else if (this.attr.type === 'radio') {
996
+ this.initRadioValue()
997
+ }
998
+ },
999
+ initRadioValue () {
1000
+ const model = this.attr.model
1001
+ if (this.mode === '新增/修改' && this.attr.type === 'radio' && (this.form[model] === undefined || this.form[model] === null) && !this.attr.prop) {
1002
+ if (this.attr.keys && this.attr.keys.length > 1) {
1003
+ this.form[model] = this.attr.keys[0].value
1004
+ } else if (this.option.length > 1) {
1005
+ this.form[model] = this.option[0].value
1006
+ }
1007
+ }
1008
+ },
1009
+ async initRichText () {
1010
+ const logicName = this.attr.keyName
1011
+ if (logicName) {
1012
+ this.getData({}, async res => {
1013
+ try {
1014
+ const response = await fetch(res.url) // 等待 fetch 完成
1015
+ if (response.ok) {
1016
+ const data = await response.text() // 等待解析为文本内容
1017
+ const richText = JSON.parse(data)
1018
+ this.$refs.richTextModal.init({
1019
+ richText: richText
1020
+ })
1021
+ } else {
1022
+ this.$message.error('富文本读取失败,请求结果:' + response.statusText)
1023
+ }
1024
+ } catch (error) {
1025
+ this.$message.error('富文本读取失败,请求结果:' + error)
1026
+ }
1027
+ })
1028
+ }
1029
+ },
1030
+ async getRichValue () {
1031
+ if (this.$refs.richTextModal) {
1032
+ const richText = this.$refs.richTextModal.getValue()
1033
+ console.log('>>>> richText: ', richText)
1034
+ const fileContent = JSON.stringify(richText)
1035
+ const fileName = uuid() + '.txt'
1036
+ // 创建一个 Blob 对象,类型为 text/plain
1037
+ const blob = new Blob([fileContent], { type: 'text/plain' })
1038
+ // 创建一个 File 对象(可选,但有助于保持一致性,因为 File 继承自 Blob)
1039
+ const file = new File([blob], fileName, { type: blob.type })
1040
+ // 组装上传数据
1041
+ const headers = {
1042
+ 'Content-Type': 'multipart/form-data',
1043
+ }
1044
+ const formData = new FormData()
1045
+ formData.append('avatar', file)
1046
+ formData.append('resUploadMode', 'server')
1047
+ formData.append('pathKey', 'Default')
1048
+ formData.append('formType', 'file')
1049
+ formData.append('useType', 'Default')
1050
+ formData.append('filename', fileName)
1051
+ formData.append('filesize', (blob.size / 1024 / 1024).toFixed(4))
1052
+ formData.append('f_operator', this.currUser ? this.currUser.username : '')
1053
+
1054
+ // 上传文件
1055
+ await upload(formData, this.serviceName, { headers, timeout: 600 * 1000 }, this.env === 'dev').then(res => {
1056
+ this.form[this.attr.model] = res.data.id
1057
+ this.form.t_f_path = res.data.f_downloadpath
1058
+ }).catch(error => {
1059
+ // 处理上传错误
1060
+ console.error(error)
1061
+ })
1062
+ }
1063
+ },
1064
+ openChangeOne (status) {
1065
+ if (status) {
1066
+ this.yearShowOne = true
1067
+ }
1068
+ },
1069
+ // 得到年份选择器的值
1070
+ panelChangeOne (value) {
1071
+ this.yearShowOne = false
1072
+ this.form[this.attr.model] = value.format('YYYY')
1073
+ },
1074
+ // 文件框时设置上传组件的值
1075
+ setFiles (fileIds) {
1076
+ if (!this.form[this.attr.model]) {
1077
+ this.form[this.attr.model] = []
1078
+ }
1079
+ this.form[this.attr.model] = [...fileIds]
1080
+ },
1081
+ // 懒加载检索方法
1082
+ fetchFunction (value) {
1083
+ this.lastFetchId += 1
1084
+ const fetchId = this.lastFetchId
1085
+ this.option = []
1086
+ this.searching = true
1087
+ this.getData({
1088
+ word: value
1089
+ }, res => {
1090
+ if (fetchId !== this.lastFetchId) {
1091
+ return
1092
+ }
1093
+ this.option = res
1094
+ this.searching = false
1095
+ })
1096
+ },
1097
+ // 获取数据
1098
+ getData (value, callbackFun) {
1099
+ if (value !== '') {
1100
+ const logicName = this.attr.keyName
1101
+ const logic = logicName.substring(6)
1102
+ // 调用logic前设置参数
1103
+ if (this.getDataParams && this.getDataParams[this.attr.model]) {
1104
+ Object.assign(value, this.getDataParams[this.attr.model])
1105
+ }
1106
+ runLogic(logic, Object.assign(value, {
1107
+ orgId: this.currUser.orgid,
1108
+ userId: this.currUser.id
1109
+ }), this.serviceName, this.env === 'dev').then(res => {
1110
+ callbackFun(res)
1111
+ }).catch(e => {
1112
+ callbackFun([])
1113
+ console.error('获取数据失败:' + e)
1114
+ })
1115
+ }
1116
+ },
1117
+ filterOption (input, option) {
1118
+ const child = option.componentOptions.children[0]
1119
+ if (child.text) {
1120
+ return child.text.toLowerCase().indexOf(input.toLowerCase()) >= 0
1121
+ } else if (child.elm.innerText) {
1122
+ return child.elm.innerText.toLowerCase().indexOf(input.toLowerCase()) >= 0
1123
+ } else {
1124
+ return child.child.value.toLowerCase().indexOf(input.toLowerCase()) >= 0
1125
+ }
1126
+ },
1127
+ emitFunc (func, data) {
1128
+ this.$emit('x-form-item-emit-func', func, data)
1129
+ }
1130
+ }
1131
+ }
1132
+ </script>
1133
+
1134
+ <style lang="less" scoped>
1135
+ .intervalPicker-begin {
1136
+ width: calc(50% - 14px);
1137
+ }
1138
+
1139
+ .intervalPicker-center {
1140
+ width: 30px;
1141
+ border-left: 0;
1142
+ pointer-events: none;
1143
+ }
1144
+
1145
+ .intervalPicker-end {
1146
+ width: calc(50% - 14px);
1147
+ border-left: 0;
1148
+ }
1149
+ </style>