vue2-client 1.16.94 → 1.16.97

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 (330) hide show
  1. package/.claude/settings.local.json +20 -20
  2. package/.cursorrules +19 -19
  3. package/.env.apply +19 -19
  4. package/.env.gaslink +19 -19
  5. package/.env.his +19 -19
  6. package/.env.liuli +20 -20
  7. package/.env.message +19 -19
  8. package/.env.scada +19 -19
  9. package/.eslintrc.js +90 -90
  10. package/CHANGELOG.md +830 -830
  11. package/CLAUDE.md +97 -97
  12. package/Components.md +60 -60
  13. package/docs/LowCode/lowcode.md +155 -155
  14. package/docs/LowCode/lowcodeForDeveloper.md +230 -230
  15. package/docs/index.md +30 -30
  16. package/index.js +31 -31
  17. package/jest-transform-stub.js +8 -8
  18. package/jest.setup.js +7 -7
  19. package/jsconfig.json +19 -19
  20. package/package.json +112 -112
  21. package/public/his/editor/editor.html +51 -51
  22. package/public/his/editor/mock/bind_data.html +779 -779
  23. package/public/his/editor/mock/data_table.html +40 -40
  24. package/public/his/editor/mock/sign.html +75 -75
  25. package/public/his/editor/vender/JsBarcode.all.js +3669 -3669
  26. package/public/his/editor/vender/date97/My97DatePicker.htm +65 -65
  27. package/public/his/editor/vender/date97/WdatePicker.js +677 -677
  28. package/public/his/editor/vender/date97/calendar.js +4 -4
  29. package/public/his/editor/vender/date97/lang/en.js +13 -13
  30. package/public/his/editor/vender/date97/lang/zh-cn.js +13 -13
  31. package/public/his/editor/vender/date97/lang/zh-tw.js +13 -13
  32. package/public/his/editor/vender/date97/skin/WdatePicker.css +10 -10
  33. package/public/his/editor/vender/date97/skin/default/datepicker.css +328 -328
  34. package/public/his/editor/vender/date97/skin/ext/datepicker.css +308 -308
  35. package/public/his/editor/vender/date97/skin/whyGreen/datepicker.css +255 -255
  36. package/public/his/editor/vender/diff.js +1627 -1627
  37. package/public/his/editor/vender/editor.js +1 -1
  38. package/public/his/editor/vender/fabric.js +31187 -31187
  39. package/public/his/editor/vender/jquery/jquery.base64.js +190 -190
  40. package/public/his/editor/vender/jquery/jquery.js +10872 -10872
  41. package/public/his/editor/vender/jquery/jquery.print.js +255 -255
  42. package/public/his/editor/vender/jquery/zTreeStyle/zTreeStyle.css +96 -96
  43. package/public/his/editor/vender/mui/mui.min.css +4 -4
  44. package/public/his/editor/vender/mui/mui.min.js +5 -5
  45. package/public/his/editor/vender/mui/mui.picker.min.css +6 -6
  46. package/public/his/editor/vender/mui/mui.picker.min.js +6 -6
  47. package/public/his/editor/vender/qrcode.js +7 -7
  48. package/public/his/editor/vender/requirejs/require.js +2145 -2145
  49. package/public/his/editor/vender/signature/jSignature.CompressorSVG.js +518 -518
  50. package/public/his/editor/vender/signature/jSignature.UndoButton.js +164 -164
  51. package/public/his/editor/vender/signature/jSignature.js +1486 -1486
  52. package/public/his/editor/vender/validator.js +5094 -5094
  53. package/public/his/editor/vender/weui/weui.css +5659 -5659
  54. package/public/his/editor/vender/weui/weui.min.css +4 -4
  55. package/public/his/editor/vender/weui/weui.min.js +11 -11
  56. package/src/assets/img/querySlotDemo.svg +15 -15
  57. package/src/assets/svg/badtwo.svg +1 -1
  58. package/src/assets/svg/goodtwo.svg +1 -1
  59. package/src/base-client/components/AI/AskAiBtn.vue +136 -136
  60. package/src/base-client/components/AI/demo.vue +31 -31
  61. package/src/base-client/components/common/AddressSearchCombobox/IcMapIcon.vue +16 -16
  62. package/src/base-client/components/common/AddressSearchCombobox/demo.vue +36 -36
  63. package/src/base-client/components/common/AddressSearchCombobox/ic_map.svg +6 -6
  64. package/src/base-client/components/common/AmapMarker/AmapPointRendering.vue +120 -120
  65. package/src/base-client/components/common/CitySelect/index.js +3 -3
  66. package/src/base-client/components/common/CitySelect/index.md +109 -109
  67. package/src/base-client/components/common/CreateQuery/CreateQuery.vue +669 -669
  68. package/src/base-client/components/common/CreateQuery/CreateQueryItem.vue +1014 -1014
  69. package/src/base-client/components/common/CreateQuery/index.js +3 -3
  70. package/src/base-client/components/common/CreateQuery/index.md +42 -42
  71. package/src/base-client/components/common/CreateSimpleFormQuery/CreateSimpleFormQuery.vue +452 -452
  72. package/src/base-client/components/common/CreateSimpleFormQuery/CreateSimpleFormQueryItem.vue +511 -511
  73. package/src/base-client/components/common/CreateSimpleFormQuery/index.js +3 -3
  74. package/src/base-client/components/common/CreateSimpleFormQuery/index.md +42 -42
  75. package/src/base-client/components/common/FormGroupEdit/index.js +3 -3
  76. package/src/base-client/components/common/FormGroupEdit/index.md +43 -43
  77. package/src/base-client/components/common/FormGroupQuery/FormGroupQuery.vue +166 -166
  78. package/src/base-client/components/common/FormGroupQuery/index.js +3 -3
  79. package/src/base-client/components/common/FormGroupQuery/index.md +43 -43
  80. package/src/base-client/components/common/HIS/HButtons/HButtons.vue +47 -1
  81. package/src/base-client/components/common/HIS/HForm/HForm.vue +44 -4
  82. package/src/base-client/components/common/HIS/HFormTable/HFormTable.vue +8 -2
  83. package/src/base-client/components/common/HIS/demo.vue +61 -61
  84. package/src/base-client/components/common/JSONToTree/jsontotree.vue +271 -271
  85. package/src/base-client/components/common/LowCodeComponent/LowCodeEditorModal.vue +108 -108
  86. package/src/base-client/components/common/LowCodeComponent/LowCodeEditorPanel.vue +413 -413
  87. package/src/base-client/components/common/LowCodeComponent/LowCodePageOrganization.vue +502 -502
  88. package/src/base-client/components/common/LowCodeComponent/LowCodeRender.vue +728 -728
  89. package/src/base-client/components/common/LowCodeComponent/LowCodeRenderEnter.vue +29 -29
  90. package/src/base-client/components/common/LowCodeComponent/LowCodeUIStore.vue +219 -219
  91. package/src/base-client/components/common/LowCodeComponent/modal/lowCodeAddPageModal.vue +117 -117
  92. package/src/base-client/components/common/LowCodeComponent/modal/lowCodeCustomJSModal.vue +80 -80
  93. package/src/base-client/components/common/LowCodeComponent/modal/lowCodeEventEditorModal.vue +398 -398
  94. package/src/base-client/components/common/LowCodeComponent/modal/lowCodeLifeCycleModal.vue +65 -65
  95. package/src/base-client/components/common/LowCodeComponent/modal/lowCodeLogicCallbackModal.vue +64 -64
  96. package/src/base-client/components/common/LowCodeComponent/modal/lowCodeLogicParamModal.vue +73 -73
  97. package/src/base-client/components/common/LowCodeComponent/modal/lowCodeRunFunctionParamModal.vue +76 -76
  98. package/src/base-client/components/common/PersonSetting/PersonSetting.vue +208 -208
  99. package/src/base-client/components/common/PersonSetting/index.js +3 -3
  100. package/src/base-client/components/common/Recording/Recording.vue +243 -243
  101. package/src/base-client/components/common/Recording/index.js +3 -3
  102. package/src/base-client/components/common/Tree/Tree.vue +149 -149
  103. package/src/base-client/components/common/Tree/index.js +2 -2
  104. package/src/base-client/components/common/Upload/Upload.vue +334 -334
  105. package/src/base-client/components/common/Upload/index.js +3 -3
  106. package/src/base-client/components/common/XAddForm/XAddForm.vue +113 -113
  107. package/src/base-client/components/common/XAddNativeForm/XAddNativeForm.vue +1292 -1288
  108. package/src/base-client/components/common/XAddNativeForm/index.md +146 -146
  109. package/src/base-client/components/common/XAddNativeFormOA/XAddNativeFormOA.vue +304 -304
  110. package/src/base-client/components/common/XAddNativeFormOA/index.js +3 -3
  111. package/src/base-client/components/common/XAddNativeFormOA/index.md +146 -146
  112. package/src/base-client/components/common/XAddReport/index.js +3 -3
  113. package/src/base-client/components/common/XAddReport/index.md +56 -56
  114. package/src/base-client/components/common/XBadge/XBadge.vue +94 -94
  115. package/src/base-client/components/common/XButtons/XButtonDemo.vue +28 -28
  116. package/src/base-client/components/common/XButtons/index.js +3 -3
  117. package/src/base-client/components/common/XButtons/index.md +61 -61
  118. package/src/base-client/components/common/XCalendar/XCalendar.vue +4 -4
  119. package/src/base-client/components/common/XCard/XCard.vue +64 -64
  120. package/src/base-client/components/common/XCheckList/XCheckList.vue +106 -106
  121. package/src/base-client/components/common/XCheckList/XCheckListDemo.vue +41 -41
  122. package/src/base-client/components/common/XDataCard/index.js +3 -3
  123. package/src/base-client/components/common/XDataCard/index.md +1 -1
  124. package/src/base-client/components/common/XDataDrawer/XDataDrawer.vue +180 -180
  125. package/src/base-client/components/common/XDataDrawer/index.js +3 -3
  126. package/src/base-client/components/common/XDataDrawer/index.md +41 -41
  127. package/src/base-client/components/common/XDatePicker/demo.vue +153 -153
  128. package/src/base-client/components/common/XDescriptions/index.js +3 -3
  129. package/src/base-client/components/common/XDescriptions/index.md +83 -83
  130. package/src/base-client/components/common/XDetailsView/XDetailsView.vue +238 -238
  131. package/src/base-client/components/common/XDetailsView/index.js +3 -3
  132. package/src/base-client/components/common/XForm/XStatusButton.vue +54 -54
  133. package/src/base-client/components/common/XForm/index.md +178 -178
  134. package/src/base-client/components/common/XForm/itemComponent/XClickChangeBtn/index.vue +49 -49
  135. package/src/base-client/components/common/XFormGroup/index.js +3 -3
  136. package/src/base-client/components/common/XFormGroup/index.md +38 -38
  137. package/src/base-client/components/common/XFormGroupDetails/index.js +3 -3
  138. package/src/base-client/components/common/XFormTable/demo.vue +89 -89
  139. package/src/base-client/components/common/XFormTable/index.md +92 -92
  140. package/src/base-client/components/common/XLabelSelect/XLabelSelect.vue +110 -110
  141. package/src/base-client/components/common/XLabelSelect/XLabelSelectDemo.vue +35 -35
  142. package/src/base-client/components/common/XLicensePlate/XLicensePlate.vue +193 -193
  143. package/src/base-client/components/common/XLicensePlate/XLicensePlateDemo.vue +48 -48
  144. package/src/base-client/components/common/XPrint/OpenInvoice.vue +21 -21
  145. package/src/base-client/components/common/XPrint/PrintHtml.js +98 -98
  146. package/src/base-client/components/common/XPrint/css/hiPrintCss.js +359 -359
  147. package/src/base-client/components/common/XPrint/css/lodopCss.js +26 -26
  148. package/src/base-client/components/common/XPrint/css/print-lock.css +351 -351
  149. package/src/base-client/components/common/XPrint/index.vue +97 -97
  150. package/src/base-client/components/common/XReport/XReportDesign.vue +463 -463
  151. package/src/base-client/components/common/XReport/XReportJsonRender.vue +381 -381
  152. package/src/base-client/components/common/XReport/index.js +3 -3
  153. package/src/base-client/components/common/XReport/print.js +186 -186
  154. package/src/base-client/components/common/XReportDrawer/index.js +3 -3
  155. package/src/base-client/components/common/XReportGrid/index.js +3 -3
  156. package/src/base-client/components/common/XReportGrid/index.md +44 -44
  157. package/src/base-client/components/common/XReportSlot/XReportSlot.vue +110 -110
  158. package/src/base-client/components/common/XReportSlot/index.js +3 -3
  159. package/src/base-client/components/common/XReportSlot/index.md +48 -48
  160. package/src/base-client/components/common/XSimpleDescriptions/XSimpleDescriptions.vue +166 -166
  161. package/src/base-client/components/common/XSimpleDescriptions/index.js +3 -3
  162. package/src/base-client/components/common/XSimpleDescriptions/index.md +7 -7
  163. package/src/base-client/components/common/XStepView/XStepView.vue +252 -252
  164. package/src/base-client/components/common/XStepView/index.js +3 -3
  165. package/src/base-client/components/common/XStepView/index.md +31 -31
  166. package/src/base-client/components/common/XTab/XTabDemo.vue +22 -22
  167. package/src/base-client/components/common/XTab/index.js +3 -3
  168. package/src/base-client/components/common/XTable/CustomFuncCel.vue +51 -51
  169. package/src/base-client/components/common/XTable/TableCellRenderer.vue +161 -161
  170. package/src/base-client/components/common/XTable/index.md +255 -255
  171. package/src/base-client/components/common/XTagGroup/index.vue +52 -52
  172. package/src/base-client/components/common/XTree/XTree.vue +424 -424
  173. package/src/base-client/components/common/XTree/index.js +3 -3
  174. package/src/base-client/components/common/XTree/index.md +36 -36
  175. package/src/base-client/components/common/XTreeOne/XTreeOne.vue +113 -113
  176. package/src/base-client/components/common/XTreeOne/XTreeOnePro.vue +128 -128
  177. package/src/base-client/components/common/richTextModal/index.vue +56 -56
  178. package/src/base-client/components/common/richTextModal/richDemo.vue +48 -48
  179. package/src/base-client/components/his/XCharge/XChargeDemo.vue +145 -145
  180. package/src/base-client/components/his/XHisEditor/index.js +3 -3
  181. package/src/base-client/components/his/XList/XList.vue +116 -7
  182. package/src/base-client/components/his/XTimeSelect/XTimeSelect.vue +1 -30
  183. package/src/base-client/components/his/XTitle/XTitle.vue +51 -19
  184. package/src/base-client/components/index.js +51 -51
  185. package/src/base-client/components/layout/XTreeView/XTreeView.vue +130 -130
  186. package/src/base-client/components/layout/XTreeView/index.js +3 -3
  187. package/src/base-client/components/layout/XTreeView/index.md +46 -46
  188. package/src/base-client/components/system/DictionaryDetailsView/DictionaryDetailsView.vue +232 -232
  189. package/src/base-client/components/system/QueryParamsDetailsView/QueryParamsDetailsView.vue +281 -281
  190. package/src/base-client/plugins/Config.js +19 -19
  191. package/src/base-client/plugins/GetLoginInfoService.js +183 -183
  192. package/src/base-client/plugins/Recording.js +258 -258
  193. package/src/base-client/plugins/index.js +23 -23
  194. package/src/base-client/plugins/tabs-page-plugin.js +39 -39
  195. package/src/components/Charts/Bar.vue +62 -62
  196. package/src/components/Charts/ChartCard.vue +134 -134
  197. package/src/components/Charts/Liquid.vue +67 -67
  198. package/src/components/Charts/MiniArea.vue +39 -39
  199. package/src/components/Charts/MiniBar.vue +39 -39
  200. package/src/components/Charts/MiniProgress.vue +75 -75
  201. package/src/components/Charts/MiniSmoothArea.vue +40 -40
  202. package/src/components/Charts/Radar.vue +68 -68
  203. package/src/components/Charts/RankList.vue +77 -77
  204. package/src/components/Charts/TagCloud.vue +113 -113
  205. package/src/components/Charts/TransferBar.vue +64 -64
  206. package/src/components/Charts/Trend.vue +82 -82
  207. package/src/components/Charts/chart.less +12 -12
  208. package/src/components/Charts/smooth.area.less +13 -13
  209. package/src/components/CodeMirror/inedx.vue +118 -118
  210. package/src/components/CodeMirror/setting.js +40 -40
  211. package/src/components/NumberInfo/NumberInfo.vue +54 -54
  212. package/src/components/NumberInfo/index.js +3 -3
  213. package/src/components/NumberInfo/index.less +54 -54
  214. package/src/components/NumberInfo/index.md +43 -43
  215. package/src/components/card/ChartCard.vue +79 -79
  216. package/src/components/chart/Bar.vue +60 -60
  217. package/src/components/chart/MiniArea.vue +67 -67
  218. package/src/components/chart/MiniBar.vue +59 -59
  219. package/src/components/chart/MiniProgress.vue +57 -57
  220. package/src/components/chart/Radar.vue +80 -80
  221. package/src/components/chart/RankingList.vue +60 -60
  222. package/src/components/chart/Trend.vue +79 -79
  223. package/src/components/chart/index.less +9 -9
  224. package/src/components/checkbox/ColorCheckbox.vue +157 -157
  225. package/src/components/checkbox/ImgCheckbox.vue +117 -117
  226. package/src/components/checkbox/ImgCheckboxGroup.vue +76 -76
  227. package/src/components/checkbox/index.js +9 -9
  228. package/src/components/exception/ExceptionPage.vue +70 -70
  229. package/src/components/g2Charts/constants.js +202 -202
  230. package/src/components/g2Charts/demo.vue +808 -808
  231. package/src/components/g2Charts/designer.vue +228 -228
  232. package/src/components/g2Charts/designerBaseConfig.vue +61 -61
  233. package/src/components/g2Charts/designerDataConfig.vue +259 -259
  234. package/src/components/g2Charts/designerStyleConfig.vue +16 -16
  235. package/src/components/g2Charts/index.vue +397 -397
  236. package/src/components/index.js +36 -36
  237. package/src/components/input/IInput.vue +66 -66
  238. package/src/components/menu/SideMenu.vue +75 -75
  239. package/src/components/menu/menu.js +273 -273
  240. package/src/components/setting/Setting.vue +234 -234
  241. package/src/components/tool/AStepItem.vue +60 -60
  242. package/src/config/CreateQueryConfig.js +325 -325
  243. package/src/config/default/antd.config.js +89 -89
  244. package/src/config/default/setting.config.js +55 -55
  245. package/src/font-style/font.css +60 -60
  246. package/src/layouts/CommonLayout.vue +56 -56
  247. package/src/layouts/PageLayout.vue +151 -151
  248. package/src/layouts/SinglePageView.vue +136 -136
  249. package/src/layouts/header/AdminHeader.vue +132 -132
  250. package/src/layouts/header/HeaderNotice.vue +177 -177
  251. package/src/layouts/header/InstitutionDetail.vue +181 -181
  252. package/src/layouts/tabs/TabsHead.vue +189 -189
  253. package/src/lib.js +1 -1
  254. package/src/mock/extend/index.js +84 -84
  255. package/src/mock/goods/index.js +108 -108
  256. package/src/pages/DefaultExample/index.vue +77 -77
  257. package/src/pages/DynamicStatistics/ChartSelector.vue +331 -331
  258. package/src/pages/DynamicStatistics/DataTabs.vue +83 -83
  259. package/src/pages/DynamicStatistics/DynamicTable.vue +128 -128
  260. package/src/pages/DynamicStatistics/EvaluationArea.vue +69 -69
  261. package/src/pages/DynamicStatistics/FavoriteList.vue +50 -50
  262. package/src/pages/DynamicStatistics/QuestionHistoryAndFavorites.vue +591 -591
  263. package/src/pages/DynamicStatistics/SearchBar.vue +192 -192
  264. package/src/pages/DynamicStatistics/index.vue +282 -282
  265. package/src/pages/Example/childIndex.vue +15 -15
  266. package/src/pages/Example/index.vue +30 -30
  267. package/src/pages/NewDynamicStatistics/ChartSelector.vue +331 -331
  268. package/src/pages/NewDynamicStatistics/DataTabs.vue +122 -122
  269. package/src/pages/NewDynamicStatistics/DynamicTable.vue +128 -128
  270. package/src/pages/NewDynamicStatistics/EvaluationArea.vue +69 -69
  271. package/src/pages/NewDynamicStatistics/FavoriteList.vue +50 -50
  272. package/src/pages/NewDynamicStatistics/QuestionHistoryAndFavorites.vue +289 -289
  273. package/src/pages/NewDynamicStatistics/SearchBar.vue +193 -193
  274. package/src/pages/NewDynamicStatistics/index.vue +258 -258
  275. package/src/pages/Recording/index.vue +77 -77
  276. package/src/pages/ServiceReview/index.vue +284 -284
  277. package/src/pages/SubExample/index.vue +26 -26
  278. package/src/pages/WorkflowDetail/WorkflowPageDetail/TrimTextTail.vue +23 -23
  279. package/src/pages/XReportView/index.vue +64 -64
  280. package/src/pages/XTreeOneProExample/index.vue +67 -67
  281. package/src/pages/dashboard/workplace/WorkPlace.vue +141 -141
  282. package/src/pages/login/Login.vue +379 -379
  283. package/src/pages/login/LoginV3.vue +389 -389
  284. package/src/pages/lowCode/lowCodeEditor.vue +1219 -1219
  285. package/src/pages/lowCode/lowCodeRenderPage.vue +43 -43
  286. package/src/pages/report/ReportTable.js +124 -124
  287. package/src/pages/resourceManage/orgListManage.vue +98 -98
  288. package/src/pages/system/dictionary/index.vue +44 -44
  289. package/src/pages/system/monitor/loginInfor/index.vue +37 -37
  290. package/src/pages/system/monitor/operLog/index.vue +37 -37
  291. package/src/pages/system/settings/modifyPassword.vue +117 -117
  292. package/src/pages/system/ticket/index.vue +480 -480
  293. package/src/pages/system/ticket/submitTicketSuccess.vue +484 -484
  294. package/src/pages/userInfoDetailManage/ChangeMeterRecordQuery/index.vue +64 -64
  295. package/src/pages/userInfoDetailManage/InfoChangeRecordQuery/index.vue +64 -64
  296. package/src/pages/userInfoDetailManage/InstructRecordQuery/index.vue +64 -64
  297. package/src/pages/userInfoDetailManage/MeterParamRecordQuery/index.vue +64 -64
  298. package/src/pages/userInfoDetailManage/TransferRecordQuery/index.vue +66 -66
  299. package/src/pages/userInfoDetailManage/WatchCollectionRecordQuery/index.vue +64 -64
  300. package/src/plugins/EventLogPlugin.js +33 -33
  301. package/src/plugins/FindParentsData.js +17 -17
  302. package/src/services/DataModel.js +30 -30
  303. package/src/services/LodopFuncs.js +137 -137
  304. package/src/services/api/TicketDetailsViewApi.js +46 -46
  305. package/src/services/api/cas.js +79 -79
  306. package/src/services/api/entity.js +18 -18
  307. package/src/services/api/index.js +17 -17
  308. package/src/store/modules/account.js +115 -115
  309. package/src/store/modules/index.js +5 -5
  310. package/src/store/modules/lowCode.js +33 -33
  311. package/src/store/modules/setting.js +119 -119
  312. package/src/theme/default/style.less +58 -58
  313. package/src/utils/authority-utils.js +85 -85
  314. package/src/utils/errorCode.js +6 -6
  315. package/src/utils/formatter.js +74 -74
  316. package/src/utils/htmlToPDF.js +108 -108
  317. package/src/utils/htmlToPDFApi.js +5 -5
  318. package/src/utils/login.js +188 -188
  319. package/src/utils/lowcode/lowcodeComponentMixin.js +120 -120
  320. package/src/utils/lowcode/lowcodeLog.js +29 -29
  321. package/src/utils/lowcode/lowcodeUtils.js +373 -373
  322. package/src/utils/lowcode/registerComponentForEditor.js +1 -1
  323. package/src/utils/lowcode/registerComponentForRender.js +11 -11
  324. package/src/utils/map-utils.js +47 -47
  325. package/src/utils/reg.js +95 -95
  326. package/src/utils/runEvalFunction.js +14 -14
  327. package/src/utils/theme-color-replacer-extend.js +92 -92
  328. package/src/utils/util.js +329 -329
  329. package/src/utils/waterMark.js +31 -31
  330. package//350/277/201/347/247/273/346/227/245/345/277/227.md +15 -15
@@ -1,1288 +1,1292 @@
1
- <template>
2
- <div id="XAddNativeForm">
3
- <a-form-model
4
- v-if="loaded"
5
- ref="selectForm"
6
- :zIndex="1001"
7
- :model="form"
8
- v-bind="formItemLayoutGen"
9
- :layout="layout">
10
- <template v-for="(item, key) in childTableData">
11
- <a-row
12
- v-if="childTablePriority"
13
- :gutter="16"
14
- :key="'childTableRow' + key">
15
- <a-card :title="item.name" :bordered="false" size="small">
16
- <x-form-table
17
- :key="'childTable_' + item.model"
18
- :title="item.name"
19
- :queryParamsName="item.childTableConfigName"
20
- :localEditMode="true"
21
- :fixed-query-form="childTableFixedQueryForm(item)"
22
- :service-name="serviceName"
23
- @innerXFormTableEmit="innerXFormTableEmit"
24
- @afterTableInit="childTableMounted(item)"
25
- :ref="'childXFormTable_' + item.model">
26
- </x-form-table>
27
- </a-card>
28
- </a-row>
29
- </template>
30
- <template v-if="isSimpleInlineMode">
31
- <a-row
32
- v-for="(row, rowIndex) in simpleInlineRows"
33
- :key="'simple-row-' + rowIndex"
34
- :gutter="0"
35
- type="flex">
36
- <a-col
37
- v-for="(item, itemIndex) in row.items"
38
- :key="'simple-item-' + itemIndex"
39
- :span="item.span">
40
- <x-form-item
41
- class="simple-inline-item"
42
- :attr="item.formItem"
43
- :disabled="itemDisabled(item.formItem)"
44
- :read-only="readonly(item.formItem)"
45
- :files="files"
46
- :form="form"
47
- :images="images"
48
- :service-name="serviceName"
49
- mode="新增/修改"
50
- layout="simple-inline"
51
- :rules="rules[`${item.formItem.name}${item.formItem.model}`]"
52
- :get-data-params="getDataParams"
53
- :env="env"
54
- :enablePopupToBody="enablePopupToBody"
55
- @x-form-item-emit-func="emitFunc"
56
- @rowChoose="rowChoose"
57
- :setForm="setForm"
58
- :style="{ margin: 0, padding: '2px' }"
59
- />
60
- </a-col>
61
- </a-row>
62
- </template>
63
- <a-row ref="GroupItemRow" v-if="!isSimpleInlineMode">
64
- <a-col :span="3" v-if="!inXFormGroup && !(groups[0].groupName === DEFAULT_GROUP_NAME)">
65
- <a-tabs tab-position="left" v-model="activeTab" @change="scrollToGroup">
66
- <a-tab-pane
67
- v-for="(groupsItem,groupsIndex) in groups"
68
- :tab="groupsItem.groupName"
69
- :key="groupsIndex">
70
- </a-tab-pane>
71
- </a-tabs>
72
- </a-col>
73
- <a-col
74
- :span="(!inXFormGroup && !(groups[0].groupName === DEFAULT_GROUP_NAME)) ? 21: 24">
75
- <a-row
76
- :gutter="16"
77
- type="flex"
78
- :key="groupsIndex"
79
- v-for="(groupsItem,groupsIndex) in groups"
80
- >
81
- <a-col
82
- :span="24"
83
- :style="{ marginTop: groupsIndex === 0 ? '' : '8px',fontSize:inXFormGroup?'15px':'14px', marginLeft:'-5px' }"
84
- v-if="groupsItem.groupName !== DEFAULT_GROUP_NAME">
85
- <span class="xFormGroupTitle" :ref="`group-title-${groupsIndex}`">{{ groupsItem.groupName }}</span>
86
- </a-col>
87
- <x-form-item
88
- v-for="(item, index) in groupsItem.realJsonData"
89
- :key="index"
90
- :attr="item"
91
- :disabled="itemDisabled(item)"
92
- :read-only="readonly(item)"
93
- :files="files"
94
- v-bind="formItemLayoutGen"
95
- :style="layout === 'inline' ? { marginTop:'5px' } : undefined"
96
- :form="form"
97
- :images="images"
98
- :enablePopupToBody="enablePopupToBody"
99
- :service-name="serviceName"
100
- mode="新增/修改"
101
- :layout="layout"
102
- :rules="rules[`${item.name}${item.model}`]"
103
- :get-data-params="getDataParams"
104
- :env="env"
105
- @x-form-item-emit-func="emitFunc"
106
- @rowChoose="rowChoose"
107
- :setForm="setForm"
108
- />
109
- </a-row>
110
- </a-col>
111
- </a-row>
112
- <a-row :gutter="16" v-for="(groupItem, groupIndex) in groupJsonData" :key="groupIndex" v-if="!isSimpleInlineMode">
113
- <a-card v-if="groupItem.groupItems.length > 0" :title="groupItem.name" :bordered="false" size="small">
114
- <x-form-item
115
- v-for="(item, index) in groupItem.groupItems"
116
- :key="index"
117
- :attr="item"
118
- :disabled="itemDisabled(item)"
119
- :readonly="readonly(item)"
120
- :files="files"
121
- v-bind="formItemLayoutGen"
122
- :style="layout ==='inline'?{marginTop:'5px'}:undefined"
123
- :form="form[groupItem.model]"
124
- :images="images"
125
- :service-name="serviceName"
126
- mode="新增/修改"
127
- :rules="rules[`${item.name}${item.model}`]"
128
- :get-data-params="getDataParams"
129
- :env="env"
130
- :setForm="setForm"
131
- @rowChoose="rowChoose"
132
- />
133
- </a-card>
134
- <template v-else>
135
- <slot
136
- name="groupFormItems"
137
- :form="form"
138
- :model="groupItem.model"
139
- :rules="rules"
140
- :modifyModelData="modifyModelData"></slot>
141
- </template>
142
- </a-row>
143
- <a-row :gutter="16" v-for="(item, key) in simpleFormJsonData" :key="'row' + key" v-if="!isSimpleInlineMode">
144
- <a-card v-if="item.value.length > 0" :title="item.name" :bordered="false" size="small">
145
- <x-form-item
146
- v-for="(formItem, formItemIndex) in item.value"
147
- :key="key + formItemIndex"
148
- :attr="formItem"
149
- :disabled="itemDisabled(formItem)"
150
- :readonly="readonly(formItem)"
151
- :files="files"
152
- :enablePopupToBody="enablePopupToBody"
153
- v-bind="formItemLayoutGen"
154
- :style="layout ==='inline'?{marginTop:'5px'}:undefined"
155
- :form="form[groupItem.model]"
156
- :images="images"
157
- :service-name="serviceName"
158
- mode="新增/修改"
159
- :rules="rules[`${item.name}${item.model}`]"
160
- :get-data-params="getDataParams"
161
- :env="env"
162
- :setForm="setForm"
163
- @rowChoose="rowChoose"
164
- />
165
- </a-card>
166
- </a-row>
167
- <template v-for="(item, key) in childTableData">
168
- <a-row
169
- v-if="!childTablePriority"
170
- :gutter="16"
171
- :key="'childTableRow' + key">
172
- <a-card :title="item.name" :bordered="false" size="small">
173
- <x-form-table
174
- :key="'childTable_' + item.model"
175
- :title="item.name"
176
- :queryParamsName="item.childTableConfigName"
177
- :localEditMode="true"
178
- @innerXFormTableEmit="innerXFormTableEmit"
179
- :fixed-query-form="childTableFixedQueryForm(item)"
180
- :service-name="serviceName"
181
- @afterTableInit="childTableMounted(item)"
182
- :ref="'childXFormTable_' + item.model">
183
- </x-form-table>
184
- </a-card>
185
- </a-row>
186
- </template>
187
- <a-row type="flex" :justify="btnPlace" :style="{paddingLeft: '16px',paddingRight: '16px'}">
188
- <slot name="footer" :loading="loading">
189
- <a-button v-if="showSubmitBtn" :loading="loading" type="primary" @click="onSubmit()">{{ btnName }}</a-button>
190
- </slot>
191
- </a-row>
192
- </a-form-model>
193
- </div>
194
- </template>
195
- <script>
196
- import XFormItem from '@vue2-client/base-client/components/common/XForm/XFormItem'
197
- import { formatDate, setDataByRealKey } from '@vue2-client/utils/util'
198
- import * as util from '@vue2-client/utils/util'
199
- import { mapState } from 'vuex'
200
- import { addOrModify, getConfigByName, getConfigByNameAsync, runLogic } from '@vue2-client/services/api/common'
201
- import { checkIdNumber, REG_EMAIL, REG_LANDLINE, REG_PHONE } from '@vue2-client/utils/reg'
202
- import moment from 'moment/moment'
203
- import { executeStrFunction, executeStrFunctionByContext } from '@vue2-client/utils/runEvalFunction'
204
- import formValidationMixin from '@vue2-client/mixins/formValidationMixin'
205
-
206
- const DEFAULT_GROUP_NAME = '__default__'
207
- export default {
208
- name: 'XAddNativeForm',
209
- components: {
210
- XFormItem,
211
- XFormTable: () => import('@vue2-client/base-client/components/common/XFormTable/XFormTable.vue')
212
- },
213
- inject: {
214
- inXFormGroup: {
215
- default: false
216
- },
217
- formGroupContext: {
218
- default: null
219
- },
220
- formDataChange: {
221
- default: null
222
- }
223
- },
224
- props: {
225
- // 是否启用 horizontal 模式的自定义配置
226
- enableHorizontalCustom: {
227
- type: Boolean,
228
- default: false
229
- },
230
- // 是否启用时间弹出到最外层
231
- enablePopupToBody: {
232
- type: Boolean,
233
- default: false
234
- }
235
- },
236
- data () {
237
- return {
238
- DEFAULT_GROUP_NAME,
239
- // 预览模式
240
- viewMode: false,
241
- // 是否处理表单Key值
242
- isHandleFormKey: true,
243
- // 内容加载是否完成
244
- loaded: false,
245
- // 业务类型
246
- businessType: '',
247
- // 业务标题
248
- title: '',
249
- // 新增或修改业务是否执行中
250
- loading: false,
251
- // 表单Model
252
- form: {},
253
- // 配置名称
254
- configName: undefined,
255
- // 配置内容,用于查询配置生成器的预览
256
- configContent: undefined,
257
- // 表单项集合
258
- formItems: [],
259
- // 服务名称
260
- serviceName: undefined,
261
- // 是否显示提交按钮
262
- showSubmitBtn: true,
263
- // 修改有文件的表单时使用
264
- files: [],
265
- images: [],
266
- // 校验
267
- rules: {},
268
- // 调用logic获取数据源的追加参数
269
- getDataParams: {},
270
- // 动态简易表单集合
271
- simpleFormJsonData: {},
272
- // 待修改的数据集
273
- modifyModelData: {},
274
- // 当前环境
275
- env: 'prod',
276
- // 表单主键
277
- primaryKey: null,
278
- // 表单模式 horizontal | vertical | inline
279
- layout: 'horizontal',
280
- // 提交按钮名称
281
- btnName: '提交',
282
- // 提交按钮位置 start / center / end
283
- btnPlace: 'center',
284
- // 子表是否排在前面
285
- childTablePriority: false,
286
- // simple-inline布局配置
287
- simpleInline: null
288
- }
289
- },
290
- computed: {
291
- // 过滤出用于新增/修改场景的表单项
292
- realJsonData: function () {
293
- return this.formItems.filter((item) => {
294
- return item.addOrEdit && item.addOrEdit !== 'no' && item.addOrEdit !== 'silenceAdd' && item.addOrEdit !== 'version' && !this.itemDisabled(item)
295
- })
296
- },
297
- // 表单项组 / 不是 数据组
298
- groups: function () {
299
- if (!this.realJsonData || this.realJsonData.length === 0) {
300
- return [{
301
- groupName: DEFAULT_GROUP_NAME,
302
- realJsonData: this.realJsonData,
303
- xAddFormLayout: 'horizontal'
304
- }]
305
- }
306
- const uniqueGroups = new Set(this.realJsonData.map(item => item.group).filter(Boolean))
307
- const allGroup = Array.from(uniqueGroups).map(group => {
308
- return {
309
- groupName: group,
310
- realJsonData: this.realJsonData.filter(item => item.group === group),
311
- xAddFormLayout: 'horizontal'
312
- }
313
- })
314
- // 判断每一组得formJson 长度相加是否等于 realJsonData 长度 避免错误数据
315
- if (allGroup.reduce((total, item) => total + item.realJsonData.length, 0) === this.realJsonData.length) {
316
- return allGroup
317
- } else {
318
- return [{
319
- groupName: DEFAULT_GROUP_NAME,
320
- realJsonData: this.realJsonData,
321
- xAddFormLayout: 'horizontal'
322
- }]
323
- }
324
- },
325
- // 拥有自定义校验函数得表单项
326
- customValidateItems: function () {
327
- return this.formItems.filter((item) => {
328
- return item?.rule?.type === 'customJs'
329
- })
330
- },
331
- // 过滤出用于新增/修改场景的表单项
332
- groupJsonData: function () {
333
- return this.formItems.filter((item) => {
334
- return item.type === 'group'
335
- }).map((item) => {
336
- item.groupItems = item.groupItems.filter((item) => {
337
- return item.addOrEdit && item.addOrEdit !== 'no' && item.addOrEdit !== 'silenceAdd' && item.addOrEdit !== 'version' && !this.itemDisabled(item)
338
- }).map((groupItem) => {
339
- // 只保留第一个下划线后面的内容
340
- // 多层校验规则需要将prop设置为 key1.key2.....
341
- groupItem.prop = `${item.model}.${groupItem.model.substring(groupItem.model.indexOf('_') + 1)}`
342
- groupItem.model = groupItem.model.substring(groupItem.model.indexOf('_') + 1)
343
- return groupItem
344
- })
345
- return item
346
- }
347
- )
348
- },
349
- // 过滤出用于子表数据新增/修改场景的表单项
350
- childTableData: function () {
351
- return this.formItems.filter((item) => {
352
- return item.type === 'childTable'
353
- })
354
- },
355
- // 过滤出用于form子表数据新增/修改场景的表单项
356
- childFormData: function () {
357
- return this.formItems.filter((item) => {
358
- return item.type === 'rowEdit'
359
- })
360
- },
361
- // 过滤出用于静默新增场景的表单项
362
- silenceAddJsonData: function () {
363
- return this.formItems.filter(function (item) {
364
- return item.addOrEdit === 'silenceAdd'
365
- })
366
- },
367
- // 过滤出版本号表单项
368
- versionJsonData: function () {
369
- return this.formItems.filter(function (item) {
370
- return item.addOrEdit === 'version'
371
- })
372
- },
373
- formItemLayoutGen () {
374
- if (this.layout === 'simple-inline') {
375
- return {
376
- labelCol: { span: 0 },
377
- wrapperCol: { span: 24 }
378
- }
379
- }
380
- if (this.layout === 'horizontal') {
381
- // 如果启用了自定义配置,从 formItemLayout 读取(支持 0 值)
382
- if (this.enableHorizontalCustom && this.formItemLayout) {
383
- return {
384
- labelCol: {
385
- span: (this.formItemLayout.labelCol ?? 4),
386
- offset: (this.formItemLayout.offset ?? 2)
387
- },
388
- wrapperCol: { span: (this.formItemLayout.wrapperCol ?? 14) },
389
- }
390
- }
391
- // 默认配置
392
- return {
393
- labelCol: { span: 4, offset: 2 },
394
- wrapperCol: { span: 14 },
395
- }
396
- } else if (this.layout === 'vertical') {
397
- return {}
398
- } else {
399
- if (!this.formItemLayout.labelCol || !this.formItemLayout.wrapperCol) {
400
- return {
401
- labelCol: { span: 8 },
402
- wrapperCol: { span: 16 },
403
- }
404
- }
405
- return {
406
- labelCol: { span: this.formItemLayout.labelCol },
407
- wrapperCol: { span: this.formItemLayout.wrapperCol },
408
- }
409
- }
410
- },
411
- // simple-inline模式判断
412
- isSimpleInlineMode () {
413
- return this.layout === 'simple-inline' && this.simpleInline
414
- },
415
- // simple-inline布局行数据
416
- simpleInlineRows () {
417
- if (!this.isSimpleInlineMode) return []
418
- return this.simpleInline.rows.map(row => ({
419
- ...row,
420
- items: row.items.map(item => ({
421
- ...item,
422
- formItem: this.realJsonData.find(f =>
423
- f.model === item.key && f.name === item.title
424
- )
425
- })).filter(item => item.formItem)
426
- }))
427
- },
428
- ...mapState('account', { currUser: 'user' })
429
- },
430
- provide () {
431
- return {
432
- getComponentByName: this.getComponentByName,
433
- registerComponent: this.registerComponent,
434
- XFormContext: this,
435
- // 移除必填项
436
- removeRequired: this.removeRequired,
437
- // 设置必填项
438
- setRequired: this.setRequired,
439
- getSelf: () => this,
440
- }
441
- },
442
- watch: {
443
- form: {
444
- handler (val) {
445
- if (this.formDataChange && typeof this.formDataChange === 'function') {
446
- this.formDataChange(val)
447
- }
448
- },
449
- deep: true
450
- }
451
- },
452
- /** //todo 本来想要实现 配置 自定义函数时,表单项得红星提示,根据自定义校验函数得返回值来判断
453
- * 但是监听不到父组件formgorup得其他form得变化,所以暂时不实现
454
- */
455
- //
456
- // watch: {
457
- // form: {
458
- // handler (val) {
459
- // // 遍历表单配置
460
- // if (this.customValidateItems.length > 0) {
461
- // for (const item of this.customValidateItems) {
462
- // const itemIndex = this.formItems.findIndex(formItem => formItem.model === item.model)
463
- // if (itemIndex < 0) {
464
- // continue
465
- // }
466
- // try {
467
- // this.customJsValidate(null, val[item.model], (res) => {
468
- // // 如果返回error则设置错误信息
469
- // if (res instanceof Error) {
470
- // // 设置表单项的错误状态
471
- // this.$set(this.formItems[itemIndex], 'tempRequired', true)
472
- // } else {
473
- // // 清除错误状态
474
- // this.$set(this.formItems[itemIndex], 'tempRequired', true)
475
- // }
476
- // }, item)
477
- // } catch (e) {
478
- // console.error(e)
479
- // this.$set(this.formItems[itemIndex], 'tempRequired', true)
480
- // }
481
- // }
482
- // console.log('customValidateItems', JSON.stringify(this.customValidateItems))
483
- // }
484
- // },
485
- // deep: true
486
- // }
487
- // },
488
- mixins: [formValidationMixin],
489
- methods: {
490
- runLogic,
491
- getConfigByNameAsync,
492
- getConfigByName,
493
- init (params) {
494
- const {
495
- configName,
496
- configContent,
497
- formItems,
498
- formJson,
499
- viewMode,
500
- isHandleFormKey,
501
- isKeyHandle = true,
502
- showSubmitBtn = true,
503
- serviceName,
504
- primaryKey,
505
- modifyModelData = {},
506
- businessType,
507
- title,
508
- fixedAddForm = {},
509
- getDataParams = {},
510
- simpleFormJsonData = {},
511
- env = 'prod',
512
- layout,
513
- xAddFormLayout = 'horizontal',
514
- formItemLayout = {},
515
- btnName = '提交',
516
- childTablePriority = false,
517
- btnPlace = 'center',
518
- simpleInline = null,
519
- paramLogicName,
520
- paramLogicNameParam
521
- } = params
522
- this.loaded = false
523
- // 兼容需要省略 传递 layout: res.xAddFormLayout 可以使用 ...res 展开运算符 直接转递
524
- if (xAddFormLayout && layout === undefined) {
525
- this.layout = xAddFormLayout
526
- } else {
527
- this.layout = layout
528
- }
529
- this.formItemLayout = formItemLayout
530
- if ((isHandleFormKey === null || isHandleFormKey === undefined) && !isKeyHandle) {
531
- this.isHandleFormKey = isKeyHandle
532
- } else if (isHandleFormKey) {
533
- this.isHandleFormKey = isHandleFormKey
534
- } else {
535
- this.isHandleFormKey = isKeyHandle
536
- }
537
- this.childTablePriority = childTablePriority
538
- this.configName = configName
539
- this.configContent = configContent
540
- this.formItems = this.getFromItem(formItems, formJson)
541
- this.viewMode = viewMode
542
- this.showSubmitBtn = showSubmitBtn
543
- this.primaryKey = primaryKey
544
- this.serviceName = serviceName
545
- this.businessType = businessType
546
- this.title = title
547
- this.getDataParams = getDataParams
548
- this.simpleFormJsonData = simpleFormJsonData
549
- this.env = env
550
- this.btnName = btnName
551
- this.btnPlace = btnPlace
552
- this.simpleInline = simpleInline
553
- // 如果 fixedAddForm 有 selected_id 值,并且设置了处理表单key值,则多给 selected_id 加前缀 避免处理错误
554
- if (fixedAddForm.selected_id && this.isHandleFormKey) {
555
- fixedAddForm._selected_id = fixedAddForm.selected_id
556
- delete fixedAddForm.selected_id
557
- }
558
- // 设置普通表单项的相关参数
559
- const formData = Object.assign({}, fixedAddForm)
560
- if (paramLogicName) {
561
- runLogic(paramLogicName, paramLogicNameParam, this.serviceName).then(res => {
562
- Object.assign(formData, res)
563
- })
564
- }
565
- for (let i = 0; i < this.realJsonData.length; i++) {
566
- const item = this.realJsonData[i]
567
- this.setFormProps(formData, item, null)
568
- }
569
- // 设置表单分组项目相关参数
570
- for (let i = 0; i < this.groupJsonData.length; i++) {
571
- const groupItem = this.groupJsonData[i]
572
- formData[groupItem.model] = {}
573
- for (let j = 0; j < groupItem.groupItems.length; j++) {
574
- const item = groupItem.groupItems[j]
575
- this.setFormProps(formData[groupItem.model], item, item.prop)
576
- }
577
- }
578
- // 设置动态简易表单项的相关参数
579
- for (const key in this.simpleFormJsonData) {
580
- for (const item of this.simpleFormJsonData[key].value) {
581
- item.model = key + '@' + item.model
582
- this.setFormProps(formData, item, null)
583
- }
584
- }
585
-
586
- this.form = formData
587
- // 修改场景下对表单项赋值
588
- if (modifyModelData && modifyModelData.data) {
589
- this.modifyModelData = modifyModelData
590
- if (Object.keys(modifyModelData.data).length > 0) {
591
- this.getModifyModelData(modifyModelData)
592
- }
593
- }
594
- // 处理表单得附件
595
- if (modifyModelData && modifyModelData.files) {
596
- this.files = modifyModelData.files
597
- }
598
- if (modifyModelData && modifyModelData.images) {
599
- this.images = modifyModelData.images
600
- }
601
- this.loaded = true
602
- },
603
- scrollToGroup (index) {
604
- const groupElement = this.$refs[`group-title-${index}`][0]
605
- if (groupElement) {
606
- groupElement.scrollIntoView({ behavior: 'smooth' })
607
- }
608
- },
609
- registerComponent (componentName, component) {
610
- console.log('内部注册', this.$options.name, componentName)
611
- this.$refs[componentName] = component
612
- console.log('内部注册完成', this.$refs)
613
- },
614
- // 根据名字从注册到组件中获取组件
615
- getComponentByName (componentName) {
616
- console.log('内部取组件', this.$options.name, componentName)
617
- console.log('内部组件内容', this.$refs)
618
- return this.$refs[componentName]
619
- },
620
- // 兼容需要省略 传递 [formItems: res.formJson ] 可以使用 ...res 展开运算符 直接转递
621
- getFromItem (formItems, formJson) {
622
- const _formItems = formItems || formJson
623
- if (typeof formItems === 'string') {
624
- return JSON.parse(_formItems)
625
- } else {
626
- return JSON.parse(JSON.stringify(_formItems))
627
- }
628
- },
629
- innerXFormTableEmit (fun, record, id, actionType, index) {
630
- this.$emit(fun, record, id, actionType, index)
631
- },
632
- // 时间组件赋默认值
633
- // .type, item.formDefault
634
- getDateRange ({ type, formDefault: defaultValue, formValueFormat }) {
635
- // const format = type === 'datePicker' ? 'YYYY-MM-DD' : 'YYYY-MM-DD HH:mm:ss'
636
- let format = 'YYYY-MM-DD HH:mm:ss'
637
- if (formValueFormat) {
638
- format = formValueFormat
639
- }
640
- let start
641
- switch (defaultValue) {
642
- case 'curYear':
643
- start = moment().startOf('year').format(format)
644
- break
645
- case 'curMonth':
646
- start = moment().startOf('month').format(format)
647
- break
648
- case 'curDay':
649
- start = moment().startOf('day').format(format)
650
- break
651
- case 'curTime':
652
- start = moment().format(format)
653
- break
654
- default:
655
- return defaultValue
656
- }
657
- return start
658
- },
659
- setFormProps (formData, item, groupItem) {
660
- const rulesKey = `${item.name}${item.model}`
661
- if (formData[item.model] === undefined || formData[item.model] === null) {
662
- formData[item.model] = undefined
663
- }
664
- if (!formData[item.model] && item.formDefault) {
665
- if (['datePicker', 'rangePicker', 'yearPicker', 'monthPicker', 'yearRangePicker', 'monthRangePicker'].includes(item.type)) {
666
- formData[item.model] = this.getDateRange(item)
667
- } else if (['treeSelect', 'select', 'checkbox'].includes(item.type) && ['curOrgId', 'curDepId', 'curUserId'].includes(item.formDefault)) {
668
- if (item.formDefault === 'curOrgId') {
669
- formData[item.model] = item.type === 'select' ? this.currUser.orgid : [this.currUser.orgid]
670
- }
671
- if (item.formDefault === 'curDepId') {
672
- formData[item.model] = item.type === 'select' ? this.currUser.depids : [this.currUser.depids]
673
- }
674
- if (item.formDefault === 'curUserId') {
675
- formData[item.model] = item.type === 'select' ? this.currUser.id : [this.currUser.id]
676
- }
677
- } else if (['addressSearch'].includes(item.type)) {
678
- formData[item.model] = item.formDefault
679
- formData[`${item.model}_lng_lat`] = item.formDefault_lng_lat
680
- } else {
681
- formData[item.model] = item.formDefault
682
- }
683
- }
684
- // 处理表单校验情况
685
- if (item.rule) {
686
- if (groupItem) {
687
- this.rules[groupItem] = []
688
- } else {
689
- this.rules[rulesKey] = []
690
- }
691
- const required = item.rule.required ? item.rule.required === true || item.rule.required === 'true' : false
692
- let trigger
693
- let message
694
- if (required) {
695
- switch (item.type) {
696
- case 'select':
697
- case 'checkbox':
698
- case 'radio':
699
- case 'treeSelect':
700
- case 'rangePicker':
701
- case 'monthPicker':
702
- case 'yearPicker':
703
- case 'datePicker':
704
- case 'file':
705
- case 'image':
706
- case 'citySelect':
707
- case 'addressSearch':
708
- case 'personSetting':
709
- message = '请选择' + item.name
710
- trigger = 'change'
711
- break
712
- default:
713
- message = '请输入' + item.name
714
- trigger = 'blur'
715
- }
716
- if (groupItem) {
717
- this.rules[groupItem].push({
718
- required: true,
719
- message: message,
720
- trigger: trigger
721
- })
722
- } else {
723
- this.rules[rulesKey].push({
724
- required: true,
725
- message: message,
726
- trigger: trigger
727
- })
728
- }
729
- }
730
-
731
- switch (item.rule.type) {
732
- case 'number':
733
- case 'integer':
734
- case 'float':
735
- // eslint-disable-next-line no-case-declarations
736
- let defaultValue
737
- // eslint-disable-next-line no-case-declarations
738
- let message
739
- switch (item.rule.type) {
740
- case 'number':
741
- item.numberInput = true
742
- message = '数字'
743
- defaultValue = 0
744
- break
745
- case 'integer':
746
- item.numberInput = true
747
- message = '整数'
748
- defaultValue = 0
749
- break
750
- case 'float':
751
- item.numberInput = true
752
- message = '小数'
753
- defaultValue = 0.0
754
- break
755
- }
756
- if (groupItem) {
757
- this.rules[groupItem].push({
758
- type: item.rule.type,
759
- message: item.name + '必须为' + message,
760
- transform: (value) => {
761
- if (value && value.length !== 0) {
762
- return Number(value)
763
- } else {
764
- return defaultValue
765
- }
766
- },
767
- trigger: 'blur'
768
- })
769
- } else {
770
- this.rules[rulesKey].push({
771
- type: item.rule.type,
772
- message: item.name + '必须为' + message,
773
- transform: (value) => {
774
- if (value && value.length !== 0) {
775
- return Number(value)
776
- } else {
777
- return defaultValue
778
- }
779
- },
780
- trigger: 'blur'
781
- })
782
- }
783
- break
784
- case 'email': {
785
- const validator = (rule, value, callback) => {
786
- if (value && !REG_EMAIL.test(value)) {
787
- callback(new Error('请输入正确的邮箱地址'))
788
- } else {
789
- callback()
790
- }
791
- }
792
- this.rules[groupItem || rulesKey].push({
793
- type: 'email',
794
- validator: validator,
795
- message: '请输入正确的邮箱地址',
796
- trigger: 'blur'
797
- })
798
- break
799
- }
800
- case 'userPhone': {
801
- this.rules[groupItem || rulesKey].push({
802
- type: 'userPhone',
803
- validator: (rule, value, callback) => {
804
- if (value && !REG_PHONE.test(value)) {
805
- callback(new Error('请输入正确的手机号码'))
806
- } else {
807
- callback()
808
- }
809
- },
810
- message: '请输入正确的手机号码',
811
- trigger: 'blur'
812
- })
813
- break
814
- }
815
- case 'idNumber': {
816
- this.rules[groupItem || rulesKey].push({
817
- validator: (rule, value, callback) => {
818
- if (value && !checkIdNumber(value)) {
819
- callback(new Error('请输入正确的身份证号码'))
820
- } else {
821
- callback()
822
- }
823
- },
824
- trigger: 'blur'
825
- })
826
- break
827
- }
828
- case 'landlineNumber': {
829
- this.rules[rulesKey].push({
830
- validator: (rule, value, callback) => {
831
- if (value && !REG_LANDLINE.test(value)) {
832
- callback(new Error('请输入正确的座机号码'))
833
- } else {
834
- callback()
835
- }
836
- },
837
- trigger: 'blur'
838
- })
839
- break
840
- }
841
- // 大于0
842
- case 'greaterThanZero': {
843
- item.numberInput = true
844
- this.rules[rulesKey].push({
845
- validator: (rule, value, callback) => {
846
- if (isNaN(value) || value <= 0) {
847
- callback(new Error('请输入一个大于0的数字'))
848
- } else {
849
- callback()
850
- }
851
- },
852
- trigger: 'blur'
853
- })
854
- break
855
- }
856
- // 大于等于0
857
- case 'greaterThanOrEqualZero': {
858
- item.numberInput = true
859
- this.rules[rulesKey].push({
860
- validator: (rule, value, callback) => {
861
- if (isNaN(value) || value < 0) {
862
- callback(new Error('请输入一个大于等于0的数字'))
863
- } else {
864
- callback()
865
- }
866
- },
867
- trigger: 'blur'
868
- })
869
- break
870
- }
871
- case 'stringLength': {
872
- this.rules[rulesKey].push({
873
- validator: (rule, value, callback) => {
874
- if (value && value.length < item.rule.minLen) {
875
- callback(new Error('长度不能少于' + item.rule.minLen + '个字符'))
876
- } else if (value && value.length > item.rule.maxLen) {
877
- callback(new Error('长度不能超过' + item.rule.maxLen + '个字符'))
878
- } else {
879
- callback()
880
- }
881
- },
882
- trigger: 'blur'
883
- })
884
- break
885
- }
886
- case 'customJs': {
887
- this.rules[rulesKey].push({
888
- validator: (rule, value, callback) => {
889
- this.customJsValidate(rule, value, callback, item)
890
- },
891
- trigger: 'blur'
892
- })
893
- break
894
- }
895
- }
896
- }
897
- },
898
- childTableMounted (item) {
899
- // 子表初始化时,设置表格数据
900
- if (this.form[item.model] && this.form[item.model].length > 0) {
901
- this.$refs[`childXFormTable_${item.model}`][0].setTableData(this.form[item.model])
902
- }
903
- },
904
- customJsValidate (rule, value, callback, item) {
905
- if (item.rule.customValidatorFunc) {
906
- executeStrFunctionByContext(this, item.rule.customValidatorFunc, [rule, value, callback, this.form, item, this.util, runLogic, getConfigByNameAsync])
907
- } else {
908
- callback()
909
- }
910
- },
911
- itemDisabled (value) {
912
- return (this.businessType === '新增' && value.addOrEdit === 'edit') ||
913
- (this.businessType === '修改' && value.addOrEdit === 'add')
914
- },
915
- readonly (value) {
916
- return value.addOrEdit === 'readonly'
917
- },
918
- async onSubmit () {
919
- const valid = await this.validateForm()
920
- if (!valid) return false
921
- if (this.viewMode) {
922
- this.$message.info('预览模式禁止新增和修改')
923
- return false
924
- }
925
- this.loading = true
926
- const requestForm = this.prepareForm()
927
- await this.appendSilenceAddFields(requestForm)
928
- const realForm = this.handleFormKeys(requestForm)
929
- // 增加子表数据
930
- if (this.childTableData.length > 0) {
931
- for (const item of this.childTableData) {
932
- const childModel = item.model
933
- const childDataRef = this.$refs['childXFormTable_' + item.model][0].getTableData()
934
- const childData = []
935
- for (const item of childDataRef) {
936
- childData.push(JSON.parse(JSON.stringify(item)))
937
- }
938
- for (let i = 0; i < childData.length; i++) {
939
- childData[i] = this.handleFormKeys(childData[i])
940
- // 外键不需要带表别名,所以此处放到表单处理后赋值
941
- if (realForm.id) {
942
- childData[i][item.childTableForeignKeyName] = realForm.id
943
- }
944
- }
945
- realForm[childModel] = childData
946
- }
947
- }
948
- // 增加form子表数据
949
- if (this.childFormData.length > 0) {
950
- for (const item of this.childFormData) {
951
- const childModel = item.model
952
- const childData = this.$refs[item.model].getTableData()
953
- for (let i = 0; i < childData.length; i++) {
954
- childData[i] = this.handleFormKeys(childData[i], true)
955
- // 外键不需要带表别名,所以此处放到表单处理后赋值
956
- if (realForm.id) {
957
- childData[i][item.foreignKey] = realForm.id
958
- }
959
- }
960
- realForm[childModel] = childData
961
- }
962
- }
963
- if (this.$listeners.onSubmit) {
964
- // 交由父级处理
965
- this.$emit('onSubmit', {
966
- businessType: this.businessType,
967
- serviceName: this.serviceName,
968
- realForm: realForm,
969
- currUserName: this.currUser.name,
970
- currUserId: this.currUser.id,
971
- orgId: this.currUser.orgid
972
- })
973
- } else {
974
- this.defaultSubmit(realForm)
975
- }
976
- },
977
-
978
- async asyncSubmit () {
979
- return new Promise((resolve, reject) => {
980
- this.$refs.selectForm.validate(async valid => {
981
- if (!valid) {
982
- reject(new Error('Form validation failed'))
983
- return
984
- }
985
- this.loading = true
986
- const requestForm = this.prepareForm()
987
- await this.appendSilenceAddFields(requestForm)
988
- const realForm = this.handleFormKeys(requestForm)
989
- resolve({
990
- realForm,
991
- businessType: this.businessType,
992
- serviceName: this.serviceName,
993
- currUserName: this.currUser.name,
994
- currUserId: this.currUser.id,
995
- orgId: this.currUser.orgid
996
- })
997
- })
998
- })
999
- },
1000
-
1001
- validateForm () {
1002
- return new Promise((resolve) => {
1003
- this.$refs.selectForm.validate(valid => resolve(valid))
1004
- })
1005
- },
1006
-
1007
- childTableFixedQueryForm (item) {
1008
- if (this.modifyModelData?.primaryKeyData) {
1009
- const fixedForm = {}
1010
- fixedForm[item.childTableForeignKeyName] = Object.values(this.modifyModelData.primaryKeyData)[0]
1011
- return fixedForm
1012
- }
1013
- return null
1014
- },
1015
-
1016
- prepareForm () {
1017
- const form = { ...this.form }
1018
- for (const key of Object.keys(form)) {
1019
- const value = form[key]
1020
- if (value === null || (typeof value === 'object' && Object.keys(value).length === 0)) {
1021
- form[key] = undefined
1022
- }
1023
- }
1024
- return form
1025
- },
1026
-
1027
- async appendSilenceAddFields (form) {
1028
- if (this.businessType === '新增') {
1029
- for (const item of this.silenceAddJsonData) {
1030
- switch (item.silencePurpose) {
1031
- case 'createTime':
1032
- form[item.model] = formatDate('now')
1033
- break
1034
- case 'operator':
1035
- form[item.model] = this.currUser.name
1036
- break
1037
- case 'operatorId':
1038
- form[item.model] = this.currUser.id
1039
- break
1040
- case 'orgId':
1041
- form[item.model] = this.currUser.orgid
1042
- break
1043
- case 'orgName':
1044
- form[item.model] = this.currUser.orgs
1045
- break
1046
- case 'depId':
1047
- form[item.model] = this.currUser.depids
1048
- break
1049
- case 'depName':
1050
- form[item.model] = this.currUser.deps
1051
- break
1052
- }
1053
- }
1054
- for (const item of this.silenceAddJsonData.filter((item) => item.silencePurpose === 'customize')) {
1055
- const result = await runLogic(item.silenceSource, form, this.serviceName)
1056
- if (result) {
1057
- const keys = Object.keys(result)
1058
- if (keys.length === 1 && keys[0] === 'value') {
1059
- form[item.model] = result.value
1060
- } else {
1061
- form[item.model] = result
1062
- }
1063
- } else {
1064
- form[item.model] = result
1065
- }
1066
- }
1067
- }
1068
- },
1069
-
1070
- handleFormKeys (form, mustHandleKey = false) {
1071
- const realForm = {}
1072
- for (const key of Object.keys(form)) {
1073
- const value = form[key]
1074
- const extraFormKeyTagIndex = key.indexOf('@')
1075
- if (extraFormKeyTagIndex !== -1) {
1076
- const extraFormKey = key.substring(0, extraFormKeyTagIndex)
1077
- const realKey = key.substring(extraFormKeyTagIndex + 1)
1078
- if (!realForm[extraFormKey]) {
1079
- realForm[extraFormKey] = {}
1080
- }
1081
- realForm[extraFormKey][realKey] = value
1082
- } else {
1083
- const realKey = this.isHandleFormKey || mustHandleKey ? this.getRealKey(key, mustHandleKey) : key
1084
- // 如果发生重名,不覆盖,把key的别名带上
1085
- if (realForm[realKey]) {
1086
- realForm[key] = value
1087
- } else {
1088
- realForm[realKey] = value
1089
- }
1090
- }
1091
- }
1092
- return realForm
1093
- },
1094
- // 默认提交事件
1095
- defaultSubmit (realForm, callback) {
1096
- // 新增移除id
1097
- if (this.businessType === '新增') {
1098
- delete realForm.id
1099
- }
1100
- // 组织请求
1101
- const requestParameters = {
1102
- queryParamsName: this.configName,
1103
- queryParams: this.configContent,
1104
- form: realForm,
1105
- businessType: this.businessType,
1106
- operator: this.currUser.name
1107
- }
1108
- addOrModify(requestParameters, this.serviceName, this.env === 'dev').then(data => {
1109
- this.$message.success(this.businessType + '成功!')
1110
- // commit
1111
- this.$emit('afterSubmit', { type: this.businessType, id: data.id, data: data, form: requestParameters.form })
1112
- this.loading = false
1113
- if (callback) {
1114
- callback()
1115
- }
1116
- }).catch(e => {
1117
- this.loading = false
1118
- this.$message.error(this.businessType + '失败:' + e)
1119
- })
1120
- },
1121
- // 获取表单字段实际值
1122
- getRealKey (key, mustHandleKey = false) {
1123
- if (key === 'selected_id') return key
1124
- if (this.isHandleFormKey || mustHandleKey) {
1125
- return key.substring(key.indexOf('_') + 1)
1126
- } else {
1127
- return key
1128
- }
1129
- },
1130
- /**
1131
- * 获取被修改记录数据
1132
- * @param modifyModelData 被修改记录的数据
1133
- */
1134
- getModifyModelData (modifyModelData) {
1135
- if (modifyModelData.primaryKeyData) {
1136
- this.form = Object.assign(this.form, modifyModelData.primaryKeyData)
1137
- }
1138
- // 对动态简易表单项特殊处理
1139
- for (const key in modifyModelData.data) {
1140
- const realKey = this.isHandleFormKey ? this.getRealKey(key) : key
1141
- if (this.simpleFormJsonData[realKey]) {
1142
- const extraForm = JSON.parse(modifyModelData.data[key])
1143
- for (const key in extraForm) {
1144
- const model = realKey + '@' + key
1145
- this.form[model] = extraForm[key]
1146
- }
1147
- }
1148
- }
1149
- // 对普通表单项处理
1150
- for (let i = 0; i < this.realJsonData.length; i++) {
1151
- if (['FilesId', 'Images'].includes(this.realJsonData[i])) {
1152
- // 附件需要跳过 因为会通过 modifyModelData中的files,images属性给upload赋值
1153
- // 新增修改表单每次提交时只会提交最新添加的文件
1154
- continue
1155
- }
1156
- const item = this.realJsonData[i]
1157
- // 地址选择器 需要传递 经纬度字段, 配置中添加 `${item.model}_lng_lat` CRUD 只需勾选 SQL生成查询项
1158
- if (['addressSearch'].includes(item.type)) {
1159
- this.form[item.model] = modifyModelData.data[item.model] + ''
1160
- this.form[`${item.model}_lng_lat`] = modifyModelData.data[`${item.model}_lng_lat`] + ''
1161
- continue
1162
- }
1163
- if (modifyModelData.data[item.model] || modifyModelData.data[item.model] === 0) {
1164
- if (modifyModelData.data[item.model] instanceof Array) {
1165
- this.form[item.model] = modifyModelData.data[item.model]
1166
- } else {
1167
- this.form[item.model] = modifyModelData.data[item.model] + ''
1168
- }
1169
- }
1170
- }
1171
- // 对分组表单进行处理
1172
- for (let i = 0; i < this.groupJsonData.length; i++) {
1173
- const item = this.groupJsonData[i]
1174
- try {
1175
- if (modifyModelData.data[item.model]) {
1176
- this.form[item.model] = JSON.parse(modifyModelData.data[item.model])
1177
- }
1178
- } catch (e) {
1179
- if (modifyModelData.data[item.model]) {
1180
- this.form[item.model] = modifyModelData.data[item.model]
1181
- }
1182
- }
1183
- }
1184
- // 追加版本号信息
1185
- for (const item of this.versionJsonData) {
1186
- if (!modifyModelData.data[item.model]) {
1187
- this.form[item.model] = 0
1188
- } else {
1189
- this.form[item.model] = modifyModelData.data[item.model] + ''
1190
- }
1191
- }
1192
- },
1193
- setForm (obj) {
1194
- this.form = Object.assign(this.form, obj)
1195
- // 给子表赋外键条件
1196
- if (this.childFormData.length > 0) {
1197
- for (const item of this.childFormData) {
1198
- const child = this.$refs[item.model]
1199
- // 获取子表别名,以便在条件上添加别名
1200
- const alias = child.realQueryConfig.tableAliasName
1201
- // 有主键,且主键有值,添加主键条件
1202
- if (this.primaryKey && this.form[this.primaryKey]) {
1203
- const foreignKey = item.foreignKey
1204
- const fixedQueryForm = { [alias + '_' + foreignKey]: this.form[this.primaryKey] }
1205
- if (!child.fixedQueryForm) {
1206
- child.fixedQueryForm = fixedQueryForm
1207
- } else {
1208
- Object.assign(child.fixedQueryForm, fixedQueryForm)
1209
- }
1210
- child.refreshTable()
1211
- }
1212
- }
1213
- }
1214
- },
1215
- setFormWithKey (obj) {
1216
- setDataByRealKey(this.form, obj)
1217
- },
1218
- setFormWithNoKey (obj) {
1219
- setDataByRealKey(this.form, obj)
1220
- },
1221
- emitFunc (func, data, value) {
1222
- this.$emit(func, data, value)
1223
- this.$emit('x-form-item-emit-func', func, data, value)
1224
- },
1225
- // 直接转发事件的函数
1226
- emitEvent (event, ...args) {
1227
- this.$emit(event, ...args)
1228
- },
1229
- close () {
1230
- this.loaded = false
1231
- },
1232
- /**
1233
- * 行选择事件
1234
- * @param row 选中行集合
1235
- * @param attr 表单项属性
1236
- */
1237
- async rowChoose (row, attr, callback) {
1238
- // 如果配置了自定义函数
1239
- if (attr.dataChangeFunc) {
1240
- await executeStrFunction(attr.dataChangeFunc, [this.form, this.setForm, {
1241
- ...attr,
1242
- selectRows: row
1243
- }, util, this.mode, runLogic, getConfigByNameAsync])
1244
- } else {
1245
- // 默认填充选中行数据到当前表单
1246
- setDataByRealKey(this.form, row[0])
1247
- }
1248
- if (callback) {
1249
- callback()
1250
- }
1251
- },
1252
- }
1253
- }
1254
- </script>
1255
-
1256
- <style scoped lang="less">
1257
- :deep(.ant-form-inline .ant-form-item ) {
1258
- display: block !important;
1259
- }
1260
-
1261
- :deep(.ant-form-item-with-help) {
1262
- margin-bottom: 0;
1263
- }
1264
-
1265
- .xFormGroupTitle {
1266
- font-weight: bold;
1267
- color: @primary-color;
1268
- }
1269
-
1270
- .simple-inline-item {
1271
- max-width: 100% !important;
1272
- }
1273
-
1274
- /* simple-inline模式样式 */
1275
- :deep(.simple-inline-item .ant-form-item) {
1276
- margin: 0 !important;
1277
- padding: 2px !important;
1278
-
1279
- .ant-form-item-label {
1280
- display: none !important;
1281
- }
1282
-
1283
- .ant-form-item-control-wrapper,
1284
- .ant-form-item-control {
1285
- width: 100% !important;
1286
- }
1287
- }
1288
- </style>
1
+ <template>
2
+ <div id="XAddNativeForm">
3
+ <a-form-model
4
+ v-if="loaded"
5
+ ref="selectForm"
6
+ :zIndex="1001"
7
+ :model="form"
8
+ v-bind="formItemLayoutGen"
9
+ :layout="layout">
10
+ <template v-for="(item, key) in childTableData">
11
+ <a-row
12
+ v-if="childTablePriority"
13
+ :gutter="16"
14
+ :key="'childTableRow' + key">
15
+ <a-card :title="item.name" :bordered="false" size="small">
16
+ <x-form-table
17
+ :key="'childTable_' + item.model"
18
+ :title="item.name"
19
+ :queryParamsName="item.childTableConfigName"
20
+ :localEditMode="true"
21
+ :fixed-query-form="childTableFixedQueryForm(item)"
22
+ :service-name="serviceName"
23
+ @innerXFormTableEmit="innerXFormTableEmit"
24
+ @afterTableInit="childTableMounted(item)"
25
+ :ref="'childXFormTable_' + item.model">
26
+ </x-form-table>
27
+ </a-card>
28
+ </a-row>
29
+ </template>
30
+ <template v-if="isSimpleInlineMode">
31
+ <a-row
32
+ v-for="(row, rowIndex) in simpleInlineRows"
33
+ :key="'simple-row-' + rowIndex"
34
+ :gutter="0"
35
+ type="flex">
36
+ <a-col
37
+ v-for="(item, itemIndex) in row.items"
38
+ :key="'simple-item-' + itemIndex"
39
+ :span="item.span">
40
+ <x-form-item
41
+ class="simple-inline-item"
42
+ :attr="item.formItem"
43
+ :disabled="itemDisabled(item.formItem)"
44
+ :read-only="readonly(item.formItem)"
45
+ :files="files"
46
+ :form="form"
47
+ :images="images"
48
+ :service-name="serviceName"
49
+ mode="新增/修改"
50
+ layout="simple-inline"
51
+ :rules="rules[`${item.formItem.name}${item.formItem.model}`]"
52
+ :get-data-params="getDataParams"
53
+ :env="env"
54
+ :enablePopupToBody="enablePopupToBody"
55
+ @x-form-item-emit-func="emitFunc"
56
+ @rowChoose="rowChoose"
57
+ :setForm="setForm"
58
+ :style="{ margin: 0, padding: '2px' }"
59
+ />
60
+ </a-col>
61
+ </a-row>
62
+ </template>
63
+ <a-row ref="GroupItemRow" v-if="!isSimpleInlineMode">
64
+ <a-col :span="3" v-if="!inXFormGroup && !(groups[0].groupName === DEFAULT_GROUP_NAME)">
65
+ <a-tabs tab-position="left" v-model="activeTab" @change="scrollToGroup">
66
+ <a-tab-pane
67
+ v-for="(groupsItem,groupsIndex) in groups"
68
+ :tab="groupsItem.groupName"
69
+ :key="groupsIndex">
70
+ </a-tab-pane>
71
+ </a-tabs>
72
+ </a-col>
73
+ <a-col
74
+ :span="(!inXFormGroup && !(groups[0].groupName === DEFAULT_GROUP_NAME)) ? 21: 24">
75
+ <a-row
76
+ :gutter="16"
77
+ type="flex"
78
+ :key="groupsIndex"
79
+ v-for="(groupsItem,groupsIndex) in groups"
80
+ >
81
+ <a-col
82
+ :span="24"
83
+ :style="{ marginTop: groupsIndex === 0 ? '' : '8px',fontSize:inXFormGroup?'15px':'14px', marginLeft:'-5px' }"
84
+ v-if="groupsItem.groupName !== DEFAULT_GROUP_NAME">
85
+ <span class="xFormGroupTitle" :ref="`group-title-${groupsIndex}`">{{ groupsItem.groupName }}</span>
86
+ </a-col>
87
+ <x-form-item
88
+ v-for="(item, index) in groupsItem.realJsonData"
89
+ :key="index"
90
+ :attr="item"
91
+ :disabled="itemDisabled(item)"
92
+ :read-only="readonly(item)"
93
+ :files="files"
94
+ v-bind="formItemLayoutGen"
95
+ :style="layout === 'inline' ? { marginTop:'5px' } : undefined"
96
+ :form="form"
97
+ :images="images"
98
+ :enablePopupToBody="enablePopupToBody"
99
+ :service-name="serviceName"
100
+ mode="新增/修改"
101
+ :layout="layout"
102
+ :rules="rules[`${item.name}${item.model}`]"
103
+ :get-data-params="getDataParams"
104
+ :env="env"
105
+ @x-form-item-emit-func="emitFunc"
106
+ @rowChoose="rowChoose"
107
+ :setForm="setForm"
108
+ />
109
+ </a-row>
110
+ </a-col>
111
+ </a-row>
112
+ <a-row :gutter="16" v-for="(groupItem, groupIndex) in groupJsonData" :key="groupIndex" v-if="!isSimpleInlineMode">
113
+ <a-card v-if="groupItem.groupItems.length > 0" :title="groupItem.name" :bordered="false" size="small">
114
+ <x-form-item
115
+ v-for="(item, index) in groupItem.groupItems"
116
+ :key="index"
117
+ :attr="item"
118
+ :disabled="itemDisabled(item)"
119
+ :readonly="readonly(item)"
120
+ :files="files"
121
+ v-bind="formItemLayoutGen"
122
+ :style="layout ==='inline'?{marginTop:'5px'}:undefined"
123
+ :form="form[groupItem.model]"
124
+ :images="images"
125
+ :service-name="serviceName"
126
+ mode="新增/修改"
127
+ :rules="rules[`${item.name}${item.model}`]"
128
+ :get-data-params="getDataParams"
129
+ :env="env"
130
+ :setForm="setForm"
131
+ @rowChoose="rowChoose"
132
+ />
133
+ </a-card>
134
+ <template v-else>
135
+ <slot
136
+ name="groupFormItems"
137
+ :form="form"
138
+ :model="groupItem.model"
139
+ :rules="rules"
140
+ :modifyModelData="modifyModelData"></slot>
141
+ </template>
142
+ </a-row>
143
+ <a-row :gutter="16" v-for="(item, key) in simpleFormJsonData" :key="'row' + key" v-if="!isSimpleInlineMode">
144
+ <a-card v-if="item.value.length > 0" :title="item.name" :bordered="false" size="small">
145
+ <x-form-item
146
+ v-for="(formItem, formItemIndex) in item.value"
147
+ :key="key + formItemIndex"
148
+ :attr="formItem"
149
+ :disabled="itemDisabled(formItem)"
150
+ :readonly="readonly(formItem)"
151
+ :files="files"
152
+ :enablePopupToBody="enablePopupToBody"
153
+ v-bind="formItemLayoutGen"
154
+ :style="layout ==='inline'?{marginTop:'5px'}:undefined"
155
+ :form="form[groupItem.model]"
156
+ :images="images"
157
+ :service-name="serviceName"
158
+ mode="新增/修改"
159
+ :rules="rules[`${item.name}${item.model}`]"
160
+ :get-data-params="getDataParams"
161
+ :env="env"
162
+ :setForm="setForm"
163
+ @rowChoose="rowChoose"
164
+ />
165
+ </a-card>
166
+ </a-row>
167
+ <template v-for="(item, key) in childTableData">
168
+ <a-row
169
+ v-if="!childTablePriority"
170
+ :gutter="16"
171
+ :key="'childTableRow' + key">
172
+ <a-card :title="item.name" :bordered="false" size="small">
173
+ <x-form-table
174
+ :key="'childTable_' + item.model"
175
+ :title="item.name"
176
+ :queryParamsName="item.childTableConfigName"
177
+ :localEditMode="true"
178
+ @innerXFormTableEmit="innerXFormTableEmit"
179
+ :fixed-query-form="childTableFixedQueryForm(item)"
180
+ :service-name="serviceName"
181
+ @afterTableInit="childTableMounted(item)"
182
+ :ref="'childXFormTable_' + item.model">
183
+ </x-form-table>
184
+ </a-card>
185
+ </a-row>
186
+ </template>
187
+ <a-row type="flex" :justify="btnPlace" :style="{paddingLeft: '16px',paddingRight: '16px'}">
188
+ <slot name="footer" :loading="loading">
189
+ <a-button v-if="showSubmitBtn" :loading="loading" type="primary" @click="onSubmit()">{{ btnName }}</a-button>
190
+ </slot>
191
+ </a-row>
192
+ </a-form-model>
193
+ </div>
194
+ </template>
195
+ <script>
196
+ import XFormItem from '@vue2-client/base-client/components/common/XForm/XFormItem'
197
+ import { formatDate, setDataByRealKey } from '@vue2-client/utils/util'
198
+ import * as util from '@vue2-client/utils/util'
199
+ import { mapState } from 'vuex'
200
+ import { addOrModify, getConfigByName, getConfigByNameAsync, runLogic } from '@vue2-client/services/api/common'
201
+ import { checkIdNumber, REG_EMAIL, REG_LANDLINE, REG_PHONE } from '@vue2-client/utils/reg'
202
+ import moment from 'moment/moment'
203
+ import { executeStrFunction, executeStrFunctionByContext } from '@vue2-client/utils/runEvalFunction'
204
+ import formValidationMixin from '@vue2-client/mixins/formValidationMixin'
205
+
206
+ const DEFAULT_GROUP_NAME = '__default__'
207
+ export default {
208
+ name: 'XAddNativeForm',
209
+ components: {
210
+ XFormItem,
211
+ XFormTable: () => import('@vue2-client/base-client/components/common/XFormTable/XFormTable.vue')
212
+ },
213
+ inject: {
214
+ inXFormGroup: {
215
+ default: false
216
+ },
217
+ formGroupContext: {
218
+ default: null
219
+ },
220
+ formDataChange: {
221
+ default: null
222
+ }
223
+ },
224
+ props: {
225
+ // 是否启用 horizontal 模式的自定义配置
226
+ enableHorizontalCustom: {
227
+ type: Boolean,
228
+ default: false
229
+ },
230
+ // 是否启用时间弹出到最外层
231
+ enablePopupToBody: {
232
+ type: Boolean,
233
+ default: false
234
+ }
235
+ },
236
+ data () {
237
+ return {
238
+ DEFAULT_GROUP_NAME,
239
+ // 预览模式
240
+ viewMode: false,
241
+ // 是否处理表单Key值
242
+ isHandleFormKey: true,
243
+ // 内容加载是否完成
244
+ loaded: false,
245
+ // 业务类型
246
+ businessType: '',
247
+ // 业务标题
248
+ title: '',
249
+ // 新增或修改业务是否执行中
250
+ loading: false,
251
+ // 表单Model
252
+ form: {},
253
+ // 配置名称
254
+ configName: undefined,
255
+ // 配置内容,用于查询配置生成器的预览
256
+ configContent: undefined,
257
+ // 表单项集合
258
+ formItems: [],
259
+ // 服务名称
260
+ serviceName: undefined,
261
+ // 是否显示提交按钮
262
+ showSubmitBtn: true,
263
+ // 修改有文件的表单时使用
264
+ files: [],
265
+ images: [],
266
+ // 校验
267
+ rules: {},
268
+ // 调用logic获取数据源的追加参数
269
+ getDataParams: {},
270
+ // 动态简易表单集合
271
+ simpleFormJsonData: {},
272
+ // 待修改的数据集
273
+ modifyModelData: {},
274
+ // 当前环境
275
+ env: 'prod',
276
+ // 表单主键
277
+ primaryKey: null,
278
+ // 表单模式 horizontal | vertical | inline
279
+ layout: 'horizontal',
280
+ // 提交按钮名称
281
+ btnName: '提交',
282
+ // 提交按钮位置 start / center / end
283
+ btnPlace: 'center',
284
+ // 子表是否排在前面
285
+ childTablePriority: false,
286
+ // simple-inline布局配置
287
+ simpleInline: null
288
+ }
289
+ },
290
+ computed: {
291
+ // 过滤出用于新增/修改场景的表单项
292
+ realJsonData: function () {
293
+ return this.formItems.filter((item) => {
294
+ return item.addOrEdit && item.addOrEdit !== 'no' && item.addOrEdit !== 'silenceAdd' && item.addOrEdit !== 'version' && !this.itemDisabled(item)
295
+ })
296
+ },
297
+ // 表单项组 / 不是 数据组
298
+ groups: function () {
299
+ if (!this.realJsonData || this.realJsonData.length === 0) {
300
+ return [{
301
+ groupName: DEFAULT_GROUP_NAME,
302
+ realJsonData: this.realJsonData,
303
+ xAddFormLayout: 'horizontal'
304
+ }]
305
+ }
306
+ const uniqueGroups = new Set(this.realJsonData.map(item => item.group).filter(Boolean))
307
+ const allGroup = Array.from(uniqueGroups).map(group => {
308
+ return {
309
+ groupName: group,
310
+ realJsonData: this.realJsonData.filter(item => item.group === group),
311
+ xAddFormLayout: 'horizontal'
312
+ }
313
+ })
314
+ // 判断每一组得formJson 长度相加是否等于 realJsonData 长度 避免错误数据
315
+ if (allGroup.reduce((total, item) => total + item.realJsonData.length, 0) === this.realJsonData.length) {
316
+ return allGroup
317
+ } else {
318
+ return [{
319
+ groupName: DEFAULT_GROUP_NAME,
320
+ realJsonData: this.realJsonData,
321
+ xAddFormLayout: 'horizontal'
322
+ }]
323
+ }
324
+ },
325
+ // 拥有自定义校验函数得表单项
326
+ customValidateItems: function () {
327
+ return this.formItems.filter((item) => {
328
+ return item?.rule?.type === 'customJs'
329
+ })
330
+ },
331
+ // 过滤出用于新增/修改场景的表单项
332
+ groupJsonData: function () {
333
+ return this.formItems.filter((item) => {
334
+ return item.type === 'group'
335
+ }).map((item) => {
336
+ item.groupItems = item.groupItems.filter((item) => {
337
+ return item.addOrEdit && item.addOrEdit !== 'no' && item.addOrEdit !== 'silenceAdd' && item.addOrEdit !== 'version' && !this.itemDisabled(item)
338
+ }).map((groupItem) => {
339
+ // 只保留第一个下划线后面的内容
340
+ // 多层校验规则需要将prop设置为 key1.key2.....
341
+ groupItem.prop = `${item.model}.${groupItem.model.substring(groupItem.model.indexOf('_') + 1)}`
342
+ groupItem.model = groupItem.model.substring(groupItem.model.indexOf('_') + 1)
343
+ return groupItem
344
+ })
345
+ return item
346
+ }
347
+ )
348
+ },
349
+ // 过滤出用于子表数据新增/修改场景的表单项
350
+ childTableData: function () {
351
+ return this.formItems.filter((item) => {
352
+ return item.type === 'childTable'
353
+ })
354
+ },
355
+ // 过滤出用于form子表数据新增/修改场景的表单项
356
+ childFormData: function () {
357
+ return this.formItems.filter((item) => {
358
+ return item.type === 'rowEdit'
359
+ })
360
+ },
361
+ // 过滤出用于静默新增场景的表单项
362
+ silenceAddJsonData: function () {
363
+ return this.formItems.filter(function (item) {
364
+ return item.addOrEdit === 'silenceAdd'
365
+ })
366
+ },
367
+ // 过滤出版本号表单项
368
+ versionJsonData: function () {
369
+ return this.formItems.filter(function (item) {
370
+ return item.addOrEdit === 'version'
371
+ })
372
+ },
373
+ formItemLayoutGen () {
374
+ if (this.layout === 'simple-inline') {
375
+ return {
376
+ labelCol: { span: 0 },
377
+ wrapperCol: { span: 24 }
378
+ }
379
+ }
380
+ if (this.layout === 'horizontal') {
381
+ // 如果启用了自定义配置,从 formItemLayout 读取(支持 0 值)
382
+ if (this.enableHorizontalCustom && this.formItemLayout) {
383
+ return {
384
+ labelCol: {
385
+ span: (this.formItemLayout.labelCol ?? 4),
386
+ offset: (this.formItemLayout.offset ?? 2)
387
+ },
388
+ wrapperCol: { span: (this.formItemLayout.wrapperCol ?? 14) },
389
+ }
390
+ }
391
+ // 默认配置
392
+ return {
393
+ labelCol: { span: 4, offset: 2 },
394
+ wrapperCol: { span: 14 },
395
+ }
396
+ } else if (this.layout === 'vertical') {
397
+ return {}
398
+ } else {
399
+ if (!this.formItemLayout.labelCol || !this.formItemLayout.wrapperCol) {
400
+ return {
401
+ labelCol: { span: 8 },
402
+ wrapperCol: { span: 16 },
403
+ }
404
+ }
405
+ return {
406
+ labelCol: { span: this.formItemLayout.labelCol },
407
+ wrapperCol: { span: this.formItemLayout.wrapperCol },
408
+ }
409
+ }
410
+ },
411
+ // simple-inline模式判断
412
+ isSimpleInlineMode () {
413
+ return this.layout === 'simple-inline' && this.simpleInline
414
+ },
415
+ // simple-inline布局行数据
416
+ simpleInlineRows () {
417
+ if (!this.isSimpleInlineMode) return []
418
+ return this.simpleInline.rows.map(row => ({
419
+ ...row,
420
+ items: row.items.map(item => ({
421
+ ...item,
422
+ formItem: this.realJsonData.find(f =>
423
+ f.model === item.key && f.name === item.title
424
+ )
425
+ })).filter(item => item.formItem)
426
+ }))
427
+ },
428
+ ...mapState('account', { currUser: 'user' })
429
+ },
430
+ provide () {
431
+ return {
432
+ getComponentByName: this.getComponentByName,
433
+ registerComponent: this.registerComponent,
434
+ XFormContext: this,
435
+ // 移除必填项
436
+ removeRequired: this.removeRequired,
437
+ // 设置必填项
438
+ setRequired: this.setRequired,
439
+ getSelf: () => this,
440
+ }
441
+ },
442
+ watch: {
443
+ form: {
444
+ handler (val) {
445
+ if (this.formDataChange && typeof this.formDataChange === 'function') {
446
+ this.formDataChange(val)
447
+ }
448
+ },
449
+ deep: true
450
+ }
451
+ },
452
+ /** //todo 本来想要实现 配置 自定义函数时,表单项得红星提示,根据自定义校验函数得返回值来判断
453
+ * 但是监听不到父组件formgorup得其他form得变化,所以暂时不实现
454
+ */
455
+ //
456
+ // watch: {
457
+ // form: {
458
+ // handler (val) {
459
+ // // 遍历表单配置
460
+ // if (this.customValidateItems.length > 0) {
461
+ // for (const item of this.customValidateItems) {
462
+ // const itemIndex = this.formItems.findIndex(formItem => formItem.model === item.model)
463
+ // if (itemIndex < 0) {
464
+ // continue
465
+ // }
466
+ // try {
467
+ // this.customJsValidate(null, val[item.model], (res) => {
468
+ // // 如果返回error则设置错误信息
469
+ // if (res instanceof Error) {
470
+ // // 设置表单项的错误状态
471
+ // this.$set(this.formItems[itemIndex], 'tempRequired', true)
472
+ // } else {
473
+ // // 清除错误状态
474
+ // this.$set(this.formItems[itemIndex], 'tempRequired', true)
475
+ // }
476
+ // }, item)
477
+ // } catch (e) {
478
+ // console.error(e)
479
+ // this.$set(this.formItems[itemIndex], 'tempRequired', true)
480
+ // }
481
+ // }
482
+ // console.log('customValidateItems', JSON.stringify(this.customValidateItems))
483
+ // }
484
+ // },
485
+ // deep: true
486
+ // }
487
+ // },
488
+ mixins: [formValidationMixin],
489
+ methods: {
490
+ runLogic,
491
+ getConfigByNameAsync,
492
+ getConfigByName,
493
+ init (params) {
494
+ console.warn('XaddNativeForm init', params)
495
+ const {
496
+ configName,
497
+ configContent,
498
+ formItems,
499
+ formJson,
500
+ viewMode,
501
+ isHandleFormKey,
502
+ isKeyHandle = true,
503
+ showSubmitBtn = true,
504
+ serviceName,
505
+ primaryKey,
506
+ modifyModelData = {},
507
+ businessType,
508
+ title,
509
+ fixedAddForm = {},
510
+ getDataParams = {},
511
+ simpleFormJsonData = {},
512
+ env = 'prod',
513
+ layout,
514
+ xAddFormLayout = 'horizontal',
515
+ formItemLayout = {},
516
+ btnName = '提交',
517
+ childTablePriority = false,
518
+ btnPlace = 'center',
519
+ simpleInline = null,
520
+ paramLogicName,
521
+ paramLogicNameParam
522
+ } = params
523
+ this.loaded = false
524
+ // 兼容需要省略 传递 layout: res.xAddFormLayout 可以使用 ...res 展开运算符 直接转递
525
+ if (xAddFormLayout && layout === undefined) {
526
+ this.layout = xAddFormLayout
527
+ } else {
528
+ this.layout = layout
529
+ }
530
+ this.formItemLayout = formItemLayout
531
+ if ((isHandleFormKey === null || isHandleFormKey === undefined) && !isKeyHandle) {
532
+ this.isHandleFormKey = isKeyHandle
533
+ } else if (isHandleFormKey) {
534
+ this.isHandleFormKey = isHandleFormKey
535
+ } else {
536
+ this.isHandleFormKey = isKeyHandle
537
+ }
538
+ this.childTablePriority = childTablePriority
539
+ this.configName = configName
540
+ this.configContent = configContent
541
+ this.formItems = this.getFromItem(formItems, formJson)
542
+ this.viewMode = viewMode
543
+ this.showSubmitBtn = showSubmitBtn
544
+ this.primaryKey = primaryKey
545
+ this.serviceName = serviceName
546
+ this.businessType = businessType
547
+ this.title = title
548
+ this.getDataParams = getDataParams
549
+ this.simpleFormJsonData = simpleFormJsonData
550
+ this.env = env
551
+ this.btnName = btnName
552
+ this.btnPlace = btnPlace
553
+ this.simpleInline = simpleInline
554
+ // 如果 fixedAddFormselected_id 值,并且设置了处理表单key值,则多给 selected_id 加前缀 避免处理错误
555
+ if (fixedAddForm.selected_id && this.isHandleFormKey) {
556
+ fixedAddForm._selected_id = fixedAddForm.selected_id
557
+ delete fixedAddForm.selected_id
558
+ }
559
+ // 设置普通表单项的相关参数
560
+ const formData = Object.assign({}, fixedAddForm)
561
+ if (paramLogicName) {
562
+ runLogic(paramLogicName, paramLogicNameParam, this.serviceName).then(res => {
563
+ Object.assign(formData, res)
564
+ })
565
+ }
566
+ for (let i = 0; i < this.realJsonData.length; i++) {
567
+ const item = this.realJsonData[i]
568
+ this.setFormProps(formData, item, null)
569
+ }
570
+ // 设置表单分组项目相关参数
571
+ for (let i = 0; i < this.groupJsonData.length; i++) {
572
+ const groupItem = this.groupJsonData[i]
573
+ formData[groupItem.model] = {}
574
+ for (let j = 0; j < groupItem.groupItems.length; j++) {
575
+ const item = groupItem.groupItems[j]
576
+ this.setFormProps(formData[groupItem.model], item, item.prop)
577
+ }
578
+ }
579
+ // 设置动态简易表单项的相关参数
580
+ for (const key in this.simpleFormJsonData) {
581
+ for (const item of this.simpleFormJsonData[key].value) {
582
+ item.model = key + '@' + item.model
583
+ this.setFormProps(formData, item, null)
584
+ }
585
+ }
586
+
587
+ this.form = formData
588
+ // 修改场景下对表单项赋值
589
+ if (modifyModelData && modifyModelData.data) {
590
+ this.modifyModelData = modifyModelData
591
+ if (Object.keys(modifyModelData.data).length > 0) {
592
+ this.getModifyModelData(modifyModelData)
593
+ }
594
+ }
595
+ // 处理表单得附件
596
+ if (modifyModelData && modifyModelData.files) {
597
+ this.files = modifyModelData.files
598
+ }
599
+ if (modifyModelData && modifyModelData.images) {
600
+ this.images = modifyModelData.images
601
+ }
602
+ this.loaded = true
603
+ },
604
+ scrollToGroup (index) {
605
+ const groupElement = this.$refs[`group-title-${index}`][0]
606
+ if (groupElement) {
607
+ groupElement.scrollIntoView({ behavior: 'smooth' })
608
+ }
609
+ },
610
+ registerComponent (componentName, component) {
611
+ console.log('内部注册', this.$options.name, componentName)
612
+ this.$refs[componentName] = component
613
+ console.log('内部注册完成', this.$refs)
614
+ },
615
+ // 根据名字从注册到组件中获取组件
616
+ getComponentByName (componentName) {
617
+ console.log('内部取组件', this.$options.name, componentName)
618
+ console.log('内部组件内容', this.$refs)
619
+ return this.$refs[componentName]
620
+ },
621
+ // 兼容需要省略 传递 [formItems: res.formJson ] 可以使用 ...res 展开运算符 直接转递
622
+ getFromItem (formItems, formJson) {
623
+ const _formItems = formItems || formJson
624
+ if (typeof formItems === 'string') {
625
+ return JSON.parse(_formItems)
626
+ } else {
627
+ return JSON.parse(JSON.stringify(_formItems))
628
+ }
629
+ },
630
+ innerXFormTableEmit (fun, record, id, actionType, index) {
631
+ this.$emit(fun, record, id, actionType, index)
632
+ },
633
+ // 时间组件赋默认值
634
+ // .type, item.formDefault
635
+ getDateRange ({ type, formDefault: defaultValue, formValueFormat }) {
636
+ // const format = type === 'datePicker' ? 'YYYY-MM-DD' : 'YYYY-MM-DD HH:mm:ss'
637
+ let format = 'YYYY-MM-DD HH:mm:ss'
638
+ if (formValueFormat) {
639
+ format = formValueFormat
640
+ }
641
+ let start
642
+ switch (defaultValue) {
643
+ case 'curYear':
644
+ start = moment().startOf('year').format(format)
645
+ break
646
+ case 'curMonth':
647
+ start = moment().startOf('month').format(format)
648
+ break
649
+ case 'curDay':
650
+ start = moment().startOf('day').format(format)
651
+ break
652
+ case 'curTime':
653
+ start = moment().format(format)
654
+ break
655
+ default:
656
+ return defaultValue
657
+ }
658
+ return start
659
+ },
660
+ setFormProps (formData, item, groupItem) {
661
+ const rulesKey = `${item.name}${item.model}`
662
+ if (formData[item.model] === undefined || formData[item.model] === null) {
663
+ formData[item.model] = undefined
664
+ }
665
+ if (!formData[item.model] && item.formDefault) {
666
+ if (['datePicker', 'rangePicker', 'yearPicker', 'monthPicker', 'yearRangePicker', 'monthRangePicker'].includes(item.type)) {
667
+ formData[item.model] = this.getDateRange(item)
668
+ } else if (['treeSelect', 'select', 'checkbox'].includes(item.type) && ['curOrgId', 'curDepId', 'curUserId'].includes(item.formDefault)) {
669
+ if (item.formDefault === 'curOrgId') {
670
+ formData[item.model] = item.type === 'select' ? this.currUser.orgid : [this.currUser.orgid]
671
+ }
672
+ if (item.formDefault === 'curDepId') {
673
+ formData[item.model] = item.type === 'select' ? this.currUser.depids : [this.currUser.depids]
674
+ }
675
+ if (item.formDefault === 'curUserId') {
676
+ formData[item.model] = item.type === 'select' ? this.currUser.id : [this.currUser.id]
677
+ }
678
+ } else if (['addressSearch'].includes(item.type)) {
679
+ formData[item.model] = item.formDefault
680
+ formData[`${item.model}_lng_lat`] = item.formDefault_lng_lat
681
+ } else {
682
+ formData[item.model] = item.formDefault
683
+ }
684
+ }
685
+ // 处理表单校验情况
686
+ if (item.rule) {
687
+ if (groupItem) {
688
+ this.rules[groupItem] = []
689
+ } else {
690
+ this.rules[rulesKey] = []
691
+ }
692
+ const required = item.rule.required ? item.rule.required === true || item.rule.required === 'true' : false
693
+ let trigger
694
+ let message
695
+ if (required) {
696
+ switch (item.type) {
697
+ case 'select':
698
+ case 'checkbox':
699
+ case 'radio':
700
+ case 'treeSelect':
701
+ case 'rangePicker':
702
+ case 'monthPicker':
703
+ case 'yearPicker':
704
+ case 'datePicker':
705
+ case 'file':
706
+ case 'image':
707
+ case 'citySelect':
708
+ case 'addressSearch':
709
+ case 'personSetting':
710
+ message = '请选择' + item.name
711
+ trigger = 'change'
712
+ break
713
+ default:
714
+ message = '请输入' + item.name
715
+ trigger = 'blur'
716
+ }
717
+ if (groupItem) {
718
+ this.rules[groupItem].push({
719
+ required: true,
720
+ message: message,
721
+ trigger: trigger
722
+ })
723
+ } else {
724
+ this.rules[rulesKey].push({
725
+ required: true,
726
+ message: message,
727
+ trigger: trigger
728
+ })
729
+ }
730
+ }
731
+
732
+ switch (item.rule.type) {
733
+ case 'number':
734
+ case 'integer':
735
+ case 'float':
736
+ // eslint-disable-next-line no-case-declarations
737
+ let defaultValue
738
+ // eslint-disable-next-line no-case-declarations
739
+ let message
740
+ switch (item.rule.type) {
741
+ case 'number':
742
+ item.numberInput = true
743
+ message = '数字'
744
+ defaultValue = 0
745
+ break
746
+ case 'integer':
747
+ item.numberInput = true
748
+ message = '整数'
749
+ defaultValue = 0
750
+ break
751
+ case 'float':
752
+ item.numberInput = true
753
+ message = '小数'
754
+ defaultValue = 0.0
755
+ break
756
+ }
757
+ if (groupItem) {
758
+ this.rules[groupItem].push({
759
+ type: item.rule.type,
760
+ message: item.name + '必须为' + message,
761
+ transform: (value) => {
762
+ if (value && value.length !== 0) {
763
+ return Number(value)
764
+ } else {
765
+ return defaultValue
766
+ }
767
+ },
768
+ trigger: 'blur'
769
+ })
770
+ } else {
771
+ this.rules[rulesKey].push({
772
+ type: item.rule.type,
773
+ message: item.name + '必须为' + message,
774
+ transform: (value) => {
775
+ if (value && value.length !== 0) {
776
+ return Number(value)
777
+ } else {
778
+ return defaultValue
779
+ }
780
+ },
781
+ trigger: 'blur'
782
+ })
783
+ }
784
+ break
785
+ case 'email': {
786
+ const validator = (rule, value, callback) => {
787
+ if (value && !REG_EMAIL.test(value)) {
788
+ callback(new Error('请输入正确的邮箱地址'))
789
+ } else {
790
+ callback()
791
+ }
792
+ }
793
+ this.rules[groupItem || rulesKey].push({
794
+ type: 'email',
795
+ validator: validator,
796
+ message: '请输入正确的邮箱地址',
797
+ trigger: 'blur'
798
+ })
799
+ break
800
+ }
801
+ case 'userPhone': {
802
+ this.rules[groupItem || rulesKey].push({
803
+ type: 'userPhone',
804
+ validator: (rule, value, callback) => {
805
+ if (value && !REG_PHONE.test(value)) {
806
+ callback(new Error('请输入正确的手机号码'))
807
+ } else {
808
+ callback()
809
+ }
810
+ },
811
+ message: '请输入正确的手机号码',
812
+ trigger: 'blur'
813
+ })
814
+ break
815
+ }
816
+ case 'idNumber': {
817
+ this.rules[groupItem || rulesKey].push({
818
+ validator: (rule, value, callback) => {
819
+ if (value && !checkIdNumber(value)) {
820
+ callback(new Error('请输入正确的身份证号码'))
821
+ } else {
822
+ callback()
823
+ }
824
+ },
825
+ trigger: 'blur'
826
+ })
827
+ break
828
+ }
829
+ case 'landlineNumber': {
830
+ this.rules[rulesKey].push({
831
+ validator: (rule, value, callback) => {
832
+ if (value && !REG_LANDLINE.test(value)) {
833
+ callback(new Error('请输入正确的座机号码'))
834
+ } else {
835
+ callback()
836
+ }
837
+ },
838
+ trigger: 'blur'
839
+ })
840
+ break
841
+ }
842
+ // 大于0
843
+ case 'greaterThanZero': {
844
+ item.numberInput = true
845
+ this.rules[rulesKey].push({
846
+ validator: (rule, value, callback) => {
847
+ if (isNaN(value) || value <= 0) {
848
+ callback(new Error('请输入一个大于0的数字'))
849
+ } else {
850
+ callback()
851
+ }
852
+ },
853
+ trigger: 'blur'
854
+ })
855
+ break
856
+ }
857
+ // 大于等于0
858
+ case 'greaterThanOrEqualZero': {
859
+ item.numberInput = true
860
+ this.rules[rulesKey].push({
861
+ validator: (rule, value, callback) => {
862
+ if (isNaN(value) || value < 0) {
863
+ callback(new Error('请输入一个大于等于0的数字'))
864
+ } else {
865
+ callback()
866
+ }
867
+ },
868
+ trigger: 'blur'
869
+ })
870
+ break
871
+ }
872
+ case 'stringLength': {
873
+ this.rules[rulesKey].push({
874
+ validator: (rule, value, callback) => {
875
+ if (value && value.length < item.rule.minLen) {
876
+ callback(new Error('长度不能少于' + item.rule.minLen + '个字符'))
877
+ } else if (value && value.length > item.rule.maxLen) {
878
+ callback(new Error('长度不能超过' + item.rule.maxLen + '个字符'))
879
+ } else {
880
+ callback()
881
+ }
882
+ },
883
+ trigger: 'blur'
884
+ })
885
+ break
886
+ }
887
+ case 'customJs': {
888
+ this.rules[rulesKey].push({
889
+ validator: (rule, value, callback) => {
890
+ this.customJsValidate(rule, value, callback, item)
891
+ },
892
+ trigger: 'blur'
893
+ })
894
+ break
895
+ }
896
+ }
897
+ }
898
+ },
899
+ childTableMounted (item) {
900
+ // 子表初始化时,设置表格数据
901
+ if (this.form[item.model] && this.form[item.model].length > 0) {
902
+ this.$refs[`childXFormTable_${item.model}`][0].setTableData(this.form[item.model])
903
+ }
904
+ },
905
+ customJsValidate (rule, value, callback, item) {
906
+ if (item.rule.customValidatorFunc) {
907
+ executeStrFunctionByContext(this, item.rule.customValidatorFunc, [rule, value, callback, this.form, item, this.util, runLogic, getConfigByNameAsync])
908
+ } else {
909
+ callback()
910
+ }
911
+ },
912
+ itemDisabled (value) {
913
+ return (this.businessType === '新增' && value.addOrEdit === 'edit') ||
914
+ (this.businessType === '修改' && value.addOrEdit === 'add')
915
+ },
916
+ readonly (value) {
917
+ return value.addOrEdit === 'readonly'
918
+ },
919
+ async onSubmit () {
920
+ const valid = await this.validateForm()
921
+ if (!valid) return false
922
+ if (this.viewMode) {
923
+ this.$message.info('预览模式禁止新增和修改')
924
+ return false
925
+ }
926
+ this.loading = true
927
+ const requestForm = this.prepareForm()
928
+ await this.appendSilenceAddFields(requestForm)
929
+ const realForm = this.handleFormKeys(requestForm)
930
+ debugger
931
+ // 增加子表数据
932
+ if (this.childTableData.length > 0) {
933
+ for (const item of this.childTableData) {
934
+ const childModel = item.model
935
+ const childDataRef = this.$refs['childXFormTable_' + item.model][0].getTableData()
936
+ const childData = []
937
+ for (const item of childDataRef) {
938
+ childData.push(JSON.parse(JSON.stringify(item)))
939
+ }
940
+ for (let i = 0; i < childData.length; i++) {
941
+ childData[i] = this.handleFormKeys(childData[i])
942
+ // 外键不需要带表别名,所以此处放到表单处理后赋值
943
+ if (realForm.id) {
944
+ childData[i][item.childTableForeignKeyName] = realForm.id
945
+ }
946
+ }
947
+ realForm[childModel] = childData
948
+ }
949
+ }
950
+ // 增加form子表数据
951
+ if (this.childFormData.length > 0) {
952
+ for (const item of this.childFormData) {
953
+ const childModel = item.model
954
+ const childData = this.$refs[item.model].getTableData()
955
+ for (let i = 0; i < childData.length; i++) {
956
+ childData[i] = this.handleFormKeys(childData[i], true)
957
+ // 外键不需要带表别名,所以此处放到表单处理后赋值
958
+ if (realForm.id) {
959
+ childData[i][item.foreignKey] = realForm.id
960
+ }
961
+ }
962
+ realForm[childModel] = childData
963
+ }
964
+ }
965
+ if (this.$listeners.onSubmit) {
966
+ // 交由父级处理
967
+ this.$emit('onSubmit', {
968
+ businessType: this.businessType,
969
+ serviceName: this.serviceName,
970
+ realForm: realForm,
971
+ currUserName: this.currUser.name,
972
+ currUserId: this.currUser.id,
973
+ orgId: this.currUser.orgid
974
+ })
975
+ } else {
976
+ this.defaultSubmit(realForm)
977
+ }
978
+ },
979
+
980
+ async asyncSubmit () {
981
+ return new Promise((resolve, reject) => {
982
+ this.$refs.selectForm.validate(async valid => {
983
+ if (!valid) {
984
+ reject(new Error('Form validation failed'))
985
+ return
986
+ }
987
+ this.loading = true
988
+ const requestForm = this.prepareForm()
989
+ await this.appendSilenceAddFields(requestForm)
990
+ const realForm = this.handleFormKeys(requestForm)
991
+ resolve({
992
+ realForm,
993
+ businessType: this.businessType,
994
+ serviceName: this.serviceName,
995
+ currUserName: this.currUser.name,
996
+ currUserId: this.currUser.id,
997
+ orgId: this.currUser.orgid
998
+ })
999
+ })
1000
+ })
1001
+ },
1002
+
1003
+ validateForm () {
1004
+ return new Promise((resolve) => {
1005
+ this.$refs.selectForm.validate(valid => resolve(valid))
1006
+ })
1007
+ },
1008
+
1009
+ childTableFixedQueryForm (item) {
1010
+ if (this.modifyModelData?.primaryKeyData) {
1011
+ const fixedForm = {}
1012
+ fixedForm[item.childTableForeignKeyName] = Object.values(this.modifyModelData.primaryKeyData)[0]
1013
+ return fixedForm
1014
+ }
1015
+ return null
1016
+ },
1017
+
1018
+ prepareForm () {
1019
+ const form = { ...this.form }
1020
+ for (const key of Object.keys(form)) {
1021
+ const value = form[key]
1022
+ if (value === null || (typeof value === 'object' && Object.keys(value).length === 0)) {
1023
+ form[key] = undefined
1024
+ } else if (typeof value === 'object' && Object.keys(value).length === 1) {
1025
+ form[key] = value[0]
1026
+ }
1027
+ }
1028
+ return form
1029
+ },
1030
+
1031
+ async appendSilenceAddFields (form) {
1032
+ if (this.businessType === '新增') {
1033
+ for (const item of this.silenceAddJsonData) {
1034
+ switch (item.silencePurpose) {
1035
+ case 'createTime':
1036
+ form[item.model] = formatDate('now')
1037
+ break
1038
+ case 'operator':
1039
+ form[item.model] = this.currUser.name
1040
+ break
1041
+ case 'operatorId':
1042
+ form[item.model] = this.currUser.id
1043
+ break
1044
+ case 'orgId':
1045
+ form[item.model] = this.currUser.orgid
1046
+ break
1047
+ case 'orgName':
1048
+ form[item.model] = this.currUser.orgs
1049
+ break
1050
+ case 'depId':
1051
+ form[item.model] = this.currUser.depids
1052
+ break
1053
+ case 'depName':
1054
+ form[item.model] = this.currUser.deps
1055
+ break
1056
+ }
1057
+ }
1058
+ for (const item of this.silenceAddJsonData.filter((item) => item.silencePurpose === 'customize')) {
1059
+ const result = await runLogic(item.silenceSource, form, this.serviceName)
1060
+ if (result) {
1061
+ const keys = Object.keys(result)
1062
+ if (keys.length === 1 && keys[0] === 'value') {
1063
+ form[item.model] = result.value
1064
+ } else {
1065
+ form[item.model] = result
1066
+ }
1067
+ } else {
1068
+ form[item.model] = result
1069
+ }
1070
+ }
1071
+ }
1072
+ },
1073
+
1074
+ handleFormKeys (form, mustHandleKey = false) {
1075
+ const realForm = {}
1076
+ for (const key of Object.keys(form)) {
1077
+ const value = form[key]
1078
+ const extraFormKeyTagIndex = key.indexOf('@')
1079
+ if (extraFormKeyTagIndex !== -1) {
1080
+ const extraFormKey = key.substring(0, extraFormKeyTagIndex)
1081
+ const realKey = key.substring(extraFormKeyTagIndex + 1)
1082
+ if (!realForm[extraFormKey]) {
1083
+ realForm[extraFormKey] = {}
1084
+ }
1085
+ realForm[extraFormKey][realKey] = value
1086
+ } else {
1087
+ const realKey = this.isHandleFormKey || mustHandleKey ? this.getRealKey(key, mustHandleKey) : key
1088
+ // 如果发生重名,不覆盖,把key的别名带上
1089
+ if (realForm[realKey]) {
1090
+ realForm[key] = value
1091
+ } else {
1092
+ realForm[realKey] = value
1093
+ }
1094
+ }
1095
+ }
1096
+ return realForm
1097
+ },
1098
+ // 默认提交事件
1099
+ defaultSubmit (realForm, callback) {
1100
+ // 新增移除id
1101
+ if (this.businessType === '新增') {
1102
+ delete realForm.id
1103
+ }
1104
+ // 组织请求
1105
+ const requestParameters = {
1106
+ queryParamsName: this.configName,
1107
+ queryParams: this.configContent,
1108
+ form: realForm,
1109
+ businessType: this.businessType,
1110
+ operator: this.currUser.name
1111
+ }
1112
+ addOrModify(requestParameters, this.serviceName, this.env === 'dev').then(data => {
1113
+ this.$message.success(this.businessType + '成功!')
1114
+ // commit
1115
+ this.$emit('afterSubmit', { type: this.businessType, id: data.id, data: data, form: requestParameters.form })
1116
+ this.loading = false
1117
+ if (callback) {
1118
+ callback()
1119
+ }
1120
+ }).catch(e => {
1121
+ this.loading = false
1122
+ this.$message.error(this.businessType + '失败:' + e)
1123
+ })
1124
+ },
1125
+ // 获取表单字段实际值
1126
+ getRealKey (key, mustHandleKey = false) {
1127
+ if (key === 'selected_id') return key
1128
+ if (this.isHandleFormKey || mustHandleKey) {
1129
+ return key.substring(key.indexOf('_') + 1)
1130
+ } else {
1131
+ return key
1132
+ }
1133
+ },
1134
+ /**
1135
+ * 获取被修改记录数据
1136
+ * @param modifyModelData 被修改记录的数据
1137
+ */
1138
+ getModifyModelData (modifyModelData) {
1139
+ if (modifyModelData.primaryKeyData) {
1140
+ this.form = Object.assign(this.form, modifyModelData.primaryKeyData)
1141
+ }
1142
+ // 对动态简易表单项特殊处理
1143
+ for (const key in modifyModelData.data) {
1144
+ const realKey = this.isHandleFormKey ? this.getRealKey(key) : key
1145
+ if (this.simpleFormJsonData[realKey]) {
1146
+ const extraForm = JSON.parse(modifyModelData.data[key])
1147
+ for (const key in extraForm) {
1148
+ const model = realKey + '@' + key
1149
+ this.form[model] = extraForm[key]
1150
+ }
1151
+ }
1152
+ }
1153
+ // 对普通表单项处理
1154
+ for (let i = 0; i < this.realJsonData.length; i++) {
1155
+ if (['FilesId', 'Images'].includes(this.realJsonData[i])) {
1156
+ // 附件需要跳过 因为会通过 modifyModelData中的files,images属性给upload赋值
1157
+ // 新增修改表单每次提交时只会提交最新添加的文件
1158
+ continue
1159
+ }
1160
+ const item = this.realJsonData[i]
1161
+ // 地址选择器 需要传递 经纬度字段, 配置中添加 `${item.model}_lng_lat` CRUD 只需勾选 SQL生成查询项
1162
+ if (['addressSearch'].includes(item.type)) {
1163
+ this.form[item.model] = modifyModelData.data[item.model] + ''
1164
+ this.form[`${item.model}_lng_lat`] = modifyModelData.data[`${item.model}_lng_lat`] + ''
1165
+ continue
1166
+ }
1167
+ if (modifyModelData.data[item.model] || modifyModelData.data[item.model] === 0) {
1168
+ if (modifyModelData.data[item.model] instanceof Array) {
1169
+ this.form[item.model] = modifyModelData.data[item.model]
1170
+ } else {
1171
+ this.form[item.model] = modifyModelData.data[item.model] + ''
1172
+ }
1173
+ }
1174
+ }
1175
+ // 对分组表单进行处理
1176
+ for (let i = 0; i < this.groupJsonData.length; i++) {
1177
+ const item = this.groupJsonData[i]
1178
+ try {
1179
+ if (modifyModelData.data[item.model]) {
1180
+ this.form[item.model] = JSON.parse(modifyModelData.data[item.model])
1181
+ }
1182
+ } catch (e) {
1183
+ if (modifyModelData.data[item.model]) {
1184
+ this.form[item.model] = modifyModelData.data[item.model]
1185
+ }
1186
+ }
1187
+ }
1188
+ // 追加版本号信息
1189
+ for (const item of this.versionJsonData) {
1190
+ if (!modifyModelData.data[item.model]) {
1191
+ this.form[item.model] = 0
1192
+ } else {
1193
+ this.form[item.model] = modifyModelData.data[item.model] + ''
1194
+ }
1195
+ }
1196
+ },
1197
+ setForm (obj) {
1198
+ this.form = Object.assign(this.form, obj)
1199
+ // 给子表赋外键条件
1200
+ if (this.childFormData.length > 0) {
1201
+ for (const item of this.childFormData) {
1202
+ const child = this.$refs[item.model]
1203
+ // 获取子表别名,以便在条件上添加别名
1204
+ const alias = child.realQueryConfig.tableAliasName
1205
+ // 有主键,且主键有值,添加主键条件
1206
+ if (this.primaryKey && this.form[this.primaryKey]) {
1207
+ const foreignKey = item.foreignKey
1208
+ const fixedQueryForm = { [alias + '_' + foreignKey]: this.form[this.primaryKey] }
1209
+ if (!child.fixedQueryForm) {
1210
+ child.fixedQueryForm = fixedQueryForm
1211
+ } else {
1212
+ Object.assign(child.fixedQueryForm, fixedQueryForm)
1213
+ }
1214
+ child.refreshTable()
1215
+ }
1216
+ }
1217
+ }
1218
+ },
1219
+ setFormWithKey (obj) {
1220
+ setDataByRealKey(this.form, obj)
1221
+ },
1222
+ setFormWithNoKey (obj) {
1223
+ setDataByRealKey(this.form, obj)
1224
+ },
1225
+ emitFunc (func, data, value) {
1226
+ this.$emit(func, data, value)
1227
+ this.$emit('x-form-item-emit-func', func, data, value)
1228
+ },
1229
+ // 直接转发事件的函数
1230
+ emitEvent (event, ...args) {
1231
+ this.$emit(event, ...args)
1232
+ },
1233
+ close () {
1234
+ this.loaded = false
1235
+ },
1236
+ /**
1237
+ * 行选择事件
1238
+ * @param row 选中行集合
1239
+ * @param attr 表单项属性
1240
+ */
1241
+ async rowChoose (row, attr, callback) {
1242
+ // 如果配置了自定义函数
1243
+ if (attr.dataChangeFunc) {
1244
+ await executeStrFunction(attr.dataChangeFunc, [this.form, this.setForm, {
1245
+ ...attr,
1246
+ selectRows: row
1247
+ }, util, this.mode, runLogic, getConfigByNameAsync])
1248
+ } else {
1249
+ // 默认填充选中行数据到当前表单
1250
+ setDataByRealKey(this.form, row[0])
1251
+ }
1252
+ if (callback) {
1253
+ callback()
1254
+ }
1255
+ },
1256
+ }
1257
+ }
1258
+ </script>
1259
+
1260
+ <style scoped lang="less">
1261
+ :deep(.ant-form-inline .ant-form-item ) {
1262
+ display: block !important;
1263
+ }
1264
+
1265
+ :deep(.ant-form-item-with-help) {
1266
+ margin-bottom: 0;
1267
+ }
1268
+
1269
+ .xFormGroupTitle {
1270
+ font-weight: bold;
1271
+ color: @primary-color;
1272
+ }
1273
+
1274
+ .simple-inline-item {
1275
+ max-width: 100% !important;
1276
+ }
1277
+
1278
+ /* simple-inline模式样式 */
1279
+ :deep(.simple-inline-item .ant-form-item) {
1280
+ margin: 0 !important;
1281
+ padding: 2px !important;
1282
+
1283
+ .ant-form-item-label {
1284
+ display: none !important;
1285
+ }
1286
+
1287
+ .ant-form-item-control-wrapper,
1288
+ .ant-form-item-control {
1289
+ width: 100% !important;
1290
+ }
1291
+ }
1292
+ </style>