vue2-client 1.9.13 → 1.9.14

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