vue2-client 1.16.25 → 1.16.27

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 (327) hide show
  1. package/.cursorrules +19 -19
  2. package/.env.apply +19 -19
  3. package/.env.gaslink +19 -19
  4. package/.env.his +19 -19
  5. package/.env.liuli +20 -20
  6. package/.env.scada +19 -19
  7. package/.eslintrc.js +90 -90
  8. package/CHANGELOG.md +824 -824
  9. package/Components.md +60 -60
  10. package/docs/LowCode/lowcode.md +155 -155
  11. package/docs/LowCode/lowcodeForDeveloper.md +230 -230
  12. package/docs/index.md +30 -30
  13. package/index.js +31 -31
  14. package/jest-transform-stub.js +8 -8
  15. package/jest.setup.js +7 -7
  16. package/jsconfig.json +19 -19
  17. package/package.json +112 -112
  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/src/assets/img/querySlotDemo.svg +15 -15
  54. package/src/assets/svg/badtwo.svg +1 -1
  55. package/src/assets/svg/goodtwo.svg +1 -1
  56. package/src/base-client/components/AI/AskAiBtn.vue +136 -136
  57. package/src/base-client/components/AI/demo.vue +31 -31
  58. package/src/base-client/components/common/AddressSearchCombobox/IcMapIcon.vue +16 -16
  59. package/src/base-client/components/common/AddressSearchCombobox/demo.vue +36 -36
  60. package/src/base-client/components/common/AddressSearchCombobox/ic_map.svg +6 -6
  61. package/src/base-client/components/common/AmapMarker/AmapPointRendering.vue +120 -120
  62. package/src/base-client/components/common/CitySelect/CitySelect.vue +1 -1
  63. package/src/base-client/components/common/CitySelect/index.js +3 -3
  64. package/src/base-client/components/common/CitySelect/index.md +109 -109
  65. package/src/base-client/components/common/CreateQuery/CreateQuery.vue +669 -669
  66. package/src/base-client/components/common/CreateQuery/CreateQueryItem.vue +1014 -1014
  67. package/src/base-client/components/common/CreateQuery/index.js +3 -3
  68. package/src/base-client/components/common/CreateQuery/index.md +42 -42
  69. package/src/base-client/components/common/CreateSimpleFormQuery/CreateSimpleFormQuery.vue +452 -452
  70. package/src/base-client/components/common/CreateSimpleFormQuery/CreateSimpleFormQueryItem.vue +511 -511
  71. package/src/base-client/components/common/CreateSimpleFormQuery/index.js +3 -3
  72. package/src/base-client/components/common/CreateSimpleFormQuery/index.md +42 -42
  73. package/src/base-client/components/common/FormGroupEdit/index.js +3 -3
  74. package/src/base-client/components/common/FormGroupEdit/index.md +43 -43
  75. package/src/base-client/components/common/FormGroupQuery/FormGroupQuery.vue +166 -166
  76. package/src/base-client/components/common/FormGroupQuery/index.js +3 -3
  77. package/src/base-client/components/common/FormGroupQuery/index.md +43 -43
  78. package/src/base-client/components/common/HIS/HForm/HForm.vue +133 -0
  79. package/src/base-client/components/common/HIS/HForm/index.js +3 -0
  80. package/src/base-client/components/common/JSONToTree/jsontotree.vue +271 -271
  81. package/src/base-client/components/common/LowCodeComponent/LowCodeEditorModal.vue +108 -108
  82. package/src/base-client/components/common/LowCodeComponent/LowCodeEditorPanel.vue +413 -413
  83. package/src/base-client/components/common/LowCodeComponent/LowCodePageOrganization.vue +502 -502
  84. package/src/base-client/components/common/LowCodeComponent/LowCodeRender.vue +728 -728
  85. package/src/base-client/components/common/LowCodeComponent/LowCodeRenderEnter.vue +29 -29
  86. package/src/base-client/components/common/LowCodeComponent/LowCodeUIStore.vue +219 -219
  87. package/src/base-client/components/common/LowCodeComponent/modal/lowCodeAddPageModal.vue +117 -117
  88. package/src/base-client/components/common/LowCodeComponent/modal/lowCodeCustomJSModal.vue +80 -80
  89. package/src/base-client/components/common/LowCodeComponent/modal/lowCodeEventEditorModal.vue +398 -398
  90. package/src/base-client/components/common/LowCodeComponent/modal/lowCodeLifeCycleModal.vue +65 -65
  91. package/src/base-client/components/common/LowCodeComponent/modal/lowCodeLogicCallbackModal.vue +64 -64
  92. package/src/base-client/components/common/LowCodeComponent/modal/lowCodeLogicParamModal.vue +73 -73
  93. package/src/base-client/components/common/LowCodeComponent/modal/lowCodeRunFunctionParamModal.vue +76 -76
  94. package/src/base-client/components/common/PersonSetting/PersonSetting.vue +208 -208
  95. package/src/base-client/components/common/PersonSetting/index.js +3 -3
  96. package/src/base-client/components/common/Recording/Recording.vue +243 -243
  97. package/src/base-client/components/common/Recording/index.js +3 -3
  98. package/src/base-client/components/common/Tree/Tree.vue +149 -149
  99. package/src/base-client/components/common/Tree/index.js +2 -2
  100. package/src/base-client/components/common/Upload/Upload.vue +333 -323
  101. package/src/base-client/components/common/Upload/index.js +3 -3
  102. package/src/base-client/components/common/XAddForm/XAddForm.vue +113 -113
  103. package/src/base-client/components/common/XAddNativeForm/index.md +146 -146
  104. package/src/base-client/components/common/XAddNativeFormOA/XAddNativeFormOA.vue +303 -303
  105. package/src/base-client/components/common/XAddNativeFormOA/index.js +3 -3
  106. package/src/base-client/components/common/XAddNativeFormOA/index.md +146 -146
  107. package/src/base-client/components/common/XAddReport/index.js +3 -3
  108. package/src/base-client/components/common/XAddReport/index.md +56 -56
  109. package/src/base-client/components/common/XBadge/XBadge.vue +94 -94
  110. package/src/base-client/components/common/XButtons/XButtonDemo.vue +28 -28
  111. package/src/base-client/components/common/XButtons/index.js +3 -3
  112. package/src/base-client/components/common/XButtons/index.md +61 -61
  113. package/src/base-client/components/common/XCard/XCard.vue +64 -64
  114. package/src/base-client/components/common/XCheckList/XCheckList.vue +106 -106
  115. package/src/base-client/components/common/XCheckList/XCheckListDemo.vue +41 -41
  116. package/src/base-client/components/common/XDataCard/index.js +3 -3
  117. package/src/base-client/components/common/XDataCard/index.md +1 -1
  118. package/src/base-client/components/common/XDataDrawer/XDataDrawer.vue +180 -180
  119. package/src/base-client/components/common/XDataDrawer/index.js +3 -3
  120. package/src/base-client/components/common/XDataDrawer/index.md +41 -41
  121. package/src/base-client/components/common/XDatePicker/demo.vue +153 -153
  122. package/src/base-client/components/common/XDescriptions/index.js +3 -3
  123. package/src/base-client/components/common/XDescriptions/index.md +83 -83
  124. package/src/base-client/components/common/XDetailsView/XDetailsView.vue +238 -238
  125. package/src/base-client/components/common/XDetailsView/index.js +3 -3
  126. package/src/base-client/components/common/XForm/XFormItem.vue +1504 -1503
  127. package/src/base-client/components/common/XForm/XStatusButton.vue +54 -54
  128. package/src/base-client/components/common/XForm/index.md +178 -178
  129. package/src/base-client/components/common/XForm/itemComponent/XClickChangeBtn/index.vue +49 -49
  130. package/src/base-client/components/common/XFormGroup/index.js +3 -3
  131. package/src/base-client/components/common/XFormGroup/index.md +38 -38
  132. package/src/base-client/components/common/XFormGroupDetails/XFormGroupDetails.vue +72 -72
  133. package/src/base-client/components/common/XFormGroupDetails/index.js +3 -3
  134. package/src/base-client/components/common/XFormTable/index.md +92 -92
  135. package/src/base-client/components/common/XLabelSelect/XLabelSelect.vue +110 -110
  136. package/src/base-client/components/common/XLabelSelect/XLabelSelectDemo.vue +35 -35
  137. package/src/base-client/components/common/XLicensePlate/XLicensePlate.vue +193 -193
  138. package/src/base-client/components/common/XLicensePlate/XLicensePlateDemo.vue +48 -48
  139. package/src/base-client/components/common/XPrint/OpenInvoice.vue +21 -21
  140. package/src/base-client/components/common/XPrint/PrintHtml.js +98 -98
  141. package/src/base-client/components/common/XPrint/css/hiPrintCss.js +359 -359
  142. package/src/base-client/components/common/XPrint/css/lodopCss.js +26 -26
  143. package/src/base-client/components/common/XPrint/css/print-lock.css +351 -351
  144. package/src/base-client/components/common/XPrint/index.vue +97 -97
  145. package/src/base-client/components/common/XReport/XReportDesign.vue +463 -463
  146. package/src/base-client/components/common/XReport/XReportJsonRender.vue +381 -381
  147. package/src/base-client/components/common/XReport/index.js +3 -3
  148. package/src/base-client/components/common/XReport/print.js +186 -186
  149. package/src/base-client/components/common/XReportDrawer/index.js +3 -3
  150. package/src/base-client/components/common/XReportGrid/XReportTrGroup.vue +4 -1
  151. package/src/base-client/components/common/XReportGrid/index.js +3 -3
  152. package/src/base-client/components/common/XReportGrid/index.md +44 -44
  153. package/src/base-client/components/common/XReportSlot/XReportSlot.vue +110 -110
  154. package/src/base-client/components/common/XReportSlot/index.js +3 -3
  155. package/src/base-client/components/common/XReportSlot/index.md +48 -48
  156. package/src/base-client/components/common/XSimpleDescriptions/XSimpleDescriptions.vue +166 -166
  157. package/src/base-client/components/common/XSimpleDescriptions/index.js +3 -3
  158. package/src/base-client/components/common/XSimpleDescriptions/index.md +7 -7
  159. package/src/base-client/components/common/XStepView/XStepView.vue +252 -252
  160. package/src/base-client/components/common/XStepView/index.js +3 -3
  161. package/src/base-client/components/common/XStepView/index.md +31 -31
  162. package/src/base-client/components/common/XTab/XTabDemo.vue +22 -22
  163. package/src/base-client/components/common/XTab/index.js +3 -3
  164. package/src/base-client/components/common/XTable/CustomFuncCel.vue +51 -51
  165. package/src/base-client/components/common/XTable/TableCellRenderer.vue +161 -161
  166. package/src/base-client/components/common/XTable/index.md +255 -255
  167. package/src/base-client/components/common/XTagGroup/index.vue +52 -52
  168. package/src/base-client/components/common/XTree/XTree.vue +424 -424
  169. package/src/base-client/components/common/XTree/index.js +3 -3
  170. package/src/base-client/components/common/XTree/index.md +36 -36
  171. package/src/base-client/components/common/XTreeOne/XTreeOne.vue +113 -113
  172. package/src/base-client/components/common/XTreeOne/XTreeOnePro.vue +128 -128
  173. package/src/base-client/components/common/richTextModal/index.vue +56 -56
  174. package/src/base-client/components/common/richTextModal/richDemo.vue +48 -48
  175. package/src/base-client/components/his/XHisEditor/index.js +3 -3
  176. package/src/base-client/components/index.js +51 -51
  177. package/src/base-client/components/layout/XTreeView/XTreeView.vue +130 -130
  178. package/src/base-client/components/layout/XTreeView/index.js +3 -3
  179. package/src/base-client/components/layout/XTreeView/index.md +46 -46
  180. package/src/base-client/components/system/DictionaryDetailsView/DictionaryDetailsView.vue +232 -232
  181. package/src/base-client/components/system/QueryParamsDetailsView/QueryParamsDetailsView.vue +281 -281
  182. package/src/base-client/plugins/Config.js +19 -19
  183. package/src/base-client/plugins/GetLoginInfoService.js +183 -183
  184. package/src/base-client/plugins/Recording.js +258 -258
  185. package/src/base-client/plugins/index.js +23 -23
  186. package/src/base-client/plugins/tabs-page-plugin.js +39 -39
  187. package/src/components/Charts/Bar.vue +62 -62
  188. package/src/components/Charts/ChartCard.vue +134 -134
  189. package/src/components/Charts/Liquid.vue +67 -67
  190. package/src/components/Charts/MiniArea.vue +39 -39
  191. package/src/components/Charts/MiniBar.vue +39 -39
  192. package/src/components/Charts/MiniProgress.vue +75 -75
  193. package/src/components/Charts/MiniSmoothArea.vue +40 -40
  194. package/src/components/Charts/Radar.vue +68 -68
  195. package/src/components/Charts/RankList.vue +77 -77
  196. package/src/components/Charts/TagCloud.vue +113 -113
  197. package/src/components/Charts/TransferBar.vue +64 -64
  198. package/src/components/Charts/Trend.vue +82 -82
  199. package/src/components/Charts/chart.less +12 -12
  200. package/src/components/Charts/smooth.area.less +13 -13
  201. package/src/components/CodeMirror/inedx.vue +118 -118
  202. package/src/components/CodeMirror/setting.js +40 -40
  203. package/src/components/FileImageItem/FileItem.vue +320 -320
  204. package/src/components/NumberInfo/NumberInfo.vue +54 -54
  205. package/src/components/NumberInfo/index.js +3 -3
  206. package/src/components/NumberInfo/index.less +54 -54
  207. package/src/components/NumberInfo/index.md +43 -43
  208. package/src/components/card/ChartCard.vue +79 -79
  209. package/src/components/chart/Bar.vue +60 -60
  210. package/src/components/chart/MiniArea.vue +67 -67
  211. package/src/components/chart/MiniBar.vue +59 -59
  212. package/src/components/chart/MiniProgress.vue +57 -57
  213. package/src/components/chart/Radar.vue +80 -80
  214. package/src/components/chart/RankingList.vue +60 -60
  215. package/src/components/chart/Trend.vue +79 -79
  216. package/src/components/chart/index.less +9 -9
  217. package/src/components/checkbox/ColorCheckbox.vue +157 -157
  218. package/src/components/checkbox/ImgCheckbox.vue +117 -117
  219. package/src/components/checkbox/ImgCheckboxGroup.vue +76 -76
  220. package/src/components/checkbox/index.js +9 -9
  221. package/src/components/exception/ExceptionPage.vue +70 -70
  222. package/src/components/g2Charts/constants.js +202 -202
  223. package/src/components/g2Charts/demo.vue +808 -808
  224. package/src/components/g2Charts/designer.vue +228 -228
  225. package/src/components/g2Charts/designerBaseConfig.vue +61 -61
  226. package/src/components/g2Charts/designerDataConfig.vue +259 -259
  227. package/src/components/g2Charts/designerStyleConfig.vue +16 -16
  228. package/src/components/g2Charts/index.vue +397 -397
  229. package/src/components/index.js +36 -36
  230. package/src/components/input/IInput.vue +66 -66
  231. package/src/components/menu/SideMenu.vue +75 -75
  232. package/src/components/menu/menu.js +273 -273
  233. package/src/components/setting/Setting.vue +234 -234
  234. package/src/components/tool/AStepItem.vue +60 -60
  235. package/src/config/CreateQueryConfig.js +325 -325
  236. package/src/config/default/antd.config.js +89 -89
  237. package/src/config/default/setting.config.js +55 -55
  238. package/src/font-style/font.css +60 -60
  239. package/src/layouts/CommonLayout.vue +56 -56
  240. package/src/layouts/PageLayout.vue +151 -151
  241. package/src/layouts/SinglePageView.vue +136 -136
  242. package/src/layouts/header/AdminHeader.vue +132 -132
  243. package/src/layouts/header/HeaderNotice.vue +177 -177
  244. package/src/layouts/header/InstitutionDetail.vue +181 -181
  245. package/src/layouts/tabs/TabsHead.vue +189 -189
  246. package/src/lib.js +1 -1
  247. package/src/mock/extend/index.js +84 -84
  248. package/src/mock/goods/index.js +108 -108
  249. package/src/pages/DefaultExample/index.vue +77 -77
  250. package/src/pages/DynamicStatistics/ChartSelector.vue +331 -331
  251. package/src/pages/DynamicStatistics/DataTabs.vue +83 -83
  252. package/src/pages/DynamicStatistics/DynamicTable.vue +128 -128
  253. package/src/pages/DynamicStatistics/EvaluationArea.vue +69 -69
  254. package/src/pages/DynamicStatistics/FavoriteList.vue +50 -50
  255. package/src/pages/DynamicStatistics/QuestionHistoryAndFavorites.vue +591 -591
  256. package/src/pages/DynamicStatistics/SearchBar.vue +192 -192
  257. package/src/pages/DynamicStatistics/index.vue +282 -282
  258. package/src/pages/Example/childIndex.vue +15 -15
  259. package/src/pages/Example/index.vue +30 -30
  260. package/src/pages/NewDynamicStatistics/ChartSelector.vue +331 -331
  261. package/src/pages/NewDynamicStatistics/DataTabs.vue +122 -122
  262. package/src/pages/NewDynamicStatistics/DynamicTable.vue +128 -128
  263. package/src/pages/NewDynamicStatistics/EvaluationArea.vue +69 -69
  264. package/src/pages/NewDynamicStatistics/FavoriteList.vue +50 -50
  265. package/src/pages/NewDynamicStatistics/QuestionHistoryAndFavorites.vue +289 -289
  266. package/src/pages/NewDynamicStatistics/SearchBar.vue +193 -193
  267. package/src/pages/NewDynamicStatistics/index.vue +258 -258
  268. package/src/pages/Recording/index.vue +77 -77
  269. package/src/pages/ServiceReview/index.vue +284 -284
  270. package/src/pages/SubExample/index.vue +26 -26
  271. package/src/pages/WorkflowDetail/WorkflowPageDetail/TrimTextTail.vue +23 -23
  272. package/src/pages/WorkflowDetail/WorkflowPageDetail/WorkFlowHandle.vue +1766 -1766
  273. package/src/pages/XReportView/index.vue +64 -64
  274. package/src/pages/XTreeOneProExample/index.vue +67 -67
  275. package/src/pages/dashboard/workplace/WorkPlace.vue +141 -141
  276. package/src/pages/login/Login.vue +379 -379
  277. package/src/pages/login/LoginV3.vue +389 -389
  278. package/src/pages/lowCode/lowCodeEditor.vue +1219 -1219
  279. package/src/pages/lowCode/lowCodeRenderPage.vue +43 -43
  280. package/src/pages/report/ReportTable.js +124 -124
  281. package/src/pages/resourceManage/orgListManage.vue +98 -98
  282. package/src/pages/system/dictionary/index.vue +44 -44
  283. package/src/pages/system/monitor/loginInfor/index.vue +37 -37
  284. package/src/pages/system/monitor/operLog/index.vue +37 -37
  285. package/src/pages/system/settings/modifyPassword.vue +117 -117
  286. package/src/pages/system/ticket/index.vue +480 -480
  287. package/src/pages/system/ticket/submitTicketSuccess.vue +484 -484
  288. package/src/pages/userInfoDetailManage/ChangeMeterRecordQuery/index.vue +64 -64
  289. package/src/pages/userInfoDetailManage/InfoChangeRecordQuery/index.vue +64 -64
  290. package/src/pages/userInfoDetailManage/InstructRecordQuery/index.vue +64 -64
  291. package/src/pages/userInfoDetailManage/MeterParamRecordQuery/index.vue +64 -64
  292. package/src/pages/userInfoDetailManage/TransferRecordQuery/index.vue +66 -66
  293. package/src/pages/userInfoDetailManage/WatchCollectionRecordQuery/index.vue +64 -64
  294. package/src/plugins/EventLogPlugin.js +33 -33
  295. package/src/plugins/FindParentsData.js +17 -17
  296. package/src/router/async/config.async.js +35 -35
  297. package/src/router/index.js +27 -27
  298. package/src/services/DataModel.js +30 -30
  299. package/src/services/LodopFuncs.js +137 -137
  300. package/src/services/api/TicketDetailsViewApi.js +46 -46
  301. package/src/services/api/cas.js +79 -79
  302. package/src/services/api/common.js +346 -346
  303. package/src/services/api/entity.js +18 -18
  304. package/src/services/api/index.js +17 -17
  305. package/src/store/modules/account.js +115 -115
  306. package/src/store/modules/index.js +5 -5
  307. package/src/store/modules/lowCode.js +33 -33
  308. package/src/store/modules/setting.js +119 -119
  309. package/src/theme/default/style.less +58 -58
  310. package/src/utils/authority-utils.js +85 -85
  311. package/src/utils/errorCode.js +6 -6
  312. package/src/utils/formatter.js +74 -74
  313. package/src/utils/htmlToPDF.js +108 -108
  314. package/src/utils/htmlToPDFApi.js +5 -5
  315. package/src/utils/login.js +188 -188
  316. package/src/utils/lowcode/lowcodeComponentMixin.js +120 -120
  317. package/src/utils/lowcode/lowcodeLog.js +29 -29
  318. package/src/utils/lowcode/lowcodeUtils.js +373 -373
  319. package/src/utils/lowcode/registerComponentForEditor.js +1 -1
  320. package/src/utils/lowcode/registerComponentForRender.js +11 -11
  321. package/src/utils/map-utils.js +47 -47
  322. package/src/utils/reg.js +95 -95
  323. package/src/utils/runEvalFunction.js +14 -14
  324. package/src/utils/theme-color-replacer-extend.js +92 -92
  325. package/src/utils/util.js +329 -329
  326. package/src/utils/waterMark.js +31 -31
  327. package//350/277/201/347/247/273/346/227/245/345/277/227.md +15 -15
@@ -1,1503 +1,1504 @@
1
- <template>
2
- <!-- 输入框 -->
3
- <x-form-col
4
- v-if="attr.type === 'input' && show"
5
- :occupyCol="attr.occupyCol"
6
- :labelCol="labelCol"
7
- :flex="attr.flex">
8
- <a-form-model-item
9
- v-bind="bindOther"
10
- :rules="rules"
11
- :ref="attr.model"
12
- :label="showLabel?attr.name:undefined"
13
- :prop="attr.prop ? attr.prop : attr.model">
14
- <!-- 如果配置了后置按钮插槽 -->
15
- <a-input-group
16
- v-if="((attr.inputOnAfterName && attr.inputOnAfterFunc) || (attr.inputOnAfterIcon && attr.inputOnAfterIconFunc)) && mode !== '查询'"
17
- style="display: flex; width: 100%; padding: 4px 0"
18
- compact>
19
- <a-input
20
- v-model="form[attr.model]"
21
- :read-only="readOnly"
22
- :disabled="disabled && !readOnly"
23
- :whitespace="true"
24
- @input="attr.dataChangeFunc && debouncedDataChangeFunc()"
25
- :suffix="attr.inputSuffix && mode !== '新增' ? attr.inputSuffix : ''"
26
- @blur="mode !== '查询' && attr.inputOnBlurFunc && emitFunc(attr.inputOnBlurFunc,attr)"
27
- @keyup.enter="mode !== '查询' && attr.inputOnEnterFunc && emitFunc(attr.inputOnEnterFunc, attr)"
28
- :placeholder="attr.placeholder ? attr.placeholder : '请输入'+attr.name.replace(/\s*/g, '')"
29
- :ref="`${attr.model}input`"/>
30
- <a-button
31
- v-if="attr.inputOnAfterName && attr.inputOnAfterFunc && !attr.inputOnAfterName.includes('|')"
32
- style="width: auto; min-width: 4rem;max-width: 6rem"
33
- type="primary"
34
- @click="emitFunc(attr.inputOnAfterFunc,attr)">
35
- {{ attr.inputOnAfterName }}
36
- </a-button>
37
- <!-- 仅可以配置 一个按钮 以及 一个图标插槽 -->
38
- <a-button
39
- style="width: 2rem; flex-shrink: 0;"
40
- v-else-if="attr.inputOnAfterIcon"
41
- :type="attr.inputOnAfterIcon && attr.inputOnAfterName ? 'primary' :''"
42
- :icon="attr.inputOnAfterIcon || 'question'"
43
- @click="emitFunc(attr.inputOnAfterIconFunc,attr)">
44
- </a-button>
45
- <!-- 状态按钮 -->
46
- <x-status-button
47
- v-else
48
- :states="parseStates(attr.inputOnAfterName, attr.inputOnAfterFunc)"
49
- v-on="generateDynamicEvents(attr.inputOnAfterFunc, attr)"
50
- style="width: auto; min-width: 4rem; max-width: 6rem"
51
- />
52
- </a-input-group>
53
- <a-input-number
54
- v-else-if="attr.numberInput && !readOnly"
55
- v-model="form[attr.model]"
56
- :whitespace="true"
57
- @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
58
- :disabled="disabled && !readOnly"
59
- style="width:100%"
60
- @blur="mode !== '查询' && attr.inputOnBlurFunc && emitFunc(attr.inputOnBlurFunc,attr)"
61
- @keyup.enter="mode !== '查询' && attr.inputOnEnterFunc && emitFunc(attr.inputOnEnterFunc, attr)"
62
- :suffix="attr.inputSuffix && mode !== '新增' ? attr.inputSuffix : ''"
63
- :placeholder="attr.placeholder ? attr.placeholder : '请输入'+attr.name.replace(/\s*/g, '')"
64
- :ref="`${attr.model}input`"/>
65
- <a-input
66
- v-else
67
- v-model="form[attr.model]"
68
- :whitespace="true"
69
- :read-only="readOnly"
70
- :disabled="disabled && !readOnly"
71
- @input="attr.dataChangeFunc && debouncedDataChangeFunc()"
72
- :suffix="attr.inputSuffix && mode !== '新增' ? attr.inputSuffix : ''"
73
- style="width:100%"
74
- @blur="mode !== '查询' && attr.inputOnBlurFunc && emitFunc(attr.inputOnBlurFunc,attr)"
75
- @keyup.enter="mode !== '查询' && attr.inputOnEnterFunc && emitFunc(attr.inputOnEnterFunc, attr)"
76
- :placeholder="attr.placeholder ? attr.placeholder : '请输入'+attr.name.replace(/\s*/g, '')"
77
- :ref="`${attr.model}input`"/>
78
- </a-form-model-item>
79
- </x-form-col>
80
- <!-- 下拉框 -->
81
- <x-form-col
82
- v-else-if="attr.type === 'select' && show"
83
- :labelCol="labelCol"
84
- :flex="attr.flex">
85
- <a-form-model-item
86
- v-bind="bindOther"
87
- :rules="rules"
88
- v-if="!attr.showMode || mode === '查询' || attr.showMode === 'select' "
89
- :ref="attr.model"
90
- :label="showLabel?attr.name:undefined"
91
- :prop="attr.prop ? attr.prop : attr.model">
92
- <!-- <span slot="label" class="label-box">{{ showLabel?attr.name:undefined }}</span>-->
93
- <a-select
94
- v-if="!attr.lazyLoad || attr.lazyLoad === 'false'"
95
- v-model="form[attr.model]"
96
- :disabled="disabled"
97
- @change="handleSelectChange"
98
- :filter-option="filterOption"
99
- :getPopupContainer="getPopupContainer"
100
- dropdownClassName="custom-dropdown"
101
- :dropdownMatchSelectWidth="false"
102
- :dropdownStyle="{ position: 'absolute'}"
103
- :placeholder="attr.placeholder ? attr.placeholder : '请选择'"
104
- show-search
105
- :allowClear="true"
106
- :getCalendarContainer="(triggerNode) => triggerNode.parentNode"
107
- >
108
- <a-select-option
109
- v-if="mode === '查询'"
110
- key="999999"
111
- value="">全部
112
- </a-select-option>
113
- <template v-if="attr.keys">
114
- <a-select-option
115
- v-for="(item,index) in attr.keys"
116
- :key="index.value"
117
- :value="item.value + ''">
118
- {{ item.label }}
119
- </a-select-option>
120
- </template>
121
- <template v-else>
122
- <template
123
- v-if="attr.keyName.indexOf('logic@') !== -1 || attr.keyName.indexOf('config@') !== -1
124
- ||attr.keyName.indexOf('search@') !== -1 || attr.keyName.indexOf('search@') !== -1">
125
- <a-select-option
126
- v-for="(item,index) in option"
127
- :key="index.value"
128
- :value="item.value + ''">
129
- <template v-if="attr.keyName.indexOf('config@') !== -1 && item.status">
130
- <!-- 徽标(badge) -->
131
- <a-badge v-if="item.status !== 'gary'" :color="item.status" :text="item.label"/>
132
- <a-badge v-else color="#D9D9D9" :text="item.label"/>
133
- </template>
134
- <template v-else>
135
- {{ item.label }}
136
- </template>
137
- </a-select-option>
138
- </template>
139
- <template
140
- v-else-if="attr.keyName.indexOf('async ') !== -1 || attr.keyName.indexOf('function ') !== -1">
141
- <a-select-option
142
- v-for="(item,index) in optionForFunc"
143
- :key="index.value"
144
- :value="item.value + ''">
145
- <template>
146
- {{ item.label }}
147
- </template>
148
- </a-select-option>
149
- </template>
150
- <template v-else>
151
- <a-select-option
152
- v-for="item in $appdata.getDictionaryList(attr.keyName)"
153
- :key="item.value"
154
- :value="item.value + ''">
155
- <!-- 徽标(badge) -->
156
- <x-badge
157
- :badge-key="attr.keyName"
158
- :replaceText="item.text"
159
- :value="item.value"
160
- :service-name="serviceName"
161
- :env="env"/>
162
- </a-select-option>
163
- </template>
164
- </template>
165
- </a-select>
166
- <a-select
167
- v-else
168
- v-model="form[attr.model]"
169
- :disabled="disabled"
170
- @change="handleSelectChange"
171
- :filter-option="filterOption"
172
- :getPopupContainer="getPopupContainer"
173
- dropdownClassName="custom-dropdown"
174
- :dropdownMatchSelectWidth="false"
175
- :dropdownStyle="{ position: 'absolute'}"
176
- :placeholder="attr.placeholder ? attr.placeholder : '搜索' + attr.name"
177
- show-search
178
- @search="fetchFunction"
179
- >
180
- <template #notFoundContent>
181
- <a-spin v-if="searching" size="small"/>
182
- </template>
183
- <a-select-option
184
- v-if="mode === '查询'"
185
- key="999999"
186
- value="">全部
187
- </a-select-option>
188
- <a-select-option
189
- v-for="(item,index) in option"
190
- :key="index"
191
- :value="item.value + ''">{{ item.label }}
192
- </a-select-option>
193
- </a-select>
194
- </a-form-model-item>
195
- <a-form-model-item
196
- v-bind="bindOther"
197
- :rules="rules"
198
- v-else-if="attr.showMode === 'radioGroup'"
199
- :ref="attr.model"
200
- :label="showLabel?attr.name:undefined"
201
- :prop="attr.prop ? attr.prop : attr.model">
202
- <a-radio-group v-model="form[attr.model]">
203
- <a-radio-button v-for="modeItem in option" :key="modeItem.value" :value="modeItem.value">
204
- {{ modeItem.label }}
205
- </a-radio-button>
206
- </a-radio-group>
207
- </a-form-model-item>
208
- <a-form-model-item
209
- v-bind="bindOther"
210
- v-else-if="attr.showMode === 'clickChange' && option.length > 0"
211
- :ref="attr.model"
212
- :label="showLabel?attr.name:undefined"
213
- :prop="attr.prop ? attr.prop : attr.model">
214
- <XClickChangeBtn></XClickChangeBtn>
215
- </a-form-model-item>
216
- </x-form-col>
217
- <!-- 多选框 -->
218
- <x-form-col
219
- v-else-if="attr.type === 'checkbox' && show"
220
- :labelCol="labelCol"
221
- :flex="attr.flex">
222
- <a-form-model-item
223
- v-bind="bindOther"
224
- :rules="rules"
225
- v-if="!attr.showMode || mode === '查询' || attr.showMode === 'select' "
226
- :ref="attr.model"
227
- :label="showLabel?attr.name:undefined"
228
- :prop="attr.prop ? attr.prop : attr.model">
229
- <a-select
230
- class="multiple_select"
231
- style="width:100%"
232
- v-if="!attr.lazyLoad || attr.lazyLoad === 'false'"
233
- v-model="form[attr.model]"
234
- :disabled="disabled"
235
- :filter-option="filterOption"
236
- :getPopupContainer="getPopupContainer"
237
- :placeholder="attr.placeholder ? attr.placeholder : '请选择'"
238
- @change="handleCheckboxChange"
239
- mode="multiple"
240
- show-search
241
- allowClear
242
- >
243
- <template v-if="attr.keys">
244
- <a-select-option
245
- v-for="(item,index) in attr.keys"
246
- :key="index"
247
- :value="item.value + ''">
248
- {{ item.label }}
249
- </a-select-option>
250
- </template>
251
- <template v-else>
252
- <template
253
- v-if="attr.keyName.indexOf('logic@') !== -1 || attr.keyName.indexOf('config@') !== -1
254
- ||attr.keyName.indexOf('search@') !== -1 || attr.keyName.indexOf('search@') !== -1">
255
- <a-select-option
256
- v-for="(item,index) in option"
257
- :key="index"
258
- :value="item.value">{{ item.label }}
259
- </a-select-option>
260
- </template>
261
- <template v-else>
262
- <a-select-option
263
- v-for="item in $appdata.getDictionaryList(attr.keyName)"
264
- :key="item.value"
265
- :value="item.value + ''">{{ item.text }}
266
- </a-select-option>
267
- </template>
268
- </template>
269
- </a-select>
270
- <a-select
271
- v-else
272
- class="multiple_select"
273
- v-model="form[attr.model]"
274
- :disabled="disabled"
275
- :filter-option="filterOption"
276
- :getPopupContainer="getPopupContainer"
277
- :placeholder="attr.placeholder ? attr.placeholder : '搜索' + attr.name"
278
- mode="multiple"
279
- style="width:100%"
280
- @change="handleCheckboxChange"
281
- show-search
282
- allowClear
283
- @search="fetchFunction"
284
- >
285
- <template #notFoundContent>
286
- <a-spin v-if="searching" size="small"/>
287
- </template>
288
- <a-select-option
289
- v-for="(item,index) in option"
290
- :key="index"
291
- :value="item.value + ''">{{ item.label }}
292
- </a-select-option>
293
- </a-select>
294
- </a-form-model-item>
295
- <a-form-model-item
296
- v-bind="bindOther"
297
- :rules="rules"
298
- v-else
299
- :ref="attr.model"
300
- :label="showLabel?attr.name:undefined"
301
- :prop="attr.prop ? attr.prop : attr.model">
302
- <a-checkbox-group
303
- v-model="form[attr.model]"
304
- :options="option"
305
- @change="handleCheckboxChange"
306
- />
307
- </a-form-model-item>
308
- </x-form-col>
309
- <!-- 单选框 -->
310
- <x-form-col
311
- v-else-if="attr.type === 'radio' && show"
312
- :labelCol="labelCol"
313
- :flex="attr.flex">
314
- <a-form-model-item
315
- v-bind="bindOther"
316
- :rules="rules"
317
- v-if="!attr.showMode || attr.type === 'radio' "
318
- :ref="attr.model"
319
- :label="showLabel?attr.name:undefined"
320
- :prop="attr.prop ? attr.prop : attr.model">
321
- <a-radio-group
322
- v-model="form[attr.model]"
323
- @change="handleRadioChange"
324
- >
325
- <template v-if="attr.keys">
326
- <a-radio v-for="(item,index) in attr.keys" :key="index" :value="item.value">
327
- {{ item.label }}
328
- </a-radio>
329
- </template>
330
- <template v-else>
331
- <template
332
- v-if="attr.keyName.indexOf('logic@') !== -1 || attr.keyName.indexOf('config@') !== -1
333
- ||attr.keyName.indexOf('search@') !== -1 || attr.keyName.indexOf('search@') !== -1">
334
- <a-radio v-for="(item,index) in option" :key="index" :value="item.value">
335
- {{ item.label }}
336
- </a-radio>
337
- </template>
338
- <template v-else>
339
- <a-radio v-for="(item,index) in $appdata.getDictionaryList(attr.keyName)" :key="index" :value="item.value">
340
- {{ item.text }}
341
- </a-radio>
342
- </template>
343
- </template>
344
- </a-radio-group>
345
- </a-form-model-item>
346
- <a-form-model-item
347
- v-bind="bindOther"
348
- :rules="rules"
349
- v-else-if="attr.showMode === 'radioGroup'"
350
- :ref="attr.model"
351
- :label="showLabel?attr.name:undefined"
352
- :prop="attr.prop ? attr.prop : attr.model">
353
- <a-radio-group v-model="form[attr.model]">
354
- <a-radio-button v-for="modeItem in option" :key="modeItem.value" :value="modeItem.value">
355
- {{ modeItem.label }}
356
- </a-radio-button>
357
- </a-radio-group>
358
- </a-form-model-item>
359
- <a-form-model-item
360
- v-bind="bindOther"
361
- :rules="rules"
362
- v-else-if="attr.showMode === 'clickChange' && option.length > 0"
363
- :ref="attr.model"
364
- :label="showLabel?attr.name:undefined"
365
- :prop="attr.prop ? attr.prop : attr.model">
366
- <XClickChangeBtn></XClickChangeBtn>
367
- </a-form-model-item>
368
- </x-form-col>
369
- <!-- 时间 日期 框整合 -->
370
- <x-form-col
371
- v-else-if="['datePicker', 'rangePicker', 'yearPicker', 'monthPicker', 'yearRangePicker', 'monthRangePicker'].includes(attr.type) && show"
372
- :labelCol="labelCol"
373
- :flex="attr.flex">
374
- <a-form-model-item
375
- v-bind="bindOther"
376
- :rules="rules"
377
- :ref="attr.model"
378
- :label="showLabel?attr.name:undefined"
379
- :prop="attr.prop ? attr.prop : attr.model">
380
- <XFormDatePicker
381
- :attr="attr"
382
- :mode="mode"
383
- :disabled="disabled"
384
- :readOnly="readOnly"
385
- :showLabel="showLabel"
386
- @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
387
- v-model="form[attr.model]"/>
388
- </a-form-model-item>
389
- </x-form-col>
390
- <!-- 文本域 -->
391
- <x-form-col
392
- v-else-if="attr.type === 'textarea' && show"
393
- :labelCol="labelCol"
394
- :flex="attr.flex">
395
- <!-- :style="layout === 'inline'?{width:'calc(100% - 60px)'}:{}"-->
396
- <a-form-model-item
397
- v-bind="bindOther"
398
- :rules="rules"
399
- :ref="attr.model"
400
- :label="showLabel?attr.name:undefined"
401
- :prop="attr.prop ? attr.prop : attr.model">
402
- <a-textarea
403
- v-model="form[attr.model]"
404
- style="width: 100%;"
405
- :disabled="disabled"
406
- :placeholder="attr.placeholder ? attr.placeholder : '请输入'+attr.name.replace(/\s*/g, '')"
407
- :rows="4"/>
408
- </a-form-model-item>
409
- </x-form-col>
410
- <!-- 文件上传 -->
411
- <x-form-col
412
- v-else-if="(attr.type === 'file' || attr.type === 'image') && show"
413
- :labelCol="labelCol"
414
- :flex="attr.flex">
415
- <a-form-model-item
416
- v-bind="bindOther"
417
- :rules="rules"
418
- :ref="attr.model"
419
- :label="showLabel?attr.name:undefined"
420
- :prop="attr.prop ? attr.prop : attr.model">
421
- <upload
422
- :files="files"
423
- :images="images"
424
- :model="attr"
425
- v-bind="attr"
426
- :service-name="serviceName"
427
- @setFiles="setFiles"></upload>
428
- </a-form-model-item>
429
- </x-form-col>
430
- <!-- 省市区选择框 -->
431
- <x-form-col
432
- v-else-if="attr.type === 'citySelect' && show"
433
- :labelCol="labelCol"
434
- :flex="attr.flex">
435
- <a-form-model-item
436
- v-bind="bindOther"
437
- :rules="rules"
438
- :ref="attr.model"
439
- :label="showLabel?attr.name:undefined"
440
- :prop="attr.prop ? attr.prop : attr.model">
441
- <citySelect
442
- @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
443
- ref="citySelect"
444
- v-model="form[attr.model]"
445
- :contexts="attr.contexts"
446
- :value-type="attr.valueType"
447
- :default-value="form[attr.model]"></citySelect>
448
- </a-form-model-item>
449
- </x-form-col>
450
- <!-- 地点搜索框 -->
451
- <x-form-col
452
- v-else-if="(attr.type === 'addressSearch' || attr.type === 'coordinateSearch') && show"
453
- :labelCol="labelCol"
454
- :occupyCol="attr.occupyCol"
455
- :flex="attr.flex">
456
- <a-form-model-item
457
- v-bind="bindOther"
458
- :rules="rules"
459
- :ref="attr.model"
460
- :label="showLabel?attr.name:undefined"
461
- :prop="attr.prop ? attr.prop : attr.model">
462
- <address-search-combobox
463
- :emitFunc="emitFunc"
464
- :attr="attr"
465
- :read-only="readOnly"
466
- :searchResult="form[attr.model]"
467
- :address="{ address: form[attr.model], coords: form[`${attr.model}_lng_lat`] }"
468
- :resultKeys="{ address: attr.model, coords: `${attr.model}_lng_lat` }"
469
- ref="addressSearchCombobox"
470
- searchResultType="Object"
471
- @onSelect="addressSearchComboboxSelect"
472
- @onDivisionsChange="onDivisionsChange"
473
- ></address-search-combobox>
474
- </a-form-model-item>
475
- </x-form-col>
476
- <!-- 颜色选择器 -->
477
- <x-form-col
478
- v-else-if="attr.type === 'colorPicker' && show"
479
- :labelCol="labelCol"
480
- :flex="attr.flex">
481
- <a-form-model-item
482
- v-bind="bindOther"
483
- :rules="rules"
484
- :ref="attr.model"
485
- :label="showLabel?attr.name:undefined"
486
- :prop="attr.prop ? attr.prop : attr.model">
487
- <color-picker-combobox
488
- :value="form[attr.model]"
489
- :read-only="readOnly"
490
- @onSelect="colorPickerComboboxSelect"
491
- />
492
- </a-form-model-item>
493
- </x-form-col>
494
- <!-- 人员选择框 -->
495
- <x-form-col
496
- v-else-if="attr.type === 'personSetting' && show"
497
- :labelCol="labelCol"
498
- :flex="attr.flex">
499
- <a-form-model-item
500
- v-bind="bindOther"
501
- :rules="rules"
502
- :ref="attr.model"
503
- :label="showLabel?attr.name:undefined"
504
- :prop="attr.prop ? attr.prop : attr.model">
505
- <PersonSetting v-model="form[attr.model]"></PersonSetting>
506
- </a-form-model-item>
507
- </x-form-col>
508
- <!-- 树形选择框 -->
509
- <x-form-col
510
- v-else-if="attr.type === 'treeSelect' && show"
511
- :labelCol="labelCol"
512
- :flex="attr.flex">
513
- <x-tree-select
514
- :rules="rules"
515
- @onChange="handleTreeSelectChange"
516
- v-model="form[attr.model]"
517
- :attr="attr"
518
- @mounted="itemMounted"
519
- ref="xTreeSelect">
520
- </x-tree-select>
521
- </x-form-col>
522
- <!-- 列表选择框 -->
523
- <x-form-col
524
- v-else-if="attr.type === 'listSelect' && show"
525
- :labelCol="labelCol"
526
- :flex="attr.flex">
527
- <a-form-model-item
528
- v-bind="bindOther"
529
- :rules="rules"
530
- :ref="attr.model"
531
- :label="showLabel?attr.name:undefined"
532
- :style="layout === 'inline'&& attr.occupyCol && attr.occupyCol > 1? {width:`calc(100% - ${attr.occupyCol * 1.533}rem)`}:{}"
533
- :prop="attr.prop ? attr.prop : attr.model">
534
- <a-popover
535
- ref="rowChoosePopover"
536
- :visible="rowChoosePopoverVisible"
537
- title="选择数据"
538
- placement="bottom"
539
- trigger="focus"
540
- :arrowPointAtCenter="true"
541
- :overlayStyle="{ width: '1000px', height: '30vh' }">
542
- <template #content>
543
- <x-report
544
- v-if="isCover"
545
- :use-oss-for-img="false"
546
- :config-name="queryParamsName"
547
- :service-name="serviceName"
548
- :show-img-in-cell="true"
549
- :display-only="true"
550
- :edit-mode="false"
551
- :show-save-button="true"
552
- :no-padding="true"
553
- :dont-format="true"
554
- @rowChoose="rowChoose"
555
- @cancel="closeRowChooseInput"
556
- >
557
- </x-report>
558
- <x-form-table
559
- v-else
560
- title="请选择数据"
561
- :queryParamsName="queryParamsName"
562
- :rowSelectMode="true"
563
- :allowSelectRowNum="1"
564
- :service-name="serviceName"
565
- :fixed-query-form="rowChooseFixedQueryValue"
566
- @rowChoose="rowChoose"
567
- @afterQuery="rowChooseSearchAfterQuery"
568
- ref="rowChooseTable">
569
- <template #button>
570
- <a-button @click="closeRowChooseInput">
571
- 关闭
572
- </a-button>
573
- </template>
574
- </x-form-table>
575
- </template>
576
- <a-input
577
- v-model="form[attr.model]"
578
- :placeholder="attr.placeholder ? attr.placeholder : '请输入'+attr.name.replace(/\s*/g, '')"
579
- @change="searchRowChooseData"
580
- @focus="showCloseRowChooseInput"/>
581
- </a-popover>
582
- </a-form-model-item>
583
- </x-form-col>
584
- <!-- 评分框 -->
585
- <x-form-col
586
- v-else-if="attr.type === 'rate' && show"
587
- :labelCol="labelCol"
588
- :flex="attr.flex">
589
- <a-form-model-item
590
- v-bind="bindOther"
591
- :rules="rules"
592
- :ref="attr.model"
593
- :label="showLabel?attr.name:undefined"
594
- :prop="attr.prop ? attr.prop : attr.model">
595
- <x-rate
596
- v-model="form[attr.model]"
597
- :mode="mode"
598
- :disabled="disabled"
599
- :query-type="attr.queryType"
600
- :max-count="attr.maxCount"
601
- :allow-half="attr.allowHalf"
602
- :icon="attr.rateIcon"
603
- :placeholder="attr.placeholder ? attr.placeholder : '请选择'+attr.name.replace(/\s*/g, '')"
604
- @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
605
- />
606
- </a-form-model-item>
607
- </x-form-col>
608
- <!-- 区间选择器 -->
609
- <x-form-col
610
- v-else-if="attr.type === 'intervalPicker' && show"
611
- :labelCol="labelCol"
612
- :flex="attr.flex">
613
- <a-form-model-item
614
- v-bind="bindOther"
615
- :rules="rules"
616
- :ref="attr.model"
617
- :label="showLabel?attr.name:undefined"
618
- :prop="attr.prop ? attr.prop : attr.model">
619
- <x-interval-picker
620
- v-model="form[attr.model]"
621
- :mode="mode"
622
- :read-only="readOnly"
623
- :disabled="disabled && !readOnly"
624
- :placeholder="attr.placeholder ? attr.placeholder : '请输入'+attr.name.replace(/\s*/g, '')"
625
- :start-placeholder="attr.startPlaceholder || '起始值'"
626
- :end-placeholder="attr.endPlaceholder || '结束值'"
627
- @blur="attr.inputOnBlurFunc && emitFunc(attr.inputOnBlurFunc,attr)"
628
- />
629
- </a-form-model-item>
630
- </x-form-col>
631
- <!-- 车牌号选择 -->
632
- <x-form-col
633
- v-else-if="attr.type === 'licensePlate' && show"
634
- :labelCol="labelCol"
635
- :flex="attr.flex">
636
- <a-form-model-item
637
- v-bind="bindOther"
638
- :rules="rules"
639
- :ref="attr.model"
640
- :label="showLabel?attr.name:undefined"
641
- :style="layout === 'inline'&& attr.occupyCol && attr.occupyCol > 1? {width:`calc(100% - ${attr.occupyCol * 1.533}rem)`}:{}"
642
- :prop="attr.prop ? attr.prop : attr.model">
643
- <!-- 如果配置了后置按钮插槽 -->
644
- <a-input
645
- v-if="mode ==='查询'"
646
- v-model="form[attr.model]"
647
- :whitespace="true"
648
- :read-only="readOnly"
649
- :disabled="disabled && !readOnly"
650
- style="width:100%"
651
- @blur="attr.inputOnBlurFunc && emitFunc(attr.inputOnBlurFunc,attr)"
652
- :placeholder="attr.placeholder ? attr.placeholder : '请输入'+attr.name.replace(/\s*/g, '')"
653
- :ref="`${attr.model}input`"/>
654
- <x-license-plate
655
- v-else
656
- v-model="form[attr.model]"
657
- @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
658
- ></x-license-plate>
659
- </a-form-model-item>
660
- </x-form-col>
661
- <!-- 录音 -->
662
- <x-form-col
663
- v-else-if="attr.type === 'recording' && show"
664
- :labelCol="labelCol"
665
- :flex="attr.flex">
666
- <recording
667
- ref="recording"
668
- @recordingData="recordingData"
669
- >
670
- </recording>
671
- </x-form-col>
672
- <!-- 表格录入 -->
673
- <x-form-col
674
- v-else-if="attr.type === 'rowEdit' && show"
675
- :labelCol="labelCol"
676
- :flex="attr.flex">
677
- <a-form-model-item
678
- v-bind="bindOther"
679
- :rules="rules"
680
- :ref="attr.model"
681
- :label="showLabel?attr.name:undefined"
682
- :prop="attr.prop ? attr.prop : attr.model">
683
- <x-form-table
684
- :key="'childTable_' + attr.model"
685
- :title="attr.name"
686
- :queryParamsName="attr.crud"
687
- :localEditMode="true"
688
- :fixed-query-form="childTableFixedQueryForm(attr)"
689
- :service-name="serviceName"
690
- @hook:mounted="(h)=>onComponentMounted(h, attr)"
691
- :ref="'childXFormTable_' + attr.model">
692
- </x-form-table>
693
- </a-form-model-item>
694
- </x-form-col>
695
- </template>
696
- <script>
697
- import { debounce } from 'ant-design-vue/lib/vc-table/src/utils'
698
- import XFormCol from '@vue2-client/base-client/components/common/XFormCol'
699
- import XBadge from '@vue2-client/base-client/components/common/XBadge'
700
- import CitySelect from '@vue2-client/base-client/components/common/CitySelect'
701
- import PersonSetting from '@vue2-client/base-client/components/common/PersonSetting'
702
- import AddressSearchCombobox from '@vue2-client/base-client/components/common/AddressSearchCombobox'
703
- import Upload from '@vue2-client/base-client/components/common/Upload'
704
- import moment from 'moment'
705
- import { getConfigByName, runLogic, getConfigByNameAsync } from '@vue2-client/services/api/common'
706
- import * as util from '@vue2-client/utils/util'
707
- import XTreeSelect from '@vue2-client/base-client/components/common/XForm/XTreeSelect'
708
- import { searchToListOption, searchToOption } from '@vue2-client/services/v3Api'
709
- import { mapState } from 'vuex'
710
- import { executeStrFunctionByContext } from '@vue2-client/utils/runEvalFunction'
711
- import XLicensePlate from '@vue2-client/base-client/components/common/XLicensePlate/XLicensePlate.vue'
712
- import XStatusButton from './XStatusButton.vue'
713
- import XClickChangeBtn from './itemComponent/XClickChangeBtn'
714
- import 'moment/locale/zh-cn'
715
- import XFormDatePicker from '@vue2-client/base-client/components/common/XDatePicker/index.vue'
716
- import XIntervalPicker from '@vue2-client/base-client/components/common/XIntervalPicker/XIntervalPicker.vue'
717
- import XRate from '@vue2-client/base-client/components/common/XRate/index.vue'
718
- import { post } from '@vue2-client/services/api/restTools'
719
- import ColorPickerCombobox from '@vue2-client/base-client/components/common/ColorPickerCombobox/ColorPickerCombobox.vue'
720
- import { createSelectValueTypeHandler } from '@vue2-client/base-client/plugins/selectValueTypeHelper'
721
-
722
- export default {
723
- name: 'XFormItem',
724
- components: {
725
- XFormDatePicker,
726
- XFormTable: () => import('@vue2-client/base-client/components/common/XFormTable/XFormTable.vue'),
727
- Recording: () => import('@vue2-client/base-client/components/common/Recording/Recording.vue'),
728
- XReport: () => import('@vue2-client/base-client/components/common/XReportGrid/XReport.vue'),
729
- XLicensePlate,
730
- XTreeSelect,
731
- XFormCol,
732
- XBadge,
733
- CitySelect,
734
- PersonSetting,
735
- AddressSearchCombobox,
736
- Upload,
737
- XStatusButton,
738
- XClickChangeBtn,
739
- XIntervalPicker,
740
- XRate,
741
- ColorPickerCombobox
742
- },
743
- data () {
744
- // 检索去抖
745
- this.fetchFunction = debounce(this.fetchFunction, 800)
746
- // 初始化selectValueType处理器
747
- this.selectValueTypeHandler = createSelectValueTypeHandler(this)
748
- return {
749
- option: [],
750
- // 最后检索版本
751
- lastFetchId: 0,
752
- // 检索中
753
- searching: false,
754
- searchResult: '',
755
- optionForFunc: [],
756
- // 控制当前表单项是否展示
757
- show: true,
758
- // moment
759
- moment,
760
- // 行选择器浮层是否显示
761
- rowChoosePopoverVisible: false,
762
- // 行选择器CRUD固定查询值
763
- rowChooseFixedQueryValue: undefined,
764
- bindOther: {}
765
- }
766
- },
767
- props: {
768
- attr: {
769
- type: Object,
770
- default:
771
- () => {
772
- return {}
773
- }
774
- },
775
- form: {
776
- type: Object,
777
- required:
778
- true
779
- },
780
- disabled: {
781
- type: Boolean,
782
- default:
783
- () => {
784
- return false
785
- }
786
- },
787
- readOnly: {
788
- type: Boolean,
789
- default:
790
- () => {
791
- return false
792
- }
793
- },
794
- mode: {
795
- type: String,
796
- default:
797
- () => {
798
- return '查询'
799
- }
800
- },
801
- files: {
802
- type: Array,
803
- default:
804
- () => {
805
- return []
806
- }
807
- },
808
- images: {
809
- type: Array,
810
- default:
811
- () => {
812
- return []
813
- }
814
- },
815
- serviceName: {
816
- type: String,
817
- default:
818
- undefined
819
- },
820
- // 调用logic获取数据源的追加参数
821
- getDataParams: {
822
- type: Object,
823
- default:
824
- undefined
825
- },
826
- // 布局
827
- layout: {
828
- type: String,
829
- default:
830
- 'horizontal'
831
- },
832
- // 环境
833
- env: {
834
- type: String,
835
- default:
836
- () => {
837
- return 'prod'
838
- }
839
- },
840
- // 设置表单值
841
- setForm: {
842
- type: Function,
843
- default: (val) => {
844
- console.log(val)
845
- }
846
- },
847
- showLabel: {
848
- type: Boolean,
849
- default:
850
- () => {
851
- return true
852
- }
853
- },
854
- labelCol: {
855
- type: Object,
856
- default: () => {
857
- return { span: 8 }
858
- }
859
- },
860
- rules: {
861
- type: Array,
862
- default:
863
- () => {
864
- return undefined
865
- }
866
- }
867
- },
868
- provide () {
869
- return {
870
- FormItemContext: this
871
- }
872
- },
873
- created () {
874
- this.init()
875
- if (this.attr.keyName && (this.attr?.keyName?.toString().indexOf('async ') !== -1 || this.attr?.keyName?.toString()?.indexOf('function') !== -1)) {
876
- this.debouncedUpdateOptions = debounce(this.updateOptions, 200)
877
- }
878
- if (this.attr.dataChangeFunc) {
879
- this.debouncedDataChangeFunc = debounce(this.dataChangeFunc, 200)
880
- // 执行一次
881
- this.dataChangeFunc()
882
- }
883
- if (this.attr.showFormItemFunc) {
884
- this.debouncedShowFormItemFunc = debounce(this.showFormItemFunc, 100)
885
- // 执行一次
886
- this.showFormItemFunc()
887
- }
888
- if (this.attr.showQueryFormItemFunc) {
889
- this.debouncedShowQueryFormItemFunc = debounce(this.showQueryFormItemFunc, 100)
890
- // 执行一次
891
- this.showQueryFormItemFunc()
892
- }
893
- // 人员联动框增加监听
894
- if (this?.attr?.keyName?.toString()?.startsWith('search@根据表单项[') && this?.attr?.keyName?.toString().endsWith(']联动人员')) {
895
- this.debouncedUserLinkFunc = debounce(() => this.updateResOptions('人员'), 200)
896
- }
897
- if (this?.attr?.keyName?.toString()?.startsWith('search@根据表单项[') && this?.attr?.keyName?.toString().endsWith(']联动部门')) {
898
- this.debouncedDepLinkFunc = debounce(() => this.updateResOptions('部门'), 200)
899
- }
900
- // xTreeSelect 自己调用 mounted
901
- if (this.attr.type !== 'treeSelect') {
902
- this.$emit('mounted', this.attr)
903
- }
904
- },
905
- computed: {
906
- ...mapState('account', { currUser: 'user', curRoles: 'roles', curPermissions: 'permissions' }),
907
- queryParamsName () {
908
- if (this.attr.keyName.startsWith('function')) {
909
- // 调用异步函数获取内容
910
- const obj = executeStrFunctionByContext(this, this.attr.keyName, [this.form, runLogic, this.mode, getConfigByNameAsync])
911
- // 处理同步返回值
912
- return this.handleQueryParamsResult(obj)
913
- } else if (this.attr.keyName.startsWith('async ')) {
914
- console.warn('此处不支持异步操作')
915
- return ''
916
- } else {
917
- // 按现有方式处理
918
- return this.attr.keyName.split('@')[this.attr.keyName.split('@').length - 1]
919
- }
920
- },
921
- // 判断弹出时是否Cover,弹出只支持Cover以及CRUD
922
- isCover () {
923
- // 如果 queryParamsName 为空,返回空
924
- if (!this.queryParamsName) {
925
- return false
926
- }
927
- const result = this.queryParamsName.endsWith('Cover')
928
- return result
929
- },
930
- },
931
- watch: {
932
- attr: {
933
- handler () {
934
- this.init()
935
- },
936
- deep: true
937
- },
938
- form: {
939
- handler (newVal, oldVal) {
940
- // 如果是从函数获取 options
941
- if (this.attr.keyName && (this.attr.keyName.toString().indexOf('async ') !== -1 || this.attr.keyName.toString().indexOf('function') !== -1)) {
942
- this.debouncedUpdateOptions()
943
- }
944
- // 如果有自定义是否展示表单项函数
945
- if (this.attr.showFormItemFunc) {
946
- this.debouncedShowFormItemFunc()
947
- }
948
- // 如果有自定义是否展示查询表单项函数
949
- if (this.attr.showQueryFormItemFunc) {
950
- this.debouncedShowQueryFormItemFunc()
951
- }
952
- // 地址搜索框赋值
953
- if (this.attr.type === 'addressSearch' || this.attr.type === 'coordinateSearch') {
954
- this.$refs.addressSearchCombobox.addressInput = this.form[this.attr.model]
955
- }
956
- // 数据源来自人员联动时更新数据
957
- if (this?.attr?.keyName?.toString()?.startsWith('search@根据表单项[') && this?.attr?.keyName?.toString().endsWith(']联动人员')) {
958
- this.debouncedUserLinkFunc()
959
- }
960
- // 数据源来自人员联动时更新数据
961
- if (this?.attr?.keyName?.toString()?.startsWith('search@根据表单项[') && this?.attr?.keyName?.toString().endsWith(']联动部门')) {
962
- this.debouncedDepLinkFunc()
963
- }
964
- },
965
- deep: true
966
- }
967
- },
968
- inject: {
969
- getComponentByName: {
970
- default: () => () => {
971
- console.warn('getComponentByName is not provided')
972
- return null // 或者返回一个默认的函数
973
- },
974
- },
975
- registerComponent: {
976
- default: () => () => {
977
- console.warn('registerComponent is not provided')
978
- return null // 或者返回一个默认的函数
979
- },
980
- },
981
- getSelf: {
982
- default: () => () => {
983
- console.warn('getSelf is not provided')
984
- return null // 或者返回一个默认的函数
985
- },
986
- },
987
- XFormContext: {
988
- default: () => () => {
989
- console.warn('XFormContext is not provided')
990
- return null // 或者返回一个默认的函数
991
- },
992
- },
993
- setRequired: {
994
- default: () => () => {
995
- console.warn('setRequired is not provided')
996
- return null // 或者返回一个默认的函数
997
- },
998
- },
999
- removeRequired: {
1000
- default: () => () => {
1001
- console.warn('removeRequired is not provided')
1002
- return null // 或者返回一个默认的函数
1003
- },
1004
- }
1005
- },
1006
- methods: {
1007
- // 处理 queryParams 结果并更新 rowChooseFixedQueryValue
1008
- handleQueryParamsResult (obj) {
1009
- let configName = ''
1010
- if (obj && typeof obj === 'object') {
1011
- // obj 是一个对象,并且不是数组
1012
- if (Object.prototype.hasOwnProperty.call(obj, 'configName')) {
1013
- configName = obj?.configName
1014
- }
1015
- if (Object.prototype.hasOwnProperty.call(obj, 'fixedQueryForm')) {
1016
- if (obj?.fixedQueryForm && typeof obj?.fixedQueryForm === 'object') {
1017
- this.rowChooseFixedQueryValue = Object.assign({}, this.rowChooseFixedQueryValue, obj.fixedQueryForm)
1018
- }
1019
- }
1020
- } else if (obj && typeof obj === 'string') {
1021
- configName = obj
1022
- }
1023
- return configName
1024
- },
1025
- // 根据selectValueType预处理options数据
1026
- processOptionsForValueType (options) {
1027
- return this.selectValueTypeHandler.processOptions(options, this.attr.selectValueType)
1028
- },
1029
-
1030
- // 处理both模式的数据,为表单添加label字段
1031
- processBothModeData () {
1032
- this.selectValueTypeHandler.processBothMode(
1033
- this.form,
1034
- this.attr.model,
1035
- this.attr.selectValueType,
1036
- this.option
1037
- )
1038
- },
1039
-
1040
- // 根据value查找对应的label(支持单选和多选)
1041
- findLabelByValue (value) {
1042
- return this.selectValueTypeHandler.findLabel(value, this.option)
1043
- },
1044
-
1045
- // 统一的表单项change处理逻辑
1046
- handleFormItemChange () {
1047
- // 处理both模式
1048
- if (this.attr.selectValueType === 'both') {
1049
- this.$nextTick(() => {
1050
- this.selectValueTypeHandler.processBothMode(
1051
- this.form,
1052
- this.attr.model,
1053
- this.form[this.attr.model],
1054
- this.option
1055
- )
1056
- })
1057
- }
1058
- // 处理label模式
1059
- if (this.attr.selectValueType === 'label') {
1060
- this.$nextTick(() => {
1061
- this.selectValueTypeHandler.processLabelMode(
1062
- this.form,
1063
- this.attr.model,
1064
- this.form[this.attr.model],
1065
- this.option
1066
- )
1067
- })
1068
- }
1069
- // 处理原有的dataChangeFunc
1070
- if (this.attr.dataChangeFunc) {
1071
- this.debouncedDataChangeFunc()
1072
- }
1073
- },
1074
-
1075
- // Select组件change处理
1076
- handleSelectChange () {
1077
- this.handleFormItemChange()
1078
- },
1079
-
1080
- // Checkbox组件change处理
1081
- handleCheckboxChange () {
1082
- this.handleFormItemChange()
1083
- },
1084
-
1085
- // Radio组件change处理
1086
- handleRadioChange () {
1087
- this.handleFormItemChange()
1088
- },
1089
-
1090
- // TreeSelect组件change处理(通过XTreeSelect组件回调)
1091
- handleTreeSelectChange () {
1092
- this.handleFormItemChange()
1093
- },
1094
-
1095
- // 把内部的crud表单录入放到表单中,以便外部可以调用
1096
- onComponentMounted (h, attr) {
1097
- console.log('crud表单', h)
1098
- if (attr.crud) {
1099
- this.registerComponent(attr.model, this.$refs['childXFormTable_' + attr.model])
1100
- }
1101
- },
1102
- childTableFixedQueryForm (item) {
1103
- console.log('传递的form', this.form)
1104
- if (this.modifyModelData?.primaryKeyData) {
1105
- const fixedForm = {}
1106
- fixedForm[item.childTableForeignKeyName] = Object.values(this.modifyModelData.primaryKeyData)[0]
1107
- return fixedForm
1108
- }
1109
- return null
1110
- },
1111
- // 动态生成事件绑定对象
1112
- generateDynamicEvents (inputOnAfterFunc, attr) {
1113
- const events = {}
1114
- const states = this.parseStates(attr.inputOnAfterName, inputOnAfterFunc)
1115
-
1116
- states.forEach((state) => {
1117
- // 动态绑定事件名到 emitFunc
1118
- events[state.event] = () => {
1119
- console.info('事件名', state.event)
1120
- this.emitFunc(state.event, attr)
1121
- }
1122
- })
1123
-
1124
- return events // 返回 { state1Event: handler, state2Event: handler, ... }
1125
- },
1126
- parseStates (input, events) {
1127
- const eventNames = events.split('|')
1128
- return input.split('|').map((label, index) => ({
1129
- label,
1130
- event: eventNames[index] // 如果没有提供事件名称,则使用默认值
1131
- }))
1132
- },
1133
- focusInput () {
1134
- if (this.attr.defaultFocus) {
1135
- this.$nextTick(h => {
1136
- const el = this.$refs[`${this.attr.model}input`]?.$el
1137
- let inputEl
1138
- if (el) {
1139
- if (el.tagName.toLowerCase() === 'input') {
1140
- inputEl = el
1141
- } else {
1142
- inputEl = el.querySelector('input')
1143
- }
1144
- }
1145
- if (inputEl) {
1146
- inputEl.focus()
1147
- if (inputEl.type === 'number') {
1148
- if (inputEl.valueAsNumber) {
1149
- inputEl.setSelectionRange(0, inputEl.valueAsNumber.toString().length)
1150
- }
1151
- } else {
1152
- if (inputEl.value) {
1153
- inputEl.setSelectionRange(0, inputEl.value.length)
1154
- }
1155
- }
1156
- }
1157
- })
1158
- }
1159
- },
1160
- // 更新人员下拉框数据
1161
- async updateResOptions (type) {
1162
- if (this?.attr?.keyName?.toString()?.startsWith('search@根据表单项[') && this?.attr?.keyName?.toString()?.endsWith(`]联动${type}`)) {
1163
- const startIndex = this.attr.keyName.indexOf('[') + 1
1164
- const endIndex = this.attr.keyName.indexOf(']', startIndex)
1165
- const fromModel = this.attr.keyName.substring(startIndex, endIndex).replace('.', '_')
1166
- // 获取表单字段的实际值(优先使用originData中的原始值)
1167
- const rawFieldValue = this.form.originData && this.form.originData[fromModel]
1168
- ? this.form.originData[fromModel]
1169
- : this.form[fromModel]
1170
-
1171
- // 确保数据为数组格式(用于filter参数)
1172
- const filterValues = Array.isArray(rawFieldValue)
1173
- ? rawFieldValue
1174
- : [rawFieldValue]
1175
- if (fromModel?.length && filterValues?.length) {
1176
- const searchData = {
1177
- source: `获取${type}`,
1178
- userid: this.currUser.id,
1179
- filter: filterValues,
1180
- filterType: fromModel.indexOf('org') > -1 ? 'org' : 'dep'
1181
- }
1182
- const tempArray = []
1183
- await searchToListOption(searchData, res => {
1184
- this.getDataCallback(
1185
- res.filter(h => {
1186
- if (fromModel.indexOf('org') > -1) {
1187
- if (type === '部门') {
1188
- if (filterValues?.includes(h.orgid || h.f_organization_id) || filterValues?.includes(h.parentid) || tempArray.includes(h.parentid)) {
1189
- tempArray.push(h.value)
1190
- return true
1191
- }
1192
- return false
1193
- } else {
1194
- return filterValues?.includes(h.orgid || h.f_organization_id || h.parentid)
1195
- }
1196
- } else {
1197
- return filterValues?.includes(h?.parentid)
1198
- }
1199
- }
1200
- )
1201
- )
1202
- })
1203
- }
1204
- }
1205
- },
1206
- // js 函数作为数据源
1207
- async updateOptions () {
1208
- if (this.attr.keyName && (this.attr.keyName.indexOf('async ') !== -1 || this.attr.keyName.indexOf('function ') !== -1)) {
1209
- const rawOptions = await executeStrFunctionByContext(this, this.attr.keyName, [this.form, runLogic, this.mode, getConfigByNameAsync, post])
1210
- // 根据selectValueType预处理options数据
1211
- this.optionForFunc = this.processOptionsForValueType(rawOptions)
1212
- }
1213
- },
1214
- async dataChangeFunc () {
1215
- if (this.attr.dataChangeFunc) {
1216
- await executeStrFunctionByContext(this, this.attr.dataChangeFunc, [this.form, this.setForm, this.attr, util, this.mode, runLogic, getConfigByNameAsync])
1217
- }
1218
- },
1219
- async showFormItemFunc () {
1220
- if (this.attr.showFormItemFunc) {
1221
- const obj = executeStrFunctionByContext(this, this.attr.showFormItemFunc, [this.form, this.setForm, this.attr, util, this.mode, this.curPermissions, this.curRoles])
1222
- // 判断是 bool 还是 obj 兼容
1223
- if (typeof obj === 'boolean') {
1224
- this.show = obj
1225
- } else if (obj && typeof obj === 'object') {
1226
- // obj 是一个对象,并且不是数组
1227
- if (Object.prototype.hasOwnProperty.call(obj, 'show')) {
1228
- this.show = obj?.show
1229
- }
1230
- if (Object.prototype.hasOwnProperty.call(obj, 'readOnly')) {
1231
- this.readOnly = obj?.readOnly
1232
- }
1233
- if (Object.prototype.hasOwnProperty.call(obj, 'disabled')) {
1234
- this.disabled = obj?.disabled
1235
- }
1236
- }
1237
- } else {
1238
- this.show = true
1239
- }
1240
- },
1241
- async showQueryFormItemFunc () {
1242
- if (this.attr.showQueryFormItemFunc) {
1243
- const obj = executeStrFunctionByContext(this, this.attr.showQueryFormItemFunc, [this.form, this.setForm, this.attr, util, this.mode, this.curPermissions, this.curRoles])
1244
- // 判断是 bool 还是 obj 兼容
1245
- if (typeof obj === 'boolean') {
1246
- this.show = obj
1247
- } else if (obj && typeof obj === 'object') {
1248
- // obj 是一个对象,并且不是数组
1249
- if (Object.prototype.hasOwnProperty.call(obj, 'show')) {
1250
- this.show = obj?.show
1251
- }
1252
- if (Object.prototype.hasOwnProperty.call(obj, 'readOnly')) {
1253
- this.readOnly = obj?.readOnly
1254
- }
1255
- if (Object.prototype.hasOwnProperty.call(obj, 'disabled')) {
1256
- this.disabled = obj?.disabled
1257
- }
1258
- }
1259
- } else {
1260
- this.show = true
1261
- }
1262
- },
1263
- init () {
1264
- if (!this.attr.flex) {
1265
- if (this.mode === '新增/修改') {
1266
- if (['horizontal', 'vertical'].includes(this.layout) || ['textarea', 'file', 'image'].includes(this.attr.type)) {
1267
- // 新增修改表单 horizontal 模式下默认为一行
1268
- this.attr.flex = {
1269
- xs: 24,
1270
- sm: 24,
1271
- md: 24,
1272
- lg: 24,
1273
- xl: 24,
1274
- xxl: 24,
1275
- fullWidth: true
1276
- }
1277
- } else {
1278
- // 新增修改表单 vertical 模式下默认为1列
1279
- this.attr.flex = {
1280
- xs: 24,
1281
- sm: 12,
1282
- md: 8,
1283
- lg: 8,
1284
- xl: 6,
1285
- xxl: 6
1286
- }
1287
- }
1288
- } else {
1289
- this.attr.flex = {
1290
- xs: 24,
1291
- sm: 24,
1292
- md: 8,
1293
- lg: 6,
1294
- xl: 6,
1295
- xxl: 6
1296
- }
1297
- }
1298
- }
1299
- if (this.attr.keyName && typeof this.attr.keyName === 'string') {
1300
- if (this.attr.keyName.indexOf('logic@') !== -1) {
1301
- this.getData({}, res => this.getDataCallback(res))
1302
- } else if (this.attr.keyName.indexOf('search@') !== -1) {
1303
- // `tool.getFullTree(this.getRights().where(row.getType()==$organization$))`
1304
- // 判断是否根据角色查询
1305
- let source = this.attr.keyName.substring(7)
1306
- const userid = this.currUser.id
1307
- let roleName = 'roleName'
1308
- if (source.startsWith('根据角色[') && source.endsWith(']获取人员')) {
1309
- const startIndex = source.indexOf('[') + 1
1310
- const endIndex = source.indexOf(']', startIndex)
1311
- roleName = source.substring(startIndex, endIndex)
1312
- source = '根据角色获取人员'
1313
- }
1314
- const searchData = { source, userid, roleName }
1315
- // 判断是否根据某个表单项联动 仅返回列表结构并筛选
1316
- if (source.startsWith('根据表单项[') && source.endsWith(']联动人员')) {
1317
- this.updateResOptions('人员')
1318
- } else if (source.startsWith('根据表单项[') && source.endsWith(']联动部门')) {
1319
- this.updateResOptions('部门')
1320
- } else if (this.attr.type === 'select' || this.attr.type === 'checkbox') {
1321
- // 仅获取最内层数据
1322
- searchToListOption(searchData, res => this.getDataCallback(res))
1323
- } else {
1324
- // 其他资源通用逻辑
1325
- searchToOption(searchData, res => this.getDataCallback(res))
1326
- }
1327
- } else if (this.attr.keyName.indexOf('config@') !== -1) {
1328
- const configName = this.attr.keyName.substring(7)
1329
- getConfigByName(configName, this.serviceName, res => {
1330
- this.getDataCallback(res.value)
1331
- }, this.env === 'dev')
1332
- } else if (this.attr.keyName.indexOf('async ') !== -1 || this.attr.keyName.indexOf('function ') !== -1) {
1333
- this.updateOptions()
1334
- }
1335
- } else if (this.attr.keys) {
1336
- // 对静态配置的keys也进行预处理
1337
- this.getDataCallback(this.attr.keys)
1338
- }
1339
- this.focusInput()
1340
- },
1341
- addressSearchComboboxSelect (data) {
1342
- this.form = Object.assign(this.form, JSON.parse(data))
1343
- },
1344
- onDivisionsChange (data) {
1345
- this.emitFunc('addressSearchComboboxSelect', {
1346
- key: this.attr.model,
1347
- value: data
1348
- })
1349
- },
1350
- getDataCallback (res) {
1351
- // 根据selectValueType预处理options数据
1352
- this.option = this.processOptionsForValueType(res)
1353
-
1354
- if (this.attr.type === 'treeSelect') {
1355
- this.$nextTick(() => {
1356
- this.$refs.xTreeSelect.init({
1357
- option: this.option,
1358
- form: this.form,
1359
- queryType: this.attr.queryType,
1360
- name: this.attr.name,
1361
- model: this.attr.model,
1362
- mode: this.mode,
1363
- disabled: this.disabled
1364
- })
1365
- })
1366
- } else if (this.attr.type === 'radio' || ['radioGroup', 'clickChange'].includes(this.attr.showMode)) {
1367
- this.initRadioValue()
1368
- }
1369
- },
1370
- initRadioValue () {
1371
- const model = this.attr.model
1372
- if (this.mode === '新增/修改' && (this.form[model] === undefined || this.form[model] === null) && !this.attr.prop) {
1373
- if (this.attr.keys && this.attr.keys.length > 1) {
1374
- this.form[model] = this.attr.keys[0].value
1375
- } else if (this.option.length > 1) {
1376
- this.form[model] = this.option[0].value
1377
- }
1378
- }
1379
- },
1380
- // 文件框时设置上传组件的值
1381
- setFiles (fileIds) {
1382
- if (!this.form[this.attr.model]) {
1383
- this.form[this.attr.model] = []
1384
- }
1385
- this.form[this.attr.model] = [...fileIds]
1386
- },
1387
- // 懒加载检索方法
1388
- fetchFunction (value) {
1389
- this.lastFetchId += 1
1390
- const fetchId = this.lastFetchId
1391
- this.option = []
1392
- this.searching = true
1393
- this.getData({
1394
- word: value
1395
- }, res => {
1396
- if (fetchId !== this.lastFetchId) {
1397
- return
1398
- }
1399
- this.option = res
1400
- this.searching = false
1401
- })
1402
- },
1403
- // 获取数据
1404
- getData (value, callbackFun) {
1405
- if (value !== '') {
1406
- const logicName = this.attr.keyName
1407
- const logic = logicName.substring(6)
1408
- // 调用logic前设置参数
1409
- if (this.getDataParams && this.getDataParams[this.attr.model]) {
1410
- Object.assign(value, this.getDataParams[this.attr.model])
1411
- }
1412
- runLogic(logic, Object.assign(value, {
1413
- orgId: this.currUser.orgid,
1414
- userId: this.currUser.id
1415
- }), this.serviceName, this.env === 'dev').then(res => {
1416
- callbackFun(res)
1417
- }).catch(e => {
1418
- callbackFun([])
1419
- console.error('获取数据失败:' + e)
1420
- })
1421
- }
1422
- },
1423
- filterOption (input, option) {
1424
- const child = option.componentOptions.children[0]
1425
- if (child.text) {
1426
- return child.text.toLowerCase().indexOf(input.toLowerCase()) >= 0
1427
- } else if (child.elm.innerText) {
1428
- return child.elm.innerText.toLowerCase().indexOf(input.toLowerCase()) >= 0
1429
- } else {
1430
- return child.child.value.toLowerCase().indexOf(input.toLowerCase()) >= 0
1431
- }
1432
- },
1433
- // 表单项变更函数中调用 控制表单组中表单项组名为 groupName 的表单是否展示
1434
- // func:x-form-show(显示)/x-form-no-show(不显示)
1435
- emitShowFormFunc (func, groupName) {
1436
- this.emitFunc(func, groupName)
1437
- },
1438
- emitFunc (func, data) {
1439
- this.$emit('x-form-item-emit-func', func, data, data?.model ? this.form[data.model] : this.form)
1440
- },
1441
- itemMounted (h) {
1442
- this.$emit('mounted', h)
1443
- },
1444
- rowChoose (rows) {
1445
- this.$emit('rowChoose', rows, this.attr, this.closeRowChooseInput)
1446
- },
1447
- searchRowChooseData () {
1448
- if (this.searching) {
1449
- return
1450
- }
1451
- this.lastFetchId += 1
1452
- const fetchId = this.lastFetchId
1453
- this.searching = true
1454
- if (fetchId !== this.lastFetchId) {
1455
- return
1456
- }
1457
- this.rowChooseFixedQueryValue = []
1458
- this.rowChooseFixedQueryValue[this.attr.model] = this.form[this.attr.model]
1459
- this.$nextTick(() => {
1460
- this.$refs.rowChooseTable.refresh(true)
1461
- })
1462
- },
1463
- showCloseRowChooseInput () {
1464
- this.rowChoosePopoverVisible = true
1465
- },
1466
- closeRowChooseInput () {
1467
- this.rowChoosePopoverVisible = false
1468
- },
1469
- rowChooseSearchAfterQuery () {
1470
- this.searching = false
1471
- },
1472
- // 获取 recording 转换后的数据
1473
- getRecodingData () {
1474
- return this.$refs.recording.getRecordingData()
1475
- },
1476
- recordingData (data) {
1477
- this.emitFunc('recordingData', data)
1478
- },
1479
- getPopupContainer (triggerNode) {
1480
- // return document.body
1481
- return triggerNode.parentNode
1482
- },
1483
- colorPickerComboboxSelect (val) {
1484
- this.form[this.attr.model] = val
1485
- },
1486
- }
1487
- }
1488
- </script>
1489
-
1490
- <style lang="less" scoped>
1491
- .custom-dropdown {
1492
- position: absolute;
1493
- z-index: 1050;
1494
- }
1495
-
1496
- .multiple_select {
1497
- :deep(.ant-select-selection) {
1498
- max-height: 32px;
1499
- overflow-y: scroll;
1500
- }
1501
- }
1502
-
1503
- </style>
1
+ <template>
2
+ <!-- 输入框 -->
3
+ <x-form-col
4
+ v-if="attr.type === 'input' && show"
5
+ :occupyCol="attr.occupyCol"
6
+ :labelCol="labelCol"
7
+ :flex="attr.flex">
8
+ <a-form-model-item
9
+ v-bind="bindOther"
10
+ :rules="rules"
11
+ :ref="attr.model"
12
+ :label="showLabel?attr.name:undefined"
13
+ :prop="attr.prop ? attr.prop : attr.model">
14
+ <!-- 如果配置了后置按钮插槽 -->
15
+ <a-input-group
16
+ v-if="((attr.inputOnAfterName && attr.inputOnAfterFunc) || (attr.inputOnAfterIcon && attr.inputOnAfterIconFunc)) && mode !== '查询'"
17
+ style="display: flex; width: 100%; padding: 4px 0"
18
+ compact>
19
+ <a-input
20
+ v-model="form[attr.model]"
21
+ :read-only="readOnly"
22
+ :disabled="disabled && !readOnly"
23
+ :whitespace="true"
24
+ @input="attr.dataChangeFunc && debouncedDataChangeFunc()"
25
+ :suffix="attr.inputSuffix && mode !== '新增' ? attr.inputSuffix : ''"
26
+ @blur="mode !== '查询' && attr.inputOnBlurFunc && emitFunc(attr.inputOnBlurFunc,attr)"
27
+ @keyup.enter="mode !== '查询' && attr.inputOnEnterFunc && emitFunc(attr.inputOnEnterFunc, attr)"
28
+ :placeholder="attr.placeholder ? attr.placeholder : '请输入'+attr.name.replace(/\s*/g, '')"
29
+ :ref="`${attr.model}input`"/>
30
+ <a-button
31
+ v-if="attr.inputOnAfterName && attr.inputOnAfterFunc && !attr.inputOnAfterName.includes('|')"
32
+ style="width: auto; min-width: 4rem;max-width: 6rem"
33
+ type="primary"
34
+ @click="emitFunc(attr.inputOnAfterFunc,attr)">
35
+ {{ attr.inputOnAfterName }}
36
+ </a-button>
37
+ <!-- 仅可以配置 一个按钮 以及 一个图标插槽 -->
38
+ <a-button
39
+ style="width: 2rem; flex-shrink: 0;"
40
+ v-else-if="attr.inputOnAfterIcon"
41
+ :type="attr.inputOnAfterIcon && attr.inputOnAfterName ? 'primary' :''"
42
+ :icon="attr.inputOnAfterIcon || 'question'"
43
+ @click="emitFunc(attr.inputOnAfterIconFunc,attr)">
44
+ </a-button>
45
+ <!-- 状态按钮 -->
46
+ <x-status-button
47
+ v-else
48
+ :states="parseStates(attr.inputOnAfterName, attr.inputOnAfterFunc)"
49
+ v-on="generateDynamicEvents(attr.inputOnAfterFunc, attr)"
50
+ style="width: auto; min-width: 4rem; max-width: 6rem"
51
+ />
52
+ </a-input-group>
53
+ <a-input-number
54
+ v-else-if="attr.numberInput && !readOnly"
55
+ v-model="form[attr.model]"
56
+ :whitespace="true"
57
+ @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
58
+ :disabled="disabled && !readOnly"
59
+ style="width:100%"
60
+ @blur="mode !== '查询' && attr.inputOnBlurFunc && emitFunc(attr.inputOnBlurFunc,attr)"
61
+ @keyup.enter="mode !== '查询' && attr.inputOnEnterFunc && emitFunc(attr.inputOnEnterFunc, attr)"
62
+ :suffix="attr.inputSuffix && mode !== '新增' ? attr.inputSuffix : ''"
63
+ :placeholder="attr.placeholder ? attr.placeholder : '请输入'+attr.name.replace(/\s*/g, '')"
64
+ :ref="`${attr.model}input`"/>
65
+ <a-input
66
+ v-else
67
+ v-model="form[attr.model]"
68
+ :whitespace="true"
69
+ :read-only="readOnly"
70
+ :disabled="disabled && !readOnly"
71
+ @input="attr.dataChangeFunc && debouncedDataChangeFunc()"
72
+ :suffix="attr.inputSuffix && mode !== '新增' ? attr.inputSuffix : ''"
73
+ style="width:100%"
74
+ @blur="mode !== '查询' && attr.inputOnBlurFunc && emitFunc(attr.inputOnBlurFunc,attr)"
75
+ @keyup.enter="mode !== '查询' && attr.inputOnEnterFunc && emitFunc(attr.inputOnEnterFunc, attr)"
76
+ :placeholder="attr.placeholder ? attr.placeholder : '请输入'+attr.name.replace(/\s*/g, '')"
77
+ :ref="`${attr.model}input`"/>
78
+ </a-form-model-item>
79
+ </x-form-col>
80
+ <!-- 下拉框 -->
81
+ <x-form-col
82
+ v-else-if="attr.type === 'select' && show"
83
+ :labelCol="labelCol"
84
+ :flex="attr.flex">
85
+ <a-form-model-item
86
+ v-bind="bindOther"
87
+ :rules="rules"
88
+ v-if="!attr.showMode || mode === '查询' || attr.showMode === 'select' "
89
+ :ref="attr.model"
90
+ :label="showLabel?attr.name:undefined"
91
+ :prop="attr.prop ? attr.prop : attr.model">
92
+ <!-- <span slot="label" class="label-box">{{ showLabel?attr.name:undefined }}</span>-->
93
+ <a-select
94
+ v-if="!attr.lazyLoad || attr.lazyLoad === 'false'"
95
+ v-model="form[attr.model]"
96
+ :disabled="disabled"
97
+ @change="handleSelectChange"
98
+ :filter-option="filterOption"
99
+ :getPopupContainer="getPopupContainer"
100
+ dropdownClassName="custom-dropdown"
101
+ :dropdownMatchSelectWidth="false"
102
+ :dropdownStyle="{ position: 'absolute'}"
103
+ :placeholder="attr.placeholder ? attr.placeholder : '请选择'"
104
+ show-search
105
+ :allowClear="true"
106
+ :getCalendarContainer="(triggerNode) => triggerNode.parentNode"
107
+ >
108
+ <a-select-option
109
+ v-if="mode === '查询'"
110
+ key="999999"
111
+ value="">全部
112
+ </a-select-option>
113
+ <template v-if="attr.keys">
114
+ <a-select-option
115
+ v-for="(item,index) in attr.keys"
116
+ :key="index.value"
117
+ :value="item.value + ''">
118
+ {{ item.label }}
119
+ </a-select-option>
120
+ </template>
121
+ <template v-else>
122
+ <template
123
+ v-if="attr.keyName.indexOf('logic@') !== -1 || attr.keyName.indexOf('config@') !== -1
124
+ ||attr.keyName.indexOf('search@') !== -1 || attr.keyName.indexOf('search@') !== -1">
125
+ <a-select-option
126
+ v-for="(item,index) in option"
127
+ :key="index.value"
128
+ :value="item.value + ''">
129
+ <template v-if="attr.keyName.indexOf('config@') !== -1 && item.status">
130
+ <!-- 徽标(badge) -->
131
+ <a-badge v-if="item.status !== 'gary'" :color="item.status" :text="item.label"/>
132
+ <a-badge v-else color="#D9D9D9" :text="item.label"/>
133
+ </template>
134
+ <template v-else>
135
+ {{ item.label }}
136
+ </template>
137
+ </a-select-option>
138
+ </template>
139
+ <template
140
+ v-else-if="attr.keyName.indexOf('async ') !== -1 || attr.keyName.indexOf('function ') !== -1">
141
+ <a-select-option
142
+ v-for="(item,index) in optionForFunc"
143
+ :key="index.value"
144
+ :value="item.value + ''">
145
+ <template>
146
+ {{ item.label }}
147
+ </template>
148
+ </a-select-option>
149
+ </template>
150
+ <template v-else>
151
+ <a-select-option
152
+ v-for="item in $appdata.getDictionaryList(attr.keyName)"
153
+ :key="item.value"
154
+ :value="item.value + ''">
155
+ <!-- 徽标(badge) -->
156
+ <x-badge
157
+ :badge-key="attr.keyName"
158
+ :replaceText="item.text"
159
+ :value="item.value"
160
+ :service-name="serviceName"
161
+ :env="env"/>
162
+ </a-select-option>
163
+ </template>
164
+ </template>
165
+ </a-select>
166
+ <a-select
167
+ v-else
168
+ v-model="form[attr.model]"
169
+ :disabled="disabled"
170
+ @change="handleSelectChange"
171
+ :filter-option="filterOption"
172
+ :getPopupContainer="getPopupContainer"
173
+ dropdownClassName="custom-dropdown"
174
+ :dropdownMatchSelectWidth="false"
175
+ :dropdownStyle="{ position: 'absolute'}"
176
+ :placeholder="attr.placeholder ? attr.placeholder : '搜索' + attr.name"
177
+ show-search
178
+ @search="fetchFunction"
179
+ >
180
+ <template #notFoundContent>
181
+ <a-spin v-if="searching" size="small"/>
182
+ </template>
183
+ <a-select-option
184
+ v-if="mode === '查询'"
185
+ key="999999"
186
+ value="">全部
187
+ </a-select-option>
188
+ <a-select-option
189
+ v-for="(item,index) in option"
190
+ :key="index"
191
+ :value="item.value + ''">{{ item.label }}
192
+ </a-select-option>
193
+ </a-select>
194
+ </a-form-model-item>
195
+ <a-form-model-item
196
+ v-bind="bindOther"
197
+ :rules="rules"
198
+ v-else-if="attr.showMode === 'radioGroup'"
199
+ :ref="attr.model"
200
+ :label="showLabel?attr.name:undefined"
201
+ :prop="attr.prop ? attr.prop : attr.model">
202
+ <a-radio-group v-model="form[attr.model]">
203
+ <a-radio-button v-for="modeItem in option" :key="modeItem.value" :value="modeItem.value">
204
+ {{ modeItem.label }}
205
+ </a-radio-button>
206
+ </a-radio-group>
207
+ </a-form-model-item>
208
+ <a-form-model-item
209
+ v-bind="bindOther"
210
+ v-else-if="attr.showMode === 'clickChange' && option.length > 0"
211
+ :ref="attr.model"
212
+ :label="showLabel?attr.name:undefined"
213
+ :prop="attr.prop ? attr.prop : attr.model">
214
+ <XClickChangeBtn></XClickChangeBtn>
215
+ </a-form-model-item>
216
+ </x-form-col>
217
+ <!-- 多选框 -->
218
+ <x-form-col
219
+ v-else-if="attr.type === 'checkbox' && show"
220
+ :labelCol="labelCol"
221
+ :flex="attr.flex">
222
+ <a-form-model-item
223
+ v-bind="bindOther"
224
+ :rules="rules"
225
+ v-if="!attr.showMode || mode === '查询' || attr.showMode === 'select' "
226
+ :ref="attr.model"
227
+ :label="showLabel?attr.name:undefined"
228
+ :prop="attr.prop ? attr.prop : attr.model">
229
+ <a-select
230
+ class="multiple_select"
231
+ style="width:100%"
232
+ v-if="!attr.lazyLoad || attr.lazyLoad === 'false'"
233
+ v-model="form[attr.model]"
234
+ :disabled="disabled"
235
+ :filter-option="filterOption"
236
+ :getPopupContainer="getPopupContainer"
237
+ :placeholder="attr.placeholder ? attr.placeholder : '请选择'"
238
+ @change="handleCheckboxChange"
239
+ mode="multiple"
240
+ show-search
241
+ allowClear
242
+ >
243
+ <template v-if="attr.keys">
244
+ <a-select-option
245
+ v-for="(item,index) in attr.keys"
246
+ :key="index"
247
+ :value="item.value + ''">
248
+ {{ item.label }}
249
+ </a-select-option>
250
+ </template>
251
+ <template v-else>
252
+ <template
253
+ v-if="attr.keyName.indexOf('logic@') !== -1 || attr.keyName.indexOf('config@') !== -1
254
+ ||attr.keyName.indexOf('search@') !== -1 || attr.keyName.indexOf('search@') !== -1">
255
+ <a-select-option
256
+ v-for="(item,index) in option"
257
+ :key="index"
258
+ :value="item.value">{{ item.label }}
259
+ </a-select-option>
260
+ </template>
261
+ <template v-else>
262
+ <a-select-option
263
+ v-for="item in $appdata.getDictionaryList(attr.keyName)"
264
+ :key="item.value"
265
+ :value="item.value + ''">{{ item.text }}
266
+ </a-select-option>
267
+ </template>
268
+ </template>
269
+ </a-select>
270
+ <a-select
271
+ v-else
272
+ class="multiple_select"
273
+ v-model="form[attr.model]"
274
+ :disabled="disabled"
275
+ :filter-option="filterOption"
276
+ :getPopupContainer="getPopupContainer"
277
+ :placeholder="attr.placeholder ? attr.placeholder : '搜索' + attr.name"
278
+ mode="multiple"
279
+ style="width:100%"
280
+ @change="handleCheckboxChange"
281
+ show-search
282
+ allowClear
283
+ @search="fetchFunction"
284
+ >
285
+ <template #notFoundContent>
286
+ <a-spin v-if="searching" size="small"/>
287
+ </template>
288
+ <a-select-option
289
+ v-for="(item,index) in option"
290
+ :key="index"
291
+ :value="item.value + ''">{{ item.label }}
292
+ </a-select-option>
293
+ </a-select>
294
+ </a-form-model-item>
295
+ <a-form-model-item
296
+ v-bind="bindOther"
297
+ :rules="rules"
298
+ v-else
299
+ :ref="attr.model"
300
+ :label="showLabel?attr.name:undefined"
301
+ :prop="attr.prop ? attr.prop : attr.model">
302
+ <a-checkbox-group
303
+ v-model="form[attr.model]"
304
+ :options="option"
305
+ @change="handleCheckboxChange"
306
+ />
307
+ </a-form-model-item>
308
+ </x-form-col>
309
+ <!-- 单选框 -->
310
+ <x-form-col
311
+ v-else-if="attr.type === 'radio' && show"
312
+ :labelCol="labelCol"
313
+ :flex="attr.flex">
314
+ <a-form-model-item
315
+ v-bind="bindOther"
316
+ :rules="rules"
317
+ v-if="!attr.showMode || attr.type === 'radio' "
318
+ :ref="attr.model"
319
+ :label="showLabel?attr.name:undefined"
320
+ :prop="attr.prop ? attr.prop : attr.model">
321
+ <a-radio-group
322
+ v-model="form[attr.model]"
323
+ @change="handleRadioChange"
324
+ >
325
+ <template v-if="attr.keys">
326
+ <a-radio v-for="(item,index) in attr.keys" :key="index" :value="item.value">
327
+ {{ item.label }}
328
+ </a-radio>
329
+ </template>
330
+ <template v-else>
331
+ <template
332
+ v-if="attr.keyName.indexOf('logic@') !== -1 || attr.keyName.indexOf('config@') !== -1
333
+ ||attr.keyName.indexOf('search@') !== -1 || attr.keyName.indexOf('search@') !== -1">
334
+ <a-radio v-for="(item,index) in option" :key="index" :value="item.value">
335
+ {{ item.label }}
336
+ </a-radio>
337
+ </template>
338
+ <template v-else>
339
+ <a-radio v-for="(item,index) in $appdata.getDictionaryList(attr.keyName)" :key="index" :value="item.value">
340
+ {{ item.text }}
341
+ </a-radio>
342
+ </template>
343
+ </template>
344
+ </a-radio-group>
345
+ </a-form-model-item>
346
+ <a-form-model-item
347
+ v-bind="bindOther"
348
+ :rules="rules"
349
+ v-else-if="attr.showMode === 'radioGroup'"
350
+ :ref="attr.model"
351
+ :label="showLabel?attr.name:undefined"
352
+ :prop="attr.prop ? attr.prop : attr.model">
353
+ <a-radio-group v-model="form[attr.model]">
354
+ <a-radio-button v-for="modeItem in option" :key="modeItem.value" :value="modeItem.value">
355
+ {{ modeItem.label }}
356
+ </a-radio-button>
357
+ </a-radio-group>
358
+ </a-form-model-item>
359
+ <a-form-model-item
360
+ v-bind="bindOther"
361
+ :rules="rules"
362
+ v-else-if="attr.showMode === 'clickChange' && option.length > 0"
363
+ :ref="attr.model"
364
+ :label="showLabel?attr.name:undefined"
365
+ :prop="attr.prop ? attr.prop : attr.model">
366
+ <XClickChangeBtn></XClickChangeBtn>
367
+ </a-form-model-item>
368
+ </x-form-col>
369
+ <!-- 时间 日期 框整合 -->
370
+ <x-form-col
371
+ v-else-if="['datePicker', 'rangePicker', 'yearPicker', 'monthPicker', 'yearRangePicker', 'monthRangePicker'].includes(attr.type) && show"
372
+ :labelCol="labelCol"
373
+ :flex="attr.flex">
374
+ <a-form-model-item
375
+ v-bind="bindOther"
376
+ :rules="rules"
377
+ :ref="attr.model"
378
+ :label="showLabel?attr.name:undefined"
379
+ :prop="attr.prop ? attr.prop : attr.model">
380
+ <XFormDatePicker
381
+ :attr="attr"
382
+ :mode="mode"
383
+ :disabled="disabled"
384
+ :readOnly="readOnly"
385
+ :showLabel="showLabel"
386
+ @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
387
+ v-model="form[attr.model]"/>
388
+ </a-form-model-item>
389
+ </x-form-col>
390
+ <!-- 文本域 -->
391
+ <x-form-col
392
+ v-else-if="attr.type === 'textarea' && show"
393
+ :labelCol="labelCol"
394
+ :flex="attr.flex">
395
+ <!-- :style="layout === 'inline'?{width:'calc(100% - 60px)'}:{}"-->
396
+ <a-form-model-item
397
+ v-bind="bindOther"
398
+ :rules="rules"
399
+ :ref="attr.model"
400
+ :label="showLabel?attr.name:undefined"
401
+ :prop="attr.prop ? attr.prop : attr.model">
402
+ <a-textarea
403
+ v-model="form[attr.model]"
404
+ style="width: 100%;"
405
+ :disabled="disabled"
406
+ :placeholder="attr.placeholder ? attr.placeholder : '请输入'+attr.name.replace(/\s*/g, '')"
407
+ :rows="4"/>
408
+ </a-form-model-item>
409
+ </x-form-col>
410
+ <!-- 文件上传 -->
411
+ <x-form-col
412
+ v-else-if="(attr.type === 'file' || attr.type === 'image') && show"
413
+ :labelCol="labelCol"
414
+ :flex="attr.flex">
415
+ <a-form-model-item
416
+ v-bind="bindOther"
417
+ :rules="rules"
418
+ :ref="attr.model"
419
+ :label="showLabel?attr.name:undefined"
420
+ :prop="attr.prop ? attr.prop : attr.model">
421
+ <upload
422
+ :files="files"
423
+ :read-only="readOnly"
424
+ :images="images"
425
+ :model="attr"
426
+ v-bind="attr"
427
+ :service-name="serviceName"
428
+ @setFiles="setFiles"></upload>
429
+ </a-form-model-item>
430
+ </x-form-col>
431
+ <!-- 省市区选择框 -->
432
+ <x-form-col
433
+ v-else-if="attr.type === 'citySelect' && show"
434
+ :labelCol="labelCol"
435
+ :flex="attr.flex">
436
+ <a-form-model-item
437
+ v-bind="bindOther"
438
+ :rules="rules"
439
+ :ref="attr.model"
440
+ :label="showLabel?attr.name:undefined"
441
+ :prop="attr.prop ? attr.prop : attr.model">
442
+ <citySelect
443
+ @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
444
+ ref="citySelect"
445
+ v-model="form[attr.model]"
446
+ :contexts="attr.contexts"
447
+ :value-type="attr.valueType"
448
+ :default-value="form[attr.model]"></citySelect>
449
+ </a-form-model-item>
450
+ </x-form-col>
451
+ <!-- 地点搜索框 -->
452
+ <x-form-col
453
+ v-else-if="(attr.type === 'addressSearch' || attr.type === 'coordinateSearch') && show"
454
+ :labelCol="labelCol"
455
+ :occupyCol="attr.occupyCol"
456
+ :flex="attr.flex">
457
+ <a-form-model-item
458
+ v-bind="bindOther"
459
+ :rules="rules"
460
+ :ref="attr.model"
461
+ :label="showLabel?attr.name:undefined"
462
+ :prop="attr.prop ? attr.prop : attr.model">
463
+ <address-search-combobox
464
+ :emitFunc="emitFunc"
465
+ :attr="attr"
466
+ :read-only="readOnly"
467
+ :searchResult="form[attr.model]"
468
+ :address="{ address: form[attr.model], coords: form[`${attr.model}_lng_lat`] }"
469
+ :resultKeys="{ address: attr.model, coords: `${attr.model}_lng_lat` }"
470
+ ref="addressSearchCombobox"
471
+ searchResultType="Object"
472
+ @onSelect="addressSearchComboboxSelect"
473
+ @onDivisionsChange="onDivisionsChange"
474
+ ></address-search-combobox>
475
+ </a-form-model-item>
476
+ </x-form-col>
477
+ <!-- 颜色选择器 -->
478
+ <x-form-col
479
+ v-else-if="attr.type === 'colorPicker' && show"
480
+ :labelCol="labelCol"
481
+ :flex="attr.flex">
482
+ <a-form-model-item
483
+ v-bind="bindOther"
484
+ :rules="rules"
485
+ :ref="attr.model"
486
+ :label="showLabel?attr.name:undefined"
487
+ :prop="attr.prop ? attr.prop : attr.model">
488
+ <color-picker-combobox
489
+ :value="form[attr.model]"
490
+ :read-only="readOnly"
491
+ @onSelect="colorPickerComboboxSelect"
492
+ />
493
+ </a-form-model-item>
494
+ </x-form-col>
495
+ <!-- 人员选择框 -->
496
+ <x-form-col
497
+ v-else-if="attr.type === 'personSetting' && show"
498
+ :labelCol="labelCol"
499
+ :flex="attr.flex">
500
+ <a-form-model-item
501
+ v-bind="bindOther"
502
+ :rules="rules"
503
+ :ref="attr.model"
504
+ :label="showLabel?attr.name:undefined"
505
+ :prop="attr.prop ? attr.prop : attr.model">
506
+ <PersonSetting v-model="form[attr.model]"></PersonSetting>
507
+ </a-form-model-item>
508
+ </x-form-col>
509
+ <!-- 树形选择框 -->
510
+ <x-form-col
511
+ v-else-if="attr.type === 'treeSelect' && show"
512
+ :labelCol="labelCol"
513
+ :flex="attr.flex">
514
+ <x-tree-select
515
+ :rules="rules"
516
+ @onChange="handleTreeSelectChange"
517
+ v-model="form[attr.model]"
518
+ :attr="attr"
519
+ @mounted="itemMounted"
520
+ ref="xTreeSelect">
521
+ </x-tree-select>
522
+ </x-form-col>
523
+ <!-- 列表选择框 -->
524
+ <x-form-col
525
+ v-else-if="attr.type === 'listSelect' && show"
526
+ :labelCol="labelCol"
527
+ :flex="attr.flex">
528
+ <a-form-model-item
529
+ v-bind="bindOther"
530
+ :rules="rules"
531
+ :ref="attr.model"
532
+ :label="showLabel?attr.name:undefined"
533
+ :style="layout === 'inline'&& attr.occupyCol && attr.occupyCol > 1? {width:`calc(100% - ${attr.occupyCol * 1.533}rem)`}:{}"
534
+ :prop="attr.prop ? attr.prop : attr.model">
535
+ <a-popover
536
+ ref="rowChoosePopover"
537
+ :visible="rowChoosePopoverVisible"
538
+ title="选择数据"
539
+ placement="bottom"
540
+ trigger="focus"
541
+ :arrowPointAtCenter="true"
542
+ :overlayStyle="{ width: '1000px', height: '30vh' }">
543
+ <template #content>
544
+ <x-report
545
+ v-if="isCover"
546
+ :use-oss-for-img="false"
547
+ :config-name="queryParamsName"
548
+ :service-name="serviceName"
549
+ :show-img-in-cell="true"
550
+ :display-only="true"
551
+ :edit-mode="false"
552
+ :show-save-button="true"
553
+ :no-padding="true"
554
+ :dont-format="true"
555
+ @rowChoose="rowChoose"
556
+ @cancel="closeRowChooseInput"
557
+ >
558
+ </x-report>
559
+ <x-form-table
560
+ v-else
561
+ title="请选择数据"
562
+ :queryParamsName="queryParamsName"
563
+ :rowSelectMode="true"
564
+ :allowSelectRowNum="1"
565
+ :service-name="serviceName"
566
+ :fixed-query-form="rowChooseFixedQueryValue"
567
+ @rowChoose="rowChoose"
568
+ @afterQuery="rowChooseSearchAfterQuery"
569
+ ref="rowChooseTable">
570
+ <template #button>
571
+ <a-button @click="closeRowChooseInput">
572
+ 关闭
573
+ </a-button>
574
+ </template>
575
+ </x-form-table>
576
+ </template>
577
+ <a-input
578
+ v-model="form[attr.model]"
579
+ :placeholder="attr.placeholder ? attr.placeholder : '请输入'+attr.name.replace(/\s*/g, '')"
580
+ @change="searchRowChooseData"
581
+ @focus="showCloseRowChooseInput"/>
582
+ </a-popover>
583
+ </a-form-model-item>
584
+ </x-form-col>
585
+ <!-- 评分框 -->
586
+ <x-form-col
587
+ v-else-if="attr.type === 'rate' && show"
588
+ :labelCol="labelCol"
589
+ :flex="attr.flex">
590
+ <a-form-model-item
591
+ v-bind="bindOther"
592
+ :rules="rules"
593
+ :ref="attr.model"
594
+ :label="showLabel?attr.name:undefined"
595
+ :prop="attr.prop ? attr.prop : attr.model">
596
+ <x-rate
597
+ v-model="form[attr.model]"
598
+ :mode="mode"
599
+ :disabled="disabled"
600
+ :query-type="attr.queryType"
601
+ :max-count="attr.maxCount"
602
+ :allow-half="attr.allowHalf"
603
+ :icon="attr.rateIcon"
604
+ :placeholder="attr.placeholder ? attr.placeholder : '请选择'+attr.name.replace(/\s*/g, '')"
605
+ @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
606
+ />
607
+ </a-form-model-item>
608
+ </x-form-col>
609
+ <!-- 区间选择器 -->
610
+ <x-form-col
611
+ v-else-if="attr.type === 'intervalPicker' && show"
612
+ :labelCol="labelCol"
613
+ :flex="attr.flex">
614
+ <a-form-model-item
615
+ v-bind="bindOther"
616
+ :rules="rules"
617
+ :ref="attr.model"
618
+ :label="showLabel?attr.name:undefined"
619
+ :prop="attr.prop ? attr.prop : attr.model">
620
+ <x-interval-picker
621
+ v-model="form[attr.model]"
622
+ :mode="mode"
623
+ :read-only="readOnly"
624
+ :disabled="disabled && !readOnly"
625
+ :placeholder="attr.placeholder ? attr.placeholder : '请输入'+attr.name.replace(/\s*/g, '')"
626
+ :start-placeholder="attr.startPlaceholder || '起始值'"
627
+ :end-placeholder="attr.endPlaceholder || '结束值'"
628
+ @blur="attr.inputOnBlurFunc && emitFunc(attr.inputOnBlurFunc,attr)"
629
+ />
630
+ </a-form-model-item>
631
+ </x-form-col>
632
+ <!-- 车牌号选择 -->
633
+ <x-form-col
634
+ v-else-if="attr.type === 'licensePlate' && show"
635
+ :labelCol="labelCol"
636
+ :flex="attr.flex">
637
+ <a-form-model-item
638
+ v-bind="bindOther"
639
+ :rules="rules"
640
+ :ref="attr.model"
641
+ :label="showLabel?attr.name:undefined"
642
+ :style="layout === 'inline'&& attr.occupyCol && attr.occupyCol > 1? {width:`calc(100% - ${attr.occupyCol * 1.533}rem)`}:{}"
643
+ :prop="attr.prop ? attr.prop : attr.model">
644
+ <!-- 如果配置了后置按钮插槽 -->
645
+ <a-input
646
+ v-if="mode ==='查询'"
647
+ v-model="form[attr.model]"
648
+ :whitespace="true"
649
+ :read-only="readOnly"
650
+ :disabled="disabled && !readOnly"
651
+ style="width:100%"
652
+ @blur="attr.inputOnBlurFunc && emitFunc(attr.inputOnBlurFunc,attr)"
653
+ :placeholder="attr.placeholder ? attr.placeholder : '请输入'+attr.name.replace(/\s*/g, '')"
654
+ :ref="`${attr.model}input`"/>
655
+ <x-license-plate
656
+ v-else
657
+ v-model="form[attr.model]"
658
+ @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
659
+ ></x-license-plate>
660
+ </a-form-model-item>
661
+ </x-form-col>
662
+ <!-- 录音 -->
663
+ <x-form-col
664
+ v-else-if="attr.type === 'recording' && show"
665
+ :labelCol="labelCol"
666
+ :flex="attr.flex">
667
+ <recording
668
+ ref="recording"
669
+ @recordingData="recordingData"
670
+ >
671
+ </recording>
672
+ </x-form-col>
673
+ <!-- 表格录入 -->
674
+ <x-form-col
675
+ v-else-if="attr.type === 'rowEdit' && show"
676
+ :labelCol="labelCol"
677
+ :flex="attr.flex">
678
+ <a-form-model-item
679
+ v-bind="bindOther"
680
+ :rules="rules"
681
+ :ref="attr.model"
682
+ :label="showLabel?attr.name:undefined"
683
+ :prop="attr.prop ? attr.prop : attr.model">
684
+ <x-form-table
685
+ :key="'childTable_' + attr.model"
686
+ :title="attr.name"
687
+ :queryParamsName="attr.crud"
688
+ :localEditMode="true"
689
+ :fixed-query-form="childTableFixedQueryForm(attr)"
690
+ :service-name="serviceName"
691
+ @hook:mounted="(h)=>onComponentMounted(h, attr)"
692
+ :ref="'childXFormTable_' + attr.model">
693
+ </x-form-table>
694
+ </a-form-model-item>
695
+ </x-form-col>
696
+ </template>
697
+ <script>
698
+ import { debounce } from 'ant-design-vue/lib/vc-table/src/utils'
699
+ import XFormCol from '@vue2-client/base-client/components/common/XFormCol'
700
+ import XBadge from '@vue2-client/base-client/components/common/XBadge'
701
+ import CitySelect from '@vue2-client/base-client/components/common/CitySelect'
702
+ import PersonSetting from '@vue2-client/base-client/components/common/PersonSetting'
703
+ import AddressSearchCombobox from '@vue2-client/base-client/components/common/AddressSearchCombobox'
704
+ import Upload from '@vue2-client/base-client/components/common/Upload'
705
+ import moment from 'moment'
706
+ import { getConfigByName, runLogic, getConfigByNameAsync } from '@vue2-client/services/api/common'
707
+ import * as util from '@vue2-client/utils/util'
708
+ import XTreeSelect from '@vue2-client/base-client/components/common/XForm/XTreeSelect'
709
+ import { searchToListOption, searchToOption } from '@vue2-client/services/v3Api'
710
+ import { mapState } from 'vuex'
711
+ import { executeStrFunctionByContext } from '@vue2-client/utils/runEvalFunction'
712
+ import XLicensePlate from '@vue2-client/base-client/components/common/XLicensePlate/XLicensePlate.vue'
713
+ import XStatusButton from './XStatusButton.vue'
714
+ import XClickChangeBtn from './itemComponent/XClickChangeBtn'
715
+ import 'moment/locale/zh-cn'
716
+ import XFormDatePicker from '@vue2-client/base-client/components/common/XDatePicker/index.vue'
717
+ import XIntervalPicker from '@vue2-client/base-client/components/common/XIntervalPicker/XIntervalPicker.vue'
718
+ import XRate from '@vue2-client/base-client/components/common/XRate/index.vue'
719
+ import { post } from '@vue2-client/services/api/restTools'
720
+ import ColorPickerCombobox from '@vue2-client/base-client/components/common/ColorPickerCombobox/ColorPickerCombobox.vue'
721
+ import { createSelectValueTypeHandler } from '@vue2-client/base-client/plugins/selectValueTypeHelper'
722
+
723
+ export default {
724
+ name: 'XFormItem',
725
+ components: {
726
+ XFormDatePicker,
727
+ XFormTable: () => import('@vue2-client/base-client/components/common/XFormTable/XFormTable.vue'),
728
+ Recording: () => import('@vue2-client/base-client/components/common/Recording/Recording.vue'),
729
+ XReport: () => import('@vue2-client/base-client/components/common/XReportGrid/XReport.vue'),
730
+ XLicensePlate,
731
+ XTreeSelect,
732
+ XFormCol,
733
+ XBadge,
734
+ CitySelect,
735
+ PersonSetting,
736
+ AddressSearchCombobox,
737
+ Upload,
738
+ XStatusButton,
739
+ XClickChangeBtn,
740
+ XIntervalPicker,
741
+ XRate,
742
+ ColorPickerCombobox
743
+ },
744
+ data () {
745
+ // 检索去抖
746
+ this.fetchFunction = debounce(this.fetchFunction, 800)
747
+ // 初始化selectValueType处理器
748
+ this.selectValueTypeHandler = createSelectValueTypeHandler(this)
749
+ return {
750
+ option: [],
751
+ // 最后检索版本
752
+ lastFetchId: 0,
753
+ // 检索中
754
+ searching: false,
755
+ searchResult: '',
756
+ optionForFunc: [],
757
+ // 控制当前表单项是否展示
758
+ show: true,
759
+ // moment
760
+ moment,
761
+ // 行选择器浮层是否显示
762
+ rowChoosePopoverVisible: false,
763
+ // 行选择器CRUD固定查询值
764
+ rowChooseFixedQueryValue: undefined,
765
+ bindOther: {}
766
+ }
767
+ },
768
+ props: {
769
+ attr: {
770
+ type: Object,
771
+ default:
772
+ () => {
773
+ return {}
774
+ }
775
+ },
776
+ form: {
777
+ type: Object,
778
+ required:
779
+ true
780
+ },
781
+ disabled: {
782
+ type: Boolean,
783
+ default:
784
+ () => {
785
+ return false
786
+ }
787
+ },
788
+ readOnly: {
789
+ type: Boolean,
790
+ default:
791
+ () => {
792
+ return false
793
+ }
794
+ },
795
+ mode: {
796
+ type: String,
797
+ default:
798
+ () => {
799
+ return '查询'
800
+ }
801
+ },
802
+ files: {
803
+ type: Array,
804
+ default:
805
+ () => {
806
+ return []
807
+ }
808
+ },
809
+ images: {
810
+ type: Array,
811
+ default:
812
+ () => {
813
+ return []
814
+ }
815
+ },
816
+ serviceName: {
817
+ type: String,
818
+ default:
819
+ undefined
820
+ },
821
+ // 调用logic获取数据源的追加参数
822
+ getDataParams: {
823
+ type: Object,
824
+ default:
825
+ undefined
826
+ },
827
+ // 布局
828
+ layout: {
829
+ type: String,
830
+ default:
831
+ 'horizontal'
832
+ },
833
+ // 环境
834
+ env: {
835
+ type: String,
836
+ default:
837
+ () => {
838
+ return 'prod'
839
+ }
840
+ },
841
+ // 设置表单值
842
+ setForm: {
843
+ type: Function,
844
+ default: (val) => {
845
+ console.log(val)
846
+ }
847
+ },
848
+ showLabel: {
849
+ type: Boolean,
850
+ default:
851
+ () => {
852
+ return true
853
+ }
854
+ },
855
+ labelCol: {
856
+ type: Object,
857
+ default: () => {
858
+ return { span: 8 }
859
+ }
860
+ },
861
+ rules: {
862
+ type: Array,
863
+ default:
864
+ () => {
865
+ return undefined
866
+ }
867
+ }
868
+ },
869
+ provide () {
870
+ return {
871
+ FormItemContext: this
872
+ }
873
+ },
874
+ created () {
875
+ this.init()
876
+ if (this.attr.keyName && (this.attr?.keyName?.toString().indexOf('async ') !== -1 || this.attr?.keyName?.toString()?.indexOf('function') !== -1)) {
877
+ this.debouncedUpdateOptions = debounce(this.updateOptions, 200)
878
+ }
879
+ if (this.attr.dataChangeFunc) {
880
+ this.debouncedDataChangeFunc = debounce(this.dataChangeFunc, 200)
881
+ // 执行一次
882
+ this.dataChangeFunc()
883
+ }
884
+ if (this.attr.showFormItemFunc) {
885
+ this.debouncedShowFormItemFunc = debounce(this.showFormItemFunc, 100)
886
+ // 执行一次
887
+ this.showFormItemFunc()
888
+ }
889
+ if (this.attr.showQueryFormItemFunc) {
890
+ this.debouncedShowQueryFormItemFunc = debounce(this.showQueryFormItemFunc, 100)
891
+ // 执行一次
892
+ this.showQueryFormItemFunc()
893
+ }
894
+ // 人员联动框增加监听
895
+ if (this?.attr?.keyName?.toString()?.startsWith('search@根据表单项[') && this?.attr?.keyName?.toString().endsWith(']联动人员')) {
896
+ this.debouncedUserLinkFunc = debounce(() => this.updateResOptions('人员'), 200)
897
+ }
898
+ if (this?.attr?.keyName?.toString()?.startsWith('search@根据表单项[') && this?.attr?.keyName?.toString().endsWith(']联动部门')) {
899
+ this.debouncedDepLinkFunc = debounce(() => this.updateResOptions('部门'), 200)
900
+ }
901
+ // xTreeSelect 自己调用 mounted
902
+ if (this.attr.type !== 'treeSelect') {
903
+ this.$emit('mounted', this.attr)
904
+ }
905
+ },
906
+ computed: {
907
+ ...mapState('account', { currUser: 'user', curRoles: 'roles', curPermissions: 'permissions' }),
908
+ queryParamsName () {
909
+ if (this.attr.keyName.startsWith('function')) {
910
+ // 调用异步函数获取内容
911
+ const obj = executeStrFunctionByContext(this, this.attr.keyName, [this.form, runLogic, this.mode, getConfigByNameAsync])
912
+ // 处理同步返回值
913
+ return this.handleQueryParamsResult(obj)
914
+ } else if (this.attr.keyName.startsWith('async ')) {
915
+ console.warn('此处不支持异步操作')
916
+ return ''
917
+ } else {
918
+ // 按现有方式处理
919
+ return this.attr.keyName.split('@')[this.attr.keyName.split('@').length - 1]
920
+ }
921
+ },
922
+ // 判断弹出时是否Cover,弹出只支持Cover以及CRUD
923
+ isCover () {
924
+ // 如果 queryParamsName 为空,返回空
925
+ if (!this.queryParamsName) {
926
+ return false
927
+ }
928
+ const result = this.queryParamsName.endsWith('Cover')
929
+ return result
930
+ },
931
+ },
932
+ watch: {
933
+ attr: {
934
+ handler () {
935
+ this.init()
936
+ },
937
+ deep: true
938
+ },
939
+ form: {
940
+ handler (newVal, oldVal) {
941
+ // 如果是从函数获取 options
942
+ if (this.attr.keyName && (this.attr.keyName.toString().indexOf('async ') !== -1 || this.attr.keyName.toString().indexOf('function') !== -1)) {
943
+ this.debouncedUpdateOptions()
944
+ }
945
+ // 如果有自定义是否展示表单项函数
946
+ if (this.attr.showFormItemFunc) {
947
+ this.debouncedShowFormItemFunc()
948
+ }
949
+ // 如果有自定义是否展示查询表单项函数
950
+ if (this.attr.showQueryFormItemFunc) {
951
+ this.debouncedShowQueryFormItemFunc()
952
+ }
953
+ // 地址搜索框赋值
954
+ if (this.attr.type === 'addressSearch' || this.attr.type === 'coordinateSearch') {
955
+ this.$refs.addressSearchCombobox.addressInput = this.form[this.attr.model]
956
+ }
957
+ // 数据源来自人员联动时更新数据
958
+ if (this?.attr?.keyName?.toString()?.startsWith('search@根据表单项[') && this?.attr?.keyName?.toString().endsWith(']联动人员')) {
959
+ this.debouncedUserLinkFunc()
960
+ }
961
+ // 数据源来自人员联动时更新数据
962
+ if (this?.attr?.keyName?.toString()?.startsWith('search@根据表单项[') && this?.attr?.keyName?.toString().endsWith(']联动部门')) {
963
+ this.debouncedDepLinkFunc()
964
+ }
965
+ },
966
+ deep: true
967
+ }
968
+ },
969
+ inject: {
970
+ getComponentByName: {
971
+ default: () => () => {
972
+ console.warn('getComponentByName is not provided')
973
+ return null // 或者返回一个默认的函数
974
+ },
975
+ },
976
+ registerComponent: {
977
+ default: () => () => {
978
+ console.warn('registerComponent is not provided')
979
+ return null // 或者返回一个默认的函数
980
+ },
981
+ },
982
+ getSelf: {
983
+ default: () => () => {
984
+ console.warn('getSelf is not provided')
985
+ return null // 或者返回一个默认的函数
986
+ },
987
+ },
988
+ XFormContext: {
989
+ default: () => () => {
990
+ console.warn('XFormContext is not provided')
991
+ return null // 或者返回一个默认的函数
992
+ },
993
+ },
994
+ setRequired: {
995
+ default: () => () => {
996
+ console.warn('setRequired is not provided')
997
+ return null // 或者返回一个默认的函数
998
+ },
999
+ },
1000
+ removeRequired: {
1001
+ default: () => () => {
1002
+ console.warn('removeRequired is not provided')
1003
+ return null // 或者返回一个默认的函数
1004
+ },
1005
+ }
1006
+ },
1007
+ methods: {
1008
+ // 处理 queryParams 结果并更新 rowChooseFixedQueryValue
1009
+ handleQueryParamsResult (obj) {
1010
+ let configName = ''
1011
+ if (obj && typeof obj === 'object') {
1012
+ // obj 是一个对象,并且不是数组
1013
+ if (Object.prototype.hasOwnProperty.call(obj, 'configName')) {
1014
+ configName = obj?.configName
1015
+ }
1016
+ if (Object.prototype.hasOwnProperty.call(obj, 'fixedQueryForm')) {
1017
+ if (obj?.fixedQueryForm && typeof obj?.fixedQueryForm === 'object') {
1018
+ this.rowChooseFixedQueryValue = Object.assign({}, this.rowChooseFixedQueryValue, obj.fixedQueryForm)
1019
+ }
1020
+ }
1021
+ } else if (obj && typeof obj === 'string') {
1022
+ configName = obj
1023
+ }
1024
+ return configName
1025
+ },
1026
+ // 根据selectValueType预处理options数据
1027
+ processOptionsForValueType (options) {
1028
+ return this.selectValueTypeHandler.processOptions(options, this.attr.selectValueType)
1029
+ },
1030
+
1031
+ // 处理both模式的数据,为表单添加label字段
1032
+ processBothModeData () {
1033
+ this.selectValueTypeHandler.processBothMode(
1034
+ this.form,
1035
+ this.attr.model,
1036
+ this.attr.selectValueType,
1037
+ this.option
1038
+ )
1039
+ },
1040
+
1041
+ // 根据value查找对应的label(支持单选和多选)
1042
+ findLabelByValue (value) {
1043
+ return this.selectValueTypeHandler.findLabel(value, this.option)
1044
+ },
1045
+
1046
+ // 统一的表单项change处理逻辑
1047
+ handleFormItemChange () {
1048
+ // 处理both模式
1049
+ if (this.attr.selectValueType === 'both') {
1050
+ this.$nextTick(() => {
1051
+ this.selectValueTypeHandler.processBothMode(
1052
+ this.form,
1053
+ this.attr.model,
1054
+ this.form[this.attr.model],
1055
+ this.option
1056
+ )
1057
+ })
1058
+ }
1059
+ // 处理label模式
1060
+ if (this.attr.selectValueType === 'label') {
1061
+ this.$nextTick(() => {
1062
+ this.selectValueTypeHandler.processLabelMode(
1063
+ this.form,
1064
+ this.attr.model,
1065
+ this.form[this.attr.model],
1066
+ this.option
1067
+ )
1068
+ })
1069
+ }
1070
+ // 处理原有的dataChangeFunc
1071
+ if (this.attr.dataChangeFunc) {
1072
+ this.debouncedDataChangeFunc()
1073
+ }
1074
+ },
1075
+
1076
+ // Select组件change处理
1077
+ handleSelectChange () {
1078
+ this.handleFormItemChange()
1079
+ },
1080
+
1081
+ // Checkbox组件change处理
1082
+ handleCheckboxChange () {
1083
+ this.handleFormItemChange()
1084
+ },
1085
+
1086
+ // Radio组件change处理
1087
+ handleRadioChange () {
1088
+ this.handleFormItemChange()
1089
+ },
1090
+
1091
+ // TreeSelect组件change处理(通过XTreeSelect组件回调)
1092
+ handleTreeSelectChange () {
1093
+ this.handleFormItemChange()
1094
+ },
1095
+
1096
+ // 把内部的crud表单录入放到表单中,以便外部可以调用
1097
+ onComponentMounted (h, attr) {
1098
+ console.log('crud表单', h)
1099
+ if (attr.crud) {
1100
+ this.registerComponent(attr.model, this.$refs['childXFormTable_' + attr.model])
1101
+ }
1102
+ },
1103
+ childTableFixedQueryForm (item) {
1104
+ console.log('传递的form', this.form)
1105
+ if (this.modifyModelData?.primaryKeyData) {
1106
+ const fixedForm = {}
1107
+ fixedForm[item.childTableForeignKeyName] = Object.values(this.modifyModelData.primaryKeyData)[0]
1108
+ return fixedForm
1109
+ }
1110
+ return null
1111
+ },
1112
+ // 动态生成事件绑定对象
1113
+ generateDynamicEvents (inputOnAfterFunc, attr) {
1114
+ const events = {}
1115
+ const states = this.parseStates(attr.inputOnAfterName, inputOnAfterFunc)
1116
+
1117
+ states.forEach((state) => {
1118
+ // 动态绑定事件名到 emitFunc
1119
+ events[state.event] = () => {
1120
+ console.info('事件名', state.event)
1121
+ this.emitFunc(state.event, attr)
1122
+ }
1123
+ })
1124
+
1125
+ return events // 返回 { state1Event: handler, state2Event: handler, ... }
1126
+ },
1127
+ parseStates (input, events) {
1128
+ const eventNames = events.split('|')
1129
+ return input.split('|').map((label, index) => ({
1130
+ label,
1131
+ event: eventNames[index] // 如果没有提供事件名称,则使用默认值
1132
+ }))
1133
+ },
1134
+ focusInput () {
1135
+ if (this.attr.defaultFocus) {
1136
+ this.$nextTick(h => {
1137
+ const el = this.$refs[`${this.attr.model}input`]?.$el
1138
+ let inputEl
1139
+ if (el) {
1140
+ if (el.tagName.toLowerCase() === 'input') {
1141
+ inputEl = el
1142
+ } else {
1143
+ inputEl = el.querySelector('input')
1144
+ }
1145
+ }
1146
+ if (inputEl) {
1147
+ inputEl.focus()
1148
+ if (inputEl.type === 'number') {
1149
+ if (inputEl.valueAsNumber) {
1150
+ inputEl.setSelectionRange(0, inputEl.valueAsNumber.toString().length)
1151
+ }
1152
+ } else {
1153
+ if (inputEl.value) {
1154
+ inputEl.setSelectionRange(0, inputEl.value.length)
1155
+ }
1156
+ }
1157
+ }
1158
+ })
1159
+ }
1160
+ },
1161
+ // 更新人员下拉框数据
1162
+ async updateResOptions (type) {
1163
+ if (this?.attr?.keyName?.toString()?.startsWith('search@根据表单项[') && this?.attr?.keyName?.toString()?.endsWith(`]联动${type}`)) {
1164
+ const startIndex = this.attr.keyName.indexOf('[') + 1
1165
+ const endIndex = this.attr.keyName.indexOf(']', startIndex)
1166
+ const fromModel = this.attr.keyName.substring(startIndex, endIndex).replace('.', '_')
1167
+ // 获取表单字段的实际值(优先使用originData中的原始值)
1168
+ const rawFieldValue = this.form.originData && this.form.originData[fromModel]
1169
+ ? this.form.originData[fromModel]
1170
+ : this.form[fromModel]
1171
+
1172
+ // 确保数据为数组格式(用于filter参数)
1173
+ const filterValues = Array.isArray(rawFieldValue)
1174
+ ? rawFieldValue
1175
+ : [rawFieldValue]
1176
+ if (fromModel?.length && filterValues?.length) {
1177
+ const searchData = {
1178
+ source: `获取${type}`,
1179
+ userid: this.currUser.id,
1180
+ filter: filterValues,
1181
+ filterType: fromModel.indexOf('org') > -1 ? 'org' : 'dep'
1182
+ }
1183
+ const tempArray = []
1184
+ await searchToListOption(searchData, res => {
1185
+ this.getDataCallback(
1186
+ res.filter(h => {
1187
+ if (fromModel.indexOf('org') > -1) {
1188
+ if (type === '部门') {
1189
+ if (filterValues?.includes(h.orgid || h.f_organization_id) || filterValues?.includes(h.parentid) || tempArray.includes(h.parentid)) {
1190
+ tempArray.push(h.value)
1191
+ return true
1192
+ }
1193
+ return false
1194
+ } else {
1195
+ return filterValues?.includes(h.orgid || h.f_organization_id || h.parentid)
1196
+ }
1197
+ } else {
1198
+ return filterValues?.includes(h?.parentid)
1199
+ }
1200
+ }
1201
+ )
1202
+ )
1203
+ })
1204
+ }
1205
+ }
1206
+ },
1207
+ // js 函数作为数据源
1208
+ async updateOptions () {
1209
+ if (this.attr.keyName && (this.attr.keyName.indexOf('async ') !== -1 || this.attr.keyName.indexOf('function ') !== -1)) {
1210
+ const rawOptions = await executeStrFunctionByContext(this, this.attr.keyName, [this.form, runLogic, this.mode, getConfigByNameAsync, post])
1211
+ // 根据selectValueType预处理options数据
1212
+ this.optionForFunc = this.processOptionsForValueType(rawOptions)
1213
+ }
1214
+ },
1215
+ async dataChangeFunc () {
1216
+ if (this.attr.dataChangeFunc) {
1217
+ await executeStrFunctionByContext(this, this.attr.dataChangeFunc, [this.form, this.setForm, this.attr, util, this.mode, runLogic, getConfigByNameAsync])
1218
+ }
1219
+ },
1220
+ async showFormItemFunc () {
1221
+ if (this.attr.showFormItemFunc) {
1222
+ const obj = executeStrFunctionByContext(this, this.attr.showFormItemFunc, [this.form, this.setForm, this.attr, util, this.mode, this.curPermissions, this.curRoles])
1223
+ // 判断是 bool 还是 obj 兼容
1224
+ if (typeof obj === 'boolean') {
1225
+ this.show = obj
1226
+ } else if (obj && typeof obj === 'object') {
1227
+ // obj 是一个对象,并且不是数组
1228
+ if (Object.prototype.hasOwnProperty.call(obj, 'show')) {
1229
+ this.show = obj?.show
1230
+ }
1231
+ if (Object.prototype.hasOwnProperty.call(obj, 'readOnly')) {
1232
+ this.readOnly = obj?.readOnly
1233
+ }
1234
+ if (Object.prototype.hasOwnProperty.call(obj, 'disabled')) {
1235
+ this.disabled = obj?.disabled
1236
+ }
1237
+ }
1238
+ } else {
1239
+ this.show = true
1240
+ }
1241
+ },
1242
+ async showQueryFormItemFunc () {
1243
+ if (this.attr.showQueryFormItemFunc) {
1244
+ const obj = executeStrFunctionByContext(this, this.attr.showQueryFormItemFunc, [this.form, this.setForm, this.attr, util, this.mode, this.curPermissions, this.curRoles])
1245
+ // 判断是 bool 还是 obj 兼容
1246
+ if (typeof obj === 'boolean') {
1247
+ this.show = obj
1248
+ } else if (obj && typeof obj === 'object') {
1249
+ // obj 是一个对象,并且不是数组
1250
+ if (Object.prototype.hasOwnProperty.call(obj, 'show')) {
1251
+ this.show = obj?.show
1252
+ }
1253
+ if (Object.prototype.hasOwnProperty.call(obj, 'readOnly')) {
1254
+ this.readOnly = obj?.readOnly
1255
+ }
1256
+ if (Object.prototype.hasOwnProperty.call(obj, 'disabled')) {
1257
+ this.disabled = obj?.disabled
1258
+ }
1259
+ }
1260
+ } else {
1261
+ this.show = true
1262
+ }
1263
+ },
1264
+ init () {
1265
+ if (!this.attr.flex) {
1266
+ if (this.mode === '新增/修改') {
1267
+ if (['horizontal', 'vertical'].includes(this.layout) || ['textarea', 'file', 'image'].includes(this.attr.type)) {
1268
+ // 新增修改表单 horizontal 模式下默认为一行
1269
+ this.attr.flex = {
1270
+ xs: 24,
1271
+ sm: 24,
1272
+ md: 24,
1273
+ lg: 24,
1274
+ xl: 24,
1275
+ xxl: 24,
1276
+ fullWidth: true
1277
+ }
1278
+ } else {
1279
+ // 新增修改表单 vertical 模式下默认为1列
1280
+ this.attr.flex = {
1281
+ xs: 24,
1282
+ sm: 12,
1283
+ md: 8,
1284
+ lg: 8,
1285
+ xl: 6,
1286
+ xxl: 6
1287
+ }
1288
+ }
1289
+ } else {
1290
+ this.attr.flex = {
1291
+ xs: 24,
1292
+ sm: 24,
1293
+ md: 8,
1294
+ lg: 6,
1295
+ xl: 6,
1296
+ xxl: 6
1297
+ }
1298
+ }
1299
+ }
1300
+ if (this.attr.keyName && typeof this.attr.keyName === 'string') {
1301
+ if (this.attr.keyName.indexOf('logic@') !== -1) {
1302
+ this.getData({}, res => this.getDataCallback(res))
1303
+ } else if (this.attr.keyName.indexOf('search@') !== -1) {
1304
+ // `tool.getFullTree(this.getRights().where(row.getType()==$organization$))`
1305
+ // 判断是否根据角色查询
1306
+ let source = this.attr.keyName.substring(7)
1307
+ const userid = this.currUser.id
1308
+ let roleName = 'roleName'
1309
+ if (source.startsWith('根据角色[') && source.endsWith(']获取人员')) {
1310
+ const startIndex = source.indexOf('[') + 1
1311
+ const endIndex = source.indexOf(']', startIndex)
1312
+ roleName = source.substring(startIndex, endIndex)
1313
+ source = '根据角色获取人员'
1314
+ }
1315
+ const searchData = { source, userid, roleName }
1316
+ // 判断是否根据某个表单项联动 仅返回列表结构并筛选
1317
+ if (source.startsWith('根据表单项[') && source.endsWith(']联动人员')) {
1318
+ this.updateResOptions('人员')
1319
+ } else if (source.startsWith('根据表单项[') && source.endsWith(']联动部门')) {
1320
+ this.updateResOptions('部门')
1321
+ } else if (this.attr.type === 'select' || this.attr.type === 'checkbox') {
1322
+ // 仅获取最内层数据
1323
+ searchToListOption(searchData, res => this.getDataCallback(res))
1324
+ } else {
1325
+ // 其他资源通用逻辑
1326
+ searchToOption(searchData, res => this.getDataCallback(res))
1327
+ }
1328
+ } else if (this.attr.keyName.indexOf('config@') !== -1) {
1329
+ const configName = this.attr.keyName.substring(7)
1330
+ getConfigByName(configName, this.serviceName, res => {
1331
+ this.getDataCallback(res.value)
1332
+ }, this.env === 'dev')
1333
+ } else if (this.attr.keyName.indexOf('async ') !== -1 || this.attr.keyName.indexOf('function ') !== -1) {
1334
+ this.updateOptions()
1335
+ }
1336
+ } else if (this.attr.keys) {
1337
+ // 对静态配置的keys也进行预处理
1338
+ this.getDataCallback(this.attr.keys)
1339
+ }
1340
+ this.focusInput()
1341
+ },
1342
+ addressSearchComboboxSelect (data) {
1343
+ this.form = Object.assign(this.form, JSON.parse(data))
1344
+ },
1345
+ onDivisionsChange (data) {
1346
+ this.emitFunc('addressSearchComboboxSelect', {
1347
+ key: this.attr.model,
1348
+ value: data
1349
+ })
1350
+ },
1351
+ getDataCallback (res) {
1352
+ // 根据selectValueType预处理options数据
1353
+ this.option = this.processOptionsForValueType(res)
1354
+
1355
+ if (this.attr.type === 'treeSelect') {
1356
+ this.$nextTick(() => {
1357
+ this.$refs.xTreeSelect.init({
1358
+ option: this.option,
1359
+ form: this.form,
1360
+ queryType: this.attr.queryType,
1361
+ name: this.attr.name,
1362
+ model: this.attr.model,
1363
+ mode: this.mode,
1364
+ disabled: this.disabled
1365
+ })
1366
+ })
1367
+ } else if (this.attr.type === 'radio' || ['radioGroup', 'clickChange'].includes(this.attr.showMode)) {
1368
+ this.initRadioValue()
1369
+ }
1370
+ },
1371
+ initRadioValue () {
1372
+ const model = this.attr.model
1373
+ if (this.mode === '新增/修改' && (this.form[model] === undefined || this.form[model] === null) && !this.attr.prop) {
1374
+ if (this.attr.keys && this.attr.keys.length > 1) {
1375
+ this.form[model] = this.attr.keys[0].value
1376
+ } else if (this.option.length > 1) {
1377
+ this.form[model] = this.option[0].value
1378
+ }
1379
+ }
1380
+ },
1381
+ // 文件框时设置上传组件的值
1382
+ setFiles (fileIds) {
1383
+ if (!this.form[this.attr.model]) {
1384
+ this.form[this.attr.model] = []
1385
+ }
1386
+ this.form[this.attr.model] = [...fileIds]
1387
+ },
1388
+ // 懒加载检索方法
1389
+ fetchFunction (value) {
1390
+ this.lastFetchId += 1
1391
+ const fetchId = this.lastFetchId
1392
+ this.option = []
1393
+ this.searching = true
1394
+ this.getData({
1395
+ word: value
1396
+ }, res => {
1397
+ if (fetchId !== this.lastFetchId) {
1398
+ return
1399
+ }
1400
+ this.option = res
1401
+ this.searching = false
1402
+ })
1403
+ },
1404
+ // 获取数据
1405
+ getData (value, callbackFun) {
1406
+ if (value !== '') {
1407
+ const logicName = this.attr.keyName
1408
+ const logic = logicName.substring(6)
1409
+ // 调用logic前设置参数
1410
+ if (this.getDataParams && this.getDataParams[this.attr.model]) {
1411
+ Object.assign(value, this.getDataParams[this.attr.model])
1412
+ }
1413
+ runLogic(logic, Object.assign(value, {
1414
+ orgId: this.currUser.orgid,
1415
+ userId: this.currUser.id
1416
+ }), this.serviceName, this.env === 'dev').then(res => {
1417
+ callbackFun(res)
1418
+ }).catch(e => {
1419
+ callbackFun([])
1420
+ console.error('获取数据失败:' + e)
1421
+ })
1422
+ }
1423
+ },
1424
+ filterOption (input, option) {
1425
+ const child = option.componentOptions.children[0]
1426
+ if (child.text) {
1427
+ return child.text.toLowerCase().indexOf(input.toLowerCase()) >= 0
1428
+ } else if (child.elm.innerText) {
1429
+ return child.elm.innerText.toLowerCase().indexOf(input.toLowerCase()) >= 0
1430
+ } else {
1431
+ return child.child.value.toLowerCase().indexOf(input.toLowerCase()) >= 0
1432
+ }
1433
+ },
1434
+ // 表单项变更函数中调用 控制表单组中表单项组名为 groupName 的表单是否展示
1435
+ // func:x-form-show(显示)/x-form-no-show(不显示)
1436
+ emitShowFormFunc (func, groupName) {
1437
+ this.emitFunc(func, groupName)
1438
+ },
1439
+ emitFunc (func, data) {
1440
+ this.$emit('x-form-item-emit-func', func, data, data?.model ? this.form[data.model] : this.form)
1441
+ },
1442
+ itemMounted (h) {
1443
+ this.$emit('mounted', h)
1444
+ },
1445
+ rowChoose (rows) {
1446
+ this.$emit('rowChoose', rows, this.attr, this.closeRowChooseInput)
1447
+ },
1448
+ searchRowChooseData () {
1449
+ if (this.searching) {
1450
+ return
1451
+ }
1452
+ this.lastFetchId += 1
1453
+ const fetchId = this.lastFetchId
1454
+ this.searching = true
1455
+ if (fetchId !== this.lastFetchId) {
1456
+ return
1457
+ }
1458
+ this.rowChooseFixedQueryValue = []
1459
+ this.rowChooseFixedQueryValue[this.attr.model] = this.form[this.attr.model]
1460
+ this.$nextTick(() => {
1461
+ this.$refs.rowChooseTable.refresh(true)
1462
+ })
1463
+ },
1464
+ showCloseRowChooseInput () {
1465
+ this.rowChoosePopoverVisible = true
1466
+ },
1467
+ closeRowChooseInput () {
1468
+ this.rowChoosePopoverVisible = false
1469
+ },
1470
+ rowChooseSearchAfterQuery () {
1471
+ this.searching = false
1472
+ },
1473
+ // 获取 recording 转换后的数据
1474
+ getRecodingData () {
1475
+ return this.$refs.recording.getRecordingData()
1476
+ },
1477
+ recordingData (data) {
1478
+ this.emitFunc('recordingData', data)
1479
+ },
1480
+ getPopupContainer (triggerNode) {
1481
+ // return document.body
1482
+ return triggerNode.parentNode
1483
+ },
1484
+ colorPickerComboboxSelect (val) {
1485
+ this.form[this.attr.model] = val
1486
+ },
1487
+ }
1488
+ }
1489
+ </script>
1490
+
1491
+ <style lang="less" scoped>
1492
+ .custom-dropdown {
1493
+ position: absolute;
1494
+ z-index: 1050;
1495
+ }
1496
+
1497
+ .multiple_select {
1498
+ :deep(.ant-select-selection) {
1499
+ max-height: 32px;
1500
+ overflow-y: scroll;
1501
+ }
1502
+ }
1503
+
1504
+ </style>