vue2-client 1.16.97 → 1.16.98

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 (326) 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/demo.vue +61 -61
  81. package/src/base-client/components/common/JSONToTree/jsontotree.vue +271 -271
  82. package/src/base-client/components/common/LowCodeComponent/LowCodeEditorModal.vue +108 -108
  83. package/src/base-client/components/common/LowCodeComponent/LowCodeEditorPanel.vue +413 -413
  84. package/src/base-client/components/common/LowCodeComponent/LowCodePageOrganization.vue +502 -502
  85. package/src/base-client/components/common/LowCodeComponent/LowCodeRender.vue +728 -728
  86. package/src/base-client/components/common/LowCodeComponent/LowCodeRenderEnter.vue +29 -29
  87. package/src/base-client/components/common/LowCodeComponent/LowCodeUIStore.vue +219 -219
  88. package/src/base-client/components/common/LowCodeComponent/modal/lowCodeAddPageModal.vue +117 -117
  89. package/src/base-client/components/common/LowCodeComponent/modal/lowCodeCustomJSModal.vue +80 -80
  90. package/src/base-client/components/common/LowCodeComponent/modal/lowCodeEventEditorModal.vue +398 -398
  91. package/src/base-client/components/common/LowCodeComponent/modal/lowCodeLifeCycleModal.vue +65 -65
  92. package/src/base-client/components/common/LowCodeComponent/modal/lowCodeLogicCallbackModal.vue +64 -64
  93. package/src/base-client/components/common/LowCodeComponent/modal/lowCodeLogicParamModal.vue +73 -73
  94. package/src/base-client/components/common/LowCodeComponent/modal/lowCodeRunFunctionParamModal.vue +76 -76
  95. package/src/base-client/components/common/PersonSetting/PersonSetting.vue +208 -208
  96. package/src/base-client/components/common/PersonSetting/index.js +3 -3
  97. package/src/base-client/components/common/Recording/Recording.vue +243 -243
  98. package/src/base-client/components/common/Recording/index.js +3 -3
  99. package/src/base-client/components/common/Tree/Tree.vue +149 -149
  100. package/src/base-client/components/common/Tree/index.js +2 -2
  101. package/src/base-client/components/common/Upload/Upload.vue +334 -334
  102. package/src/base-client/components/common/Upload/index.js +3 -3
  103. package/src/base-client/components/common/XAddForm/XAddForm.vue +113 -113
  104. package/src/base-client/components/common/XAddNativeForm/XAddNativeForm.vue +1292 -1292
  105. package/src/base-client/components/common/XAddNativeForm/index.md +146 -146
  106. package/src/base-client/components/common/XAddNativeFormOA/XAddNativeFormOA.vue +304 -304
  107. package/src/base-client/components/common/XAddNativeFormOA/index.js +3 -3
  108. package/src/base-client/components/common/XAddNativeFormOA/index.md +146 -146
  109. package/src/base-client/components/common/XAddReport/index.js +3 -3
  110. package/src/base-client/components/common/XAddReport/index.md +56 -56
  111. package/src/base-client/components/common/XBadge/XBadge.vue +94 -94
  112. package/src/base-client/components/common/XButtons/XButtonDemo.vue +28 -28
  113. package/src/base-client/components/common/XButtons/index.js +3 -3
  114. package/src/base-client/components/common/XButtons/index.md +61 -61
  115. package/src/base-client/components/common/XCalendar/XCalendar.vue +4 -4
  116. package/src/base-client/components/common/XCard/XCard.vue +64 -64
  117. package/src/base-client/components/common/XCheckList/XCheckList.vue +106 -106
  118. package/src/base-client/components/common/XCheckList/XCheckListDemo.vue +41 -41
  119. package/src/base-client/components/common/XDataCard/index.js +3 -3
  120. package/src/base-client/components/common/XDataCard/index.md +1 -1
  121. package/src/base-client/components/common/XDataDrawer/XDataDrawer.vue +180 -180
  122. package/src/base-client/components/common/XDataDrawer/index.js +3 -3
  123. package/src/base-client/components/common/XDataDrawer/index.md +41 -41
  124. package/src/base-client/components/common/XDatePicker/demo.vue +153 -153
  125. package/src/base-client/components/common/XDescriptions/index.js +3 -3
  126. package/src/base-client/components/common/XDescriptions/index.md +83 -83
  127. package/src/base-client/components/common/XDetailsView/XDetailsView.vue +238 -238
  128. package/src/base-client/components/common/XDetailsView/index.js +3 -3
  129. package/src/base-client/components/common/XForm/XFormItem.vue +1530 -1530
  130. package/src/base-client/components/common/XForm/XStatusButton.vue +54 -54
  131. package/src/base-client/components/common/XForm/index.md +178 -178
  132. package/src/base-client/components/common/XForm/itemComponent/XClickChangeBtn/index.vue +49 -49
  133. package/src/base-client/components/common/XFormGroup/index.js +3 -3
  134. package/src/base-client/components/common/XFormGroup/index.md +38 -38
  135. package/src/base-client/components/common/XFormGroupDetails/index.js +3 -3
  136. package/src/base-client/components/common/XFormTable/demo.vue +89 -89
  137. package/src/base-client/components/common/XFormTable/index.md +92 -92
  138. package/src/base-client/components/common/XLabelSelect/XLabelSelect.vue +110 -110
  139. package/src/base-client/components/common/XLabelSelect/XLabelSelectDemo.vue +35 -35
  140. package/src/base-client/components/common/XLicensePlate/XLicensePlate.vue +193 -193
  141. package/src/base-client/components/common/XLicensePlate/XLicensePlateDemo.vue +48 -48
  142. package/src/base-client/components/common/XPrint/OpenInvoice.vue +21 -21
  143. package/src/base-client/components/common/XPrint/PrintHtml.js +98 -98
  144. package/src/base-client/components/common/XPrint/css/hiPrintCss.js +359 -359
  145. package/src/base-client/components/common/XPrint/css/lodopCss.js +26 -26
  146. package/src/base-client/components/common/XPrint/css/print-lock.css +351 -351
  147. package/src/base-client/components/common/XPrint/index.vue +97 -97
  148. package/src/base-client/components/common/XReport/XReportDesign.vue +463 -463
  149. package/src/base-client/components/common/XReport/XReportJsonRender.vue +381 -381
  150. package/src/base-client/components/common/XReport/index.js +3 -3
  151. package/src/base-client/components/common/XReport/print.js +186 -186
  152. package/src/base-client/components/common/XReportDrawer/index.js +3 -3
  153. package/src/base-client/components/common/XReportGrid/index.js +3 -3
  154. package/src/base-client/components/common/XReportGrid/index.md +44 -44
  155. package/src/base-client/components/common/XReportSlot/XReportSlot.vue +110 -110
  156. package/src/base-client/components/common/XReportSlot/index.js +3 -3
  157. package/src/base-client/components/common/XReportSlot/index.md +48 -48
  158. package/src/base-client/components/common/XSimpleDescriptions/XSimpleDescriptions.vue +166 -166
  159. package/src/base-client/components/common/XSimpleDescriptions/index.js +3 -3
  160. package/src/base-client/components/common/XSimpleDescriptions/index.md +7 -7
  161. package/src/base-client/components/common/XStepView/XStepView.vue +252 -252
  162. package/src/base-client/components/common/XStepView/index.js +3 -3
  163. package/src/base-client/components/common/XStepView/index.md +31 -31
  164. package/src/base-client/components/common/XTab/XTabDemo.vue +22 -22
  165. package/src/base-client/components/common/XTab/index.js +3 -3
  166. package/src/base-client/components/common/XTable/CustomFuncCel.vue +51 -51
  167. package/src/base-client/components/common/XTable/TableCellRenderer.vue +161 -161
  168. package/src/base-client/components/common/XTable/XTable.vue +2 -1
  169. package/src/base-client/components/common/XTable/index.md +255 -255
  170. package/src/base-client/components/common/XTagGroup/index.vue +52 -52
  171. package/src/base-client/components/common/XTree/XTree.vue +424 -424
  172. package/src/base-client/components/common/XTree/index.js +3 -3
  173. package/src/base-client/components/common/XTree/index.md +36 -36
  174. package/src/base-client/components/common/XTreeOne/XTreeOne.vue +113 -113
  175. package/src/base-client/components/common/XTreeOne/XTreeOnePro.vue +128 -128
  176. package/src/base-client/components/common/richTextModal/index.vue +56 -56
  177. package/src/base-client/components/common/richTextModal/richDemo.vue +48 -48
  178. package/src/base-client/components/his/XCharge/XChargeDemo.vue +145 -145
  179. package/src/base-client/components/his/XHisEditor/index.js +3 -3
  180. package/src/base-client/components/index.js +51 -51
  181. package/src/base-client/components/layout/XTreeView/XTreeView.vue +130 -130
  182. package/src/base-client/components/layout/XTreeView/index.js +3 -3
  183. package/src/base-client/components/layout/XTreeView/index.md +46 -46
  184. package/src/base-client/components/system/DictionaryDetailsView/DictionaryDetailsView.vue +232 -232
  185. package/src/base-client/components/system/QueryParamsDetailsView/QueryParamsDetailsView.vue +281 -281
  186. package/src/base-client/plugins/Config.js +19 -19
  187. package/src/base-client/plugins/GetLoginInfoService.js +183 -183
  188. package/src/base-client/plugins/Recording.js +258 -258
  189. package/src/base-client/plugins/index.js +23 -23
  190. package/src/base-client/plugins/tabs-page-plugin.js +39 -39
  191. package/src/components/Charts/Bar.vue +62 -62
  192. package/src/components/Charts/ChartCard.vue +134 -134
  193. package/src/components/Charts/Liquid.vue +67 -67
  194. package/src/components/Charts/MiniArea.vue +39 -39
  195. package/src/components/Charts/MiniBar.vue +39 -39
  196. package/src/components/Charts/MiniProgress.vue +75 -75
  197. package/src/components/Charts/MiniSmoothArea.vue +40 -40
  198. package/src/components/Charts/Radar.vue +68 -68
  199. package/src/components/Charts/RankList.vue +77 -77
  200. package/src/components/Charts/TagCloud.vue +113 -113
  201. package/src/components/Charts/TransferBar.vue +64 -64
  202. package/src/components/Charts/Trend.vue +82 -82
  203. package/src/components/Charts/chart.less +12 -12
  204. package/src/components/Charts/smooth.area.less +13 -13
  205. package/src/components/CodeMirror/inedx.vue +118 -118
  206. package/src/components/CodeMirror/setting.js +40 -40
  207. package/src/components/NumberInfo/NumberInfo.vue +54 -54
  208. package/src/components/NumberInfo/index.js +3 -3
  209. package/src/components/NumberInfo/index.less +54 -54
  210. package/src/components/NumberInfo/index.md +43 -43
  211. package/src/components/card/ChartCard.vue +79 -79
  212. package/src/components/chart/Bar.vue +60 -60
  213. package/src/components/chart/MiniArea.vue +67 -67
  214. package/src/components/chart/MiniBar.vue +59 -59
  215. package/src/components/chart/MiniProgress.vue +57 -57
  216. package/src/components/chart/Radar.vue +80 -80
  217. package/src/components/chart/RankingList.vue +60 -60
  218. package/src/components/chart/Trend.vue +79 -79
  219. package/src/components/chart/index.less +9 -9
  220. package/src/components/checkbox/ColorCheckbox.vue +157 -157
  221. package/src/components/checkbox/ImgCheckbox.vue +117 -117
  222. package/src/components/checkbox/ImgCheckboxGroup.vue +76 -76
  223. package/src/components/checkbox/index.js +9 -9
  224. package/src/components/exception/ExceptionPage.vue +70 -70
  225. package/src/components/g2Charts/constants.js +202 -202
  226. package/src/components/g2Charts/demo.vue +808 -808
  227. package/src/components/g2Charts/designer.vue +228 -228
  228. package/src/components/g2Charts/designerBaseConfig.vue +61 -61
  229. package/src/components/g2Charts/designerDataConfig.vue +259 -259
  230. package/src/components/g2Charts/designerStyleConfig.vue +16 -16
  231. package/src/components/g2Charts/index.vue +397 -397
  232. package/src/components/index.js +36 -36
  233. package/src/components/input/IInput.vue +66 -66
  234. package/src/components/menu/SideMenu.vue +75 -75
  235. package/src/components/menu/menu.js +273 -273
  236. package/src/components/setting/Setting.vue +234 -234
  237. package/src/components/tool/AStepItem.vue +60 -60
  238. package/src/config/CreateQueryConfig.js +325 -325
  239. package/src/config/default/antd.config.js +89 -89
  240. package/src/config/default/setting.config.js +55 -55
  241. package/src/font-style/font.css +60 -60
  242. package/src/layouts/CommonLayout.vue +56 -56
  243. package/src/layouts/PageLayout.vue +151 -151
  244. package/src/layouts/SinglePageView.vue +136 -136
  245. package/src/layouts/header/AdminHeader.vue +132 -132
  246. package/src/layouts/header/HeaderNotice.vue +177 -177
  247. package/src/layouts/header/InstitutionDetail.vue +181 -181
  248. package/src/layouts/tabs/TabsHead.vue +189 -189
  249. package/src/lib.js +1 -1
  250. package/src/mock/extend/index.js +84 -84
  251. package/src/mock/goods/index.js +108 -108
  252. package/src/pages/DefaultExample/index.vue +77 -77
  253. package/src/pages/DynamicStatistics/ChartSelector.vue +331 -331
  254. package/src/pages/DynamicStatistics/DataTabs.vue +83 -83
  255. package/src/pages/DynamicStatistics/DynamicTable.vue +128 -128
  256. package/src/pages/DynamicStatistics/EvaluationArea.vue +69 -69
  257. package/src/pages/DynamicStatistics/FavoriteList.vue +50 -50
  258. package/src/pages/DynamicStatistics/QuestionHistoryAndFavorites.vue +591 -591
  259. package/src/pages/DynamicStatistics/SearchBar.vue +192 -192
  260. package/src/pages/DynamicStatistics/index.vue +282 -282
  261. package/src/pages/Example/childIndex.vue +15 -15
  262. package/src/pages/Example/index.vue +30 -30
  263. package/src/pages/NewDynamicStatistics/ChartSelector.vue +331 -331
  264. package/src/pages/NewDynamicStatistics/DataTabs.vue +122 -122
  265. package/src/pages/NewDynamicStatistics/DynamicTable.vue +128 -128
  266. package/src/pages/NewDynamicStatistics/EvaluationArea.vue +69 -69
  267. package/src/pages/NewDynamicStatistics/FavoriteList.vue +50 -50
  268. package/src/pages/NewDynamicStatistics/QuestionHistoryAndFavorites.vue +289 -289
  269. package/src/pages/NewDynamicStatistics/SearchBar.vue +193 -193
  270. package/src/pages/NewDynamicStatistics/index.vue +258 -258
  271. package/src/pages/Recording/index.vue +77 -77
  272. package/src/pages/ServiceReview/index.vue +284 -284
  273. package/src/pages/SubExample/index.vue +26 -26
  274. package/src/pages/WorkflowDetail/WorkflowPageDetail/TrimTextTail.vue +23 -23
  275. package/src/pages/XReportView/index.vue +64 -64
  276. package/src/pages/XTreeOneProExample/index.vue +67 -67
  277. package/src/pages/dashboard/workplace/WorkPlace.vue +141 -141
  278. package/src/pages/login/Login.vue +379 -379
  279. package/src/pages/login/LoginV3.vue +389 -389
  280. package/src/pages/lowCode/lowCodeEditor.vue +1219 -1219
  281. package/src/pages/lowCode/lowCodeRenderPage.vue +43 -43
  282. package/src/pages/report/ReportTable.js +124 -124
  283. package/src/pages/resourceManage/orgListManage.vue +98 -98
  284. package/src/pages/system/dictionary/index.vue +44 -44
  285. package/src/pages/system/monitor/loginInfor/index.vue +37 -37
  286. package/src/pages/system/monitor/operLog/index.vue +37 -37
  287. package/src/pages/system/settings/modifyPassword.vue +117 -117
  288. package/src/pages/system/ticket/index.vue +480 -480
  289. package/src/pages/system/ticket/submitTicketSuccess.vue +484 -484
  290. package/src/pages/userInfoDetailManage/ChangeMeterRecordQuery/index.vue +64 -64
  291. package/src/pages/userInfoDetailManage/InfoChangeRecordQuery/index.vue +64 -64
  292. package/src/pages/userInfoDetailManage/InstructRecordQuery/index.vue +64 -64
  293. package/src/pages/userInfoDetailManage/MeterParamRecordQuery/index.vue +64 -64
  294. package/src/pages/userInfoDetailManage/TransferRecordQuery/index.vue +66 -66
  295. package/src/pages/userInfoDetailManage/WatchCollectionRecordQuery/index.vue +64 -64
  296. package/src/plugins/EventLogPlugin.js +33 -33
  297. package/src/plugins/FindParentsData.js +17 -17
  298. package/src/services/DataModel.js +30 -30
  299. package/src/services/LodopFuncs.js +137 -137
  300. package/src/services/api/TicketDetailsViewApi.js +46 -46
  301. package/src/services/api/cas.js +79 -79
  302. package/src/services/api/entity.js +18 -18
  303. package/src/services/api/index.js +17 -17
  304. package/src/store/modules/account.js +115 -115
  305. package/src/store/modules/index.js +5 -5
  306. package/src/store/modules/lowCode.js +33 -33
  307. package/src/store/modules/setting.js +119 -119
  308. package/src/theme/default/style.less +58 -58
  309. package/src/utils/authority-utils.js +85 -85
  310. package/src/utils/errorCode.js +6 -6
  311. package/src/utils/formatter.js +74 -74
  312. package/src/utils/htmlToPDF.js +108 -108
  313. package/src/utils/htmlToPDFApi.js +5 -5
  314. package/src/utils/login.js +188 -188
  315. package/src/utils/lowcode/lowcodeComponentMixin.js +120 -120
  316. package/src/utils/lowcode/lowcodeLog.js +29 -29
  317. package/src/utils/lowcode/lowcodeUtils.js +373 -373
  318. package/src/utils/lowcode/registerComponentForEditor.js +1 -1
  319. package/src/utils/lowcode/registerComponentForRender.js +11 -11
  320. package/src/utils/map-utils.js +47 -47
  321. package/src/utils/reg.js +95 -95
  322. package/src/utils/runEvalFunction.js +14 -14
  323. package/src/utils/theme-color-replacer-extend.js +92 -92
  324. package/src/utils/util.js +329 -329
  325. package/src/utils/waterMark.js +31 -31
  326. package//350/277/201/347/247/273/346/227/245/345/277/227.md +15 -15
@@ -1,1292 +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
- 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
- // 如果 fixedAddForm 有 selected_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>
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
+ // 如果 fixedAddForm 有 selected_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>