cnhis-design-vue 2.1.57 → 2.1.59

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 (574) hide show
  1. package/.prettierrc.js +27 -27
  2. package/CHANGELOG.md +2610 -2634
  3. package/README.md +90 -90
  4. package/commitlint.config.js +1 -1
  5. package/es/affix/index.js +8 -8
  6. package/es/age/index.js +18 -18
  7. package/es/alert/index.js +8 -8
  8. package/es/anchor/index.js +8 -8
  9. package/es/auto-complete/index.js +8 -8
  10. package/es/avatar/index.js +8 -8
  11. package/es/back-top/index.js +8 -8
  12. package/es/badge/index.js +8 -8
  13. package/es/base/index.js +8 -8
  14. package/es/big-table/index.js +345 -333
  15. package/es/big-table/style.css +1 -1
  16. package/es/breadcrumb/index.js +8 -8
  17. package/es/button/index.js +31 -31
  18. package/es/calendar/index.js +8 -8
  19. package/es/captcha/index.js +7 -7
  20. package/es/card/index.js +8 -8
  21. package/es/carousel/index.js +8 -8
  22. package/es/cascader/index.js +8 -8
  23. package/es/checkbox/index.js +17 -17
  24. package/es/col/index.js +8 -8
  25. package/es/collapse/index.js +8 -8
  26. package/es/color-picker/index.js +5 -5
  27. package/es/comment/index.js +8 -8
  28. package/es/config-provider/index.js +8 -8
  29. package/es/date-picker/index.js +30 -30
  30. package/es/descriptions/index.js +8 -8
  31. package/es/divider/index.js +8 -8
  32. package/es/drag-layout/index.js +5 -5
  33. package/es/drawer/index.js +8 -8
  34. package/es/dropdown/index.js +8 -8
  35. package/es/editor/index.js +1 -1
  36. package/es/ellipsis/index.js +1 -1
  37. package/es/empty/index.js +8 -8
  38. package/es/fabric-chart/index.js +724 -436
  39. package/es/fabric-chart/style.css +1 -1
  40. package/es/form/index.js +8 -8
  41. package/es/form-model/index.js +8 -8
  42. package/es/form-table/index.js +221 -189
  43. package/es/form-table/style.css +1 -1
  44. package/es/grid/index.js +4 -4
  45. package/es/index/index.js +2042 -1695
  46. package/es/index/style.css +1 -1
  47. package/es/input/index.js +11 -11
  48. package/es/input-number/index.js +8 -8
  49. package/es/keep-cache/index.js +9 -9
  50. package/es/layout/index.js +8 -8
  51. package/es/list/index.js +8 -8
  52. package/es/locale-provider/index.js +8 -8
  53. package/es/map/index.js +13 -13
  54. package/es/mentions/index.js +8 -8
  55. package/es/menu/index.js +8 -8
  56. package/es/message/index.js +8 -8
  57. package/es/multi-chat/index.js +116 -116
  58. package/es/multi-chat-client/index.js +110 -110
  59. package/es/multi-chat-history/index.js +6 -6
  60. package/es/multi-chat-record/index.js +27 -27
  61. package/es/multi-chat-setting/index.js +43 -43
  62. package/es/multi-chat-sip/index.js +1 -1
  63. package/es/notification/index.js +8 -8
  64. package/es/page-header/index.js +8 -8
  65. package/es/pagination/index.js +8 -8
  66. package/es/popconfirm/index.js +8 -8
  67. package/es/popover/index.js +8 -8
  68. package/es/progress/index.js +8 -8
  69. package/es/radio/index.js +17 -17
  70. package/es/rate/index.js +8 -8
  71. package/es/result/index.js +8 -8
  72. package/es/row/index.js +8 -8
  73. package/es/scale-container/index.js +28 -23
  74. package/es/scale-container/style.css +1 -1
  75. package/es/scale-view/index.js +158 -158
  76. package/es/select/index.js +44 -44
  77. package/es/select-label/index.js +50 -50
  78. package/es/select-person/index.js +20 -20
  79. package/es/shortcut-setter/index.js +10 -10
  80. package/es/skeleton/index.js +8 -8
  81. package/es/slider/index.js +8 -8
  82. package/es/space/index.js +8 -8
  83. package/es/spin/index.js +8 -8
  84. package/es/statistic/index.js +8 -8
  85. package/es/steps/index.js +8 -8
  86. package/es/switch/index.js +8 -8
  87. package/es/table-filter/index.js +253 -238
  88. package/es/table-filter/style.css +1 -1
  89. package/es/tabs/index.js +8 -8
  90. package/es/tag/index.js +9 -9
  91. package/es/time-picker/index.js +8 -8
  92. package/es/timeline/index.js +8 -8
  93. package/es/tooltip/index.js +8 -8
  94. package/es/transfer/index.js +8 -8
  95. package/es/tree/index.js +8 -8
  96. package/es/tree-select/index.js +8 -8
  97. package/es/upload/index.js +8 -8
  98. package/es/utils/clickoutside.js +7 -7
  99. package/es/utils/kty.min-1.0.0.js +5 -5
  100. package/es/utils/time-domain.js +16 -16
  101. package/es/utils/utils-map.js +32 -32
  102. package/es/utils/vexutils.js +27 -27
  103. package/es/verification-code/index.js +2 -2
  104. package/lib/cui.common.js +2172 -1825
  105. package/lib/cui.umd.js +2172 -1825
  106. package/lib/cui.umd.min.js +28 -28
  107. package/package.json +110 -110
  108. package/packages/affix/index.js +12 -12
  109. package/packages/affix/src/Affix.jsx +12 -12
  110. package/packages/age/index.js +27 -27
  111. package/packages/age/src/age/index.vue +139 -139
  112. package/packages/age/src/age-com/index.vue +209 -209
  113. package/packages/alert/index.js +12 -12
  114. package/packages/alert/src/Alert.jsx +11 -11
  115. package/packages/anchor/index.js +18 -18
  116. package/packages/anchor/src/Anchor.jsx +11 -11
  117. package/packages/anchor/src/Link.jsx +11 -11
  118. package/packages/auto-complete/index.js +12 -12
  119. package/packages/auto-complete/src/AutoComplete.jsx +12 -12
  120. package/packages/avatar/index.js +12 -12
  121. package/packages/avatar/src/Avatar.jsx +11 -11
  122. package/packages/back-top/index.js +12 -12
  123. package/packages/back-top/src/BackTop.jsx +11 -11
  124. package/packages/badge/index.js +12 -12
  125. package/packages/badge/src/Badge.jsx +11 -11
  126. package/packages/base/index.js +3 -3
  127. package/packages/big-table/index.js +16 -16
  128. package/packages/big-table/src/BigTable.vue +3150 -3144
  129. package/packages/big-table/src/Fieldset.vue +2067 -2067
  130. package/packages/big-table/src/assets/iconfont/iconfont.css +21 -21
  131. package/packages/big-table/src/assets/style/table-base.less +385 -385
  132. package/packages/big-table/src/assets/style/table-global.less +175 -175
  133. package/packages/big-table/src/components/AutoLayoutButton.vue +279 -279
  134. package/packages/big-table/src/components/NoData.vue +81 -81
  135. package/packages/big-table/src/components/TextOverTooltip.vue +120 -120
  136. package/packages/big-table/src/components/edit-form/EditForm.vue +509 -509
  137. package/packages/big-table/src/components/edit-form/edit-component/config-data/index.js +68 -68
  138. package/packages/big-table/src/components/edit-form/edit-component/edit-date-picker/edit-date-picker.vue +60 -60
  139. package/packages/big-table/src/components/edit-form/edit-component/edit-digital/edit-digital.vue +54 -54
  140. package/packages/big-table/src/components/edit-form/edit-component/edit-input/edit-input.vue +39 -39
  141. package/packages/big-table/src/components/edit-form/edit-component/edit-input-password/edit-input-password.vue +79 -79
  142. package/packages/big-table/src/components/edit-form/edit-component/edit-month-picker/edit-month-picker.vue +37 -37
  143. package/packages/big-table/src/components/edit-form/edit-component/edit-search/edit-search.vue +82 -82
  144. package/packages/big-table/src/components/edit-form/edit-component/edit-search-more/edit-search-more.vue +95 -95
  145. package/packages/big-table/src/components/edit-form/edit-component/edit-select/edit-select.vue +40 -40
  146. package/packages/big-table/src/components/edit-form/edit-component/edit-select-multiple/edit-select-multiple.vue +55 -55
  147. package/packages/big-table/src/components/edit-form/edit-component/edit-switch/edit-switch.vue +43 -43
  148. package/packages/big-table/src/components/edit-form/edit-component/edit-textarea/edit-textarea.vue +41 -41
  149. package/packages/big-table/src/components/edit-form/edit-component/edit-time-picker/edit-time-picker.vue +40 -40
  150. package/packages/big-table/src/components/edit-form/edit-component/mixins/bound-date.js +3 -3
  151. package/packages/big-table/src/components/edit-form/edit-component/mixins/dateType.js +217 -217
  152. package/packages/big-table/src/components/edit-form/edit-component/mixins/item-default.js +639 -639
  153. package/packages/big-table/src/components/edit-form/edit-component/mixins/search.js +1247 -1247
  154. package/packages/big-table/src/components/edit-form/edit-component/register-com.js +26 -26
  155. package/packages/big-table/src/components/edit-form/edit-item/form-event.js +80 -80
  156. package/packages/big-table/src/components/edit-form/edit-item/global-props.js +33 -33
  157. package/packages/big-table/src/components/edit-form/edit-item/index.js +4 -4
  158. package/packages/big-table/src/components/edit-form/edit-item/render-methods.js +28 -28
  159. package/packages/big-table/src/components/edit-form/edit-item/validate-rules.js +463 -463
  160. package/packages/big-table/src/components/edit-form/edit-mixins/form-commom.js +673 -673
  161. package/packages/big-table/src/components/edit-form/edit-mixins/index.js +3 -3
  162. package/packages/big-table/src/components/edit-form/edit-utils/index.js +112 -112
  163. package/packages/big-table/src/components/password-com.vue +58 -58
  164. package/packages/big-table/src/components/player-vod/index.vue +57 -57
  165. package/packages/big-table/src/components/player-vod/player.vue +189 -189
  166. package/packages/big-table/src/components/player-vod/video-list.vue +265 -265
  167. package/packages/big-table/src/components/player-vod/video-modal.vue +126 -126
  168. package/packages/big-table/src/utils/CustomPagination.vue +86 -86
  169. package/packages/big-table/src/utils/batchEditing.js +610 -610
  170. package/packages/big-table/src/utils/bigTableProps.js +103 -103
  171. package/packages/big-table/src/utils/format.js +557 -557
  172. package/packages/big-table/src/utils/nestTable.js +109 -109
  173. package/packages/big-table/src/utils/tableParse.js +234 -234
  174. package/packages/breadcrumb/index.js +21 -21
  175. package/packages/breadcrumb/src/Breadcrumb.jsx +11 -11
  176. package/packages/breadcrumb/src/BreadcrumbItem.jsx +11 -11
  177. package/packages/breadcrumb/src/BreadcrumbSeparator.jsx +11 -11
  178. package/packages/button/index.js +21 -21
  179. package/packages/button/src/Button.jsx +11 -11
  180. package/packages/button/src/ButtonGroup.jsx +11 -11
  181. package/packages/button/src/ButtonPrint/components/IdentityVerification.vue +181 -181
  182. package/packages/button/src/ButtonPrint/index.vue +766 -766
  183. package/packages/button/src/ButtonPrint/mixin/his-print.js +95 -95
  184. package/packages/calendar/index.js +12 -12
  185. package/packages/calendar/src/Calendar.jsx +11 -11
  186. package/packages/captcha/index.js +9 -9
  187. package/packages/captcha/src/Captcha.vue +164 -164
  188. package/packages/captcha/src/Index.vue +47 -47
  189. package/packages/captcha/src/SlideVerify.vue +285 -285
  190. package/packages/card/index.js +21 -21
  191. package/packages/card/src/Card.jsx +12 -12
  192. package/packages/card/src/CardGrid.js +7 -7
  193. package/packages/card/src/CardMeta.js +7 -7
  194. package/packages/carousel/index.js +12 -12
  195. package/packages/carousel/src/Carousel.jsx +12 -12
  196. package/packages/cascader/index.js +12 -12
  197. package/packages/cascader/src/Cascader.jsx +11 -11
  198. package/packages/checkbox/index.js +30 -30
  199. package/packages/checkbox/src/Checkbox.jsx +11 -11
  200. package/packages/checkbox/src/CheckboxImg/index.vue +141 -141
  201. package/packages/checkbox/src/Group.jsx +11 -11
  202. package/packages/col/index.js +13 -13
  203. package/packages/col/src/Col.jsx +11 -11
  204. package/packages/collapse/index.js +18 -18
  205. package/packages/collapse/src/Collapse.jsx +11 -11
  206. package/packages/collapse/src/Panel.jsx +11 -11
  207. package/packages/color-picker/index.js +10 -10
  208. package/packages/color-picker/src/color-picker.vue +191 -191
  209. package/packages/color-picker/src/style.less +109 -109
  210. package/packages/comment/index.js +12 -12
  211. package/packages/comment/src/Comment.jsx +11 -11
  212. package/packages/config-provider/index.js +12 -12
  213. package/packages/config-provider/src/ConfigProvider.jsx +11 -11
  214. package/packages/date-picker/index.js +26 -26
  215. package/packages/date-picker/src/DatePicker.jsx +12 -12
  216. package/packages/date-picker/src/MonthPicker.jsx +11 -11
  217. package/packages/date-picker/src/RangePicker.jsx +11 -11
  218. package/packages/date-picker/src/WeekPicker.jsx +11 -11
  219. package/packages/date-picker/src/utils/index.js +374 -374
  220. package/packages/descriptions/index.js +18 -18
  221. package/packages/descriptions/src/Descriptions.jsx +11 -11
  222. package/packages/descriptions/src/Item.jsx +11 -11
  223. package/packages/divider/index.js +12 -12
  224. package/packages/divider/src/Divider.jsx +11 -11
  225. package/packages/drag-layout/DragFormLeftItem.vue +173 -173
  226. package/packages/drag-layout/DragFormRightItem.vue +284 -284
  227. package/packages/drag-layout/I18n-mixins.js +10 -10
  228. package/packages/drag-layout/drag-layout.vue +778 -778
  229. package/packages/drag-layout/index.js +12 -12
  230. package/packages/drawer/index.js +12 -12
  231. package/packages/drawer/src/Drawer.jsx +11 -11
  232. package/packages/dropdown/index.js +12 -12
  233. package/packages/dropdown/src/Dropdown.jsx +11 -11
  234. package/packages/editor/index.js +9 -9
  235. package/packages/ellipsis/index.js +8 -8
  236. package/packages/ellipsis/src/Ellipsis.vue +65 -65
  237. package/packages/empty/index.js +12 -12
  238. package/packages/empty/src/Empty.jsx +11 -11
  239. package/packages/fabric-chart/index.js +9 -9
  240. package/packages/fabric-chart/src/FabricGrid.vue +67 -66
  241. package/packages/fabric-chart/src/components/DropPopup.vue +90 -90
  242. package/packages/fabric-chart/src/components/MouseRightClick.vue +168 -168
  243. package/packages/fabric-chart/src/components/TimeScaleValue.vue +114 -115
  244. package/packages/fabric-chart/src/const/defaultVaule.js +60 -59
  245. package/packages/fabric-chart/src/fabric-chart/FabricCanvas.vue +43 -9
  246. package/packages/fabric-chart/src/fabric-chart/FabricLines.vue +579 -552
  247. package/packages/fabric-chart/src/fabric-chart/FabricPolylines.vue +1142 -1126
  248. package/packages/fabric-chart/src/fabric-chart/FabricScaleValue.vue +134 -134
  249. package/packages/fabric-chart/src/fabric-chart/FabricTextGroup.vue +574 -566
  250. package/packages/fabric-chart/src/mixins/eventCommon.js +34 -1
  251. package/packages/fabric-chart/src/mixins/fabricCommon.js +95 -95
  252. package/packages/fabric-chart/src/mixins/fabricObject.js +193 -193
  253. package/packages/fabric-chart/src/mixins/type.js +5 -5
  254. package/packages/form/index.js +16 -16
  255. package/packages/form/src/Form.jsx +11 -11
  256. package/packages/form/src/Item.jsx +11 -11
  257. package/packages/form-model/index.js +14 -14
  258. package/packages/form-model/src/FormModel.jsx +11 -11
  259. package/packages/form-model/src/Item.jsx +11 -11
  260. package/packages/form-table/index.js +16 -16
  261. package/packages/form-table/src/FormTable.vue +1110 -1110
  262. package/packages/form-table/src/components/table-component/config-data/index.js +80 -80
  263. package/packages/form-table/src/components/table-component/global-props.js +22 -22
  264. package/packages/form-table/src/components/table-component/index.js +8 -8
  265. package/packages/form-table/src/components/table-component/mixins/bound-date.js +455 -455
  266. package/packages/form-table/src/components/table-component/mixins/dateType.js +217 -217
  267. package/packages/form-table/src/components/table-component/mixins/item-default.js +257 -257
  268. package/packages/form-table/src/components/table-component/mixins/search.js +1242 -1238
  269. package/packages/form-table/src/components/table-component/register-com.js +30 -30
  270. package/packages/form-table/src/components/table-component/table-age/table-age.vue +175 -175
  271. package/packages/form-table/src/components/table-component/table-date-picker/table-date-picker.vue +87 -87
  272. package/packages/form-table/src/components/table-component/table-digital/table-digital.vue +93 -93
  273. package/packages/form-table/src/components/table-component/table-input/table-input.vue +81 -81
  274. package/packages/form-table/src/components/table-component/table-input-password/table-input-password.vue +126 -126
  275. package/packages/form-table/src/components/table-component/table-month-picker/table-month-picker.vue +55 -55
  276. package/packages/form-table/src/components/table-component/table-search/table-search.vue +174 -174
  277. package/packages/form-table/src/components/table-component/table-search-more/table-search-more.vue +191 -191
  278. package/packages/form-table/src/components/table-component/table-select/table-select.vue +64 -64
  279. package/packages/form-table/src/components/table-component/table-select-multiple/table-select-multiple.vue +81 -81
  280. package/packages/form-table/src/components/table-component/table-textarea/table-textarea.vue +76 -76
  281. package/packages/form-table/src/components/table-component/table-time-picker/table-time-picker.vue +55 -55
  282. package/packages/form-table/src/components/table-component/table-tree-select/table-tree-select.vue +135 -135
  283. package/packages/form-table/src/components/table-component/text-over-tooltip/TextOverTooltip.vue +97 -97
  284. package/packages/form-table/src/components/table-item/form-event.js +81 -81
  285. package/packages/form-table/src/components/table-item/global-props.js +27 -27
  286. package/packages/form-table/src/components/table-item/index.js +4 -4
  287. package/packages/form-table/src/components/table-item/render-methods.js +28 -28
  288. package/packages/form-table/src/components/table-item/validate-rules.js +520 -520
  289. package/packages/form-table/src/components/table-mixins/form-commom.js +98 -98
  290. package/packages/form-table/src/components/table-mixins/index.js +3 -3
  291. package/packages/form-table/src/components/table-utils/index.js +112 -112
  292. package/packages/form-table/src/disabledDetail.less +46 -46
  293. package/packages/grid/index.js +10 -10
  294. package/packages/grid/src/grid.js +28 -28
  295. package/packages/icon/index.js +10 -10
  296. package/packages/icon/src/icon.js +13 -13
  297. package/packages/index.js +313 -313
  298. package/packages/input/index.js +30 -30
  299. package/packages/input/src/Group.jsx +11 -11
  300. package/packages/input/src/Input.jsx +11 -11
  301. package/packages/input/src/Password.jsx +11 -11
  302. package/packages/input/src/Search.jsx +11 -11
  303. package/packages/input/src/TextArea.jsx +11 -11
  304. package/packages/input/src/input-quick/components/quick-item.vue +284 -284
  305. package/packages/input/src/input-quick/components/quick-popover.vue +596 -596
  306. package/packages/input/src/input-quick/index.vue +137 -137
  307. package/packages/input-number/index.js +12 -12
  308. package/packages/input-number/src/InputNumber.jsx +11 -11
  309. package/packages/keep-cache/KeepCache.js +236 -236
  310. package/packages/keep-cache/index.css +2 -2
  311. package/packages/keep-cache/index.js +8 -8
  312. package/packages/layout/index.js +27 -27
  313. package/packages/layout/src/Content.jsx +11 -11
  314. package/packages/layout/src/Footer.jsx +11 -11
  315. package/packages/layout/src/Header.jsx +11 -11
  316. package/packages/layout/src/Layout.jsx +11 -11
  317. package/packages/layout/src/Sider.jsx +11 -11
  318. package/packages/list/index.js +21 -21
  319. package/packages/list/src/Item.jsx +11 -11
  320. package/packages/list/src/ItemMeta.jsx +11 -11
  321. package/packages/list/src/List.jsx +11 -11
  322. package/packages/locale-provider/index.js +12 -12
  323. package/packages/locale-provider/src/LocaleProvider.jsx +11 -11
  324. package/packages/map/index.js +9 -9
  325. package/packages/map/src/Map.vue +484 -484
  326. package/packages/map/src/popup-map.vue +53 -53
  327. package/packages/mentions/index.js +18 -18
  328. package/packages/mentions/src/Mentions.jsx +11 -11
  329. package/packages/mentions/src/Option.jsx +11 -11
  330. package/packages/menu/index.js +27 -27
  331. package/packages/menu/src/Divider.jsx +11 -11
  332. package/packages/menu/src/Item.jsx +11 -11
  333. package/packages/menu/src/ItemGroup.jsx +11 -11
  334. package/packages/menu/src/Menu.jsx +11 -11
  335. package/packages/menu/src/SubMenu.jsx +11 -11
  336. package/packages/message/index.js +8 -8
  337. package/packages/modal/index.js +10 -10
  338. package/packages/modal/src/Modal.js +7 -7
  339. package/packages/multi-chat/chat/addConference.vue +200 -200
  340. package/packages/multi-chat/chat/addMembers.vue +411 -411
  341. package/packages/multi-chat/chat/advancedFilter.vue +372 -372
  342. package/packages/multi-chat/chat/calling.vue +246 -246
  343. package/packages/multi-chat/chat/chatFooter.vue +1596 -1596
  344. package/packages/multi-chat/chat/chatHistory.vue +605 -605
  345. package/packages/multi-chat/chat/chatMain.vue +1486 -1486
  346. package/packages/multi-chat/chat/client/index.vue +149 -149
  347. package/packages/multi-chat/chat/delay.vue +177 -177
  348. package/packages/multi-chat/chat/evaluate.vue +343 -343
  349. package/packages/multi-chat/chat/messageRecord.vue +324 -324
  350. package/packages/multi-chat/chat/mixins/NoData.js +20 -20
  351. package/packages/multi-chat/chat/mixins/base.js +97 -97
  352. package/packages/multi-chat/chat/mixins/uniRTCAPI.js +80 -80
  353. package/packages/multi-chat/chat/mixins/viewerOptions.js +67 -67
  354. package/packages/multi-chat/chat/quickReply.vue +439 -439
  355. package/packages/multi-chat/chat/robot/index.vue +312 -312
  356. package/packages/multi-chat/chat/scrollList.vue +1238 -1238
  357. package/packages/multi-chat/chat/videoVoiceList.vue +348 -348
  358. package/packages/multi-chat/chat/voice.vue +431 -431
  359. package/packages/multi-chat/components/avatar.vue +113 -113
  360. package/packages/multi-chat/components/chat-tabs-header.vue +251 -251
  361. package/packages/multi-chat/components/classify-tabs.vue +185 -185
  362. package/packages/multi-chat/components/empty.vue +24 -24
  363. package/packages/multi-chat/components/modal-refuse-reason.vue +112 -112
  364. package/packages/multi-chat/components/modal-sip.vue +160 -160
  365. package/packages/multi-chat/components/modal-user-transfer.vue +98 -98
  366. package/packages/multi-chat/components/msg-describe.vue +138 -138
  367. package/packages/multi-chat/components/msg-picture.vue +68 -68
  368. package/packages/multi-chat/components/msg-prescription.vue +205 -205
  369. package/packages/multi-chat/components/read-record.vue +133 -133
  370. package/packages/multi-chat/components/read-status.vue +34 -34
  371. package/packages/multi-chat/components/user-status.vue +198 -198
  372. package/packages/multi-chat/index.js +7 -7
  373. package/packages/multi-chat/setting/authority/index.vue +156 -156
  374. package/packages/multi-chat/setting/authority/roleSetting.vue +204 -204
  375. package/packages/multi-chat/setting/baseInfo/index.vue +1316 -1316
  376. package/packages/multi-chat/setting/customerService/batchSelect.vue +403 -403
  377. package/packages/multi-chat/setting/customerService/index.vue +273 -273
  378. package/packages/multi-chat/setting/event/edit/condition.vue +128 -128
  379. package/packages/multi-chat/setting/event/edit/index.vue +437 -437
  380. package/packages/multi-chat/setting/event/edit/notice.vue +129 -129
  381. package/packages/multi-chat/setting/event/edit/strategy.vue +98 -98
  382. package/packages/multi-chat/setting/event/index.vue +249 -249
  383. package/packages/multi-chat/setting/index.vue +269 -269
  384. package/packages/multi-chat/setting/page.vue +14 -14
  385. package/packages/multi-chat/setting/sessionList/index.vue +412 -412
  386. package/packages/multi-chat/setting/sessionList/messageRecord.vue +372 -372
  387. package/packages/multi-chat/setting/userConfig/index.vue +124 -124
  388. package/packages/multi-chat/setting/worktime/index.vue +274 -274
  389. package/packages/multi-chat/store/actions.js +452 -452
  390. package/packages/multi-chat/store/getters.js +371 -371
  391. package/packages/multi-chat/store/helper.js +66 -66
  392. package/packages/multi-chat/store/index.js +50 -50
  393. package/packages/multi-chat/store/mutation.js +296 -296
  394. package/packages/multi-chat/store/state.js +117 -117
  395. package/packages/multi-chat/style/emoji.css +315 -315
  396. package/packages/multi-chat/style/message.mixin.less +38 -38
  397. package/packages/multi-chat/utils/chatSock.js +93 -93
  398. package/packages/multi-chat/utils/compressImage.js +115 -115
  399. package/packages/multi-chat/utils/emoji.json +68 -68
  400. package/packages/multi-chat/utils/index.js +259 -259
  401. package/packages/multi-chat/utils/observer-scroll.js +49 -49
  402. package/packages/multi-chat/utils/panelsetting.js +48 -48
  403. package/packages/multi-chat-client/index.js +7 -7
  404. package/packages/multi-chat-history/index.js +7 -7
  405. package/packages/multi-chat-record/index.js +7 -7
  406. package/packages/multi-chat-setting/index.js +7 -7
  407. package/packages/multi-chat-sip/index.js +6 -6
  408. package/packages/notification/index.js +8 -8
  409. package/packages/page-header/index.js +12 -12
  410. package/packages/page-header/src/PageHeader.jsx +11 -11
  411. package/packages/pagination/index.js +12 -12
  412. package/packages/pagination/src/Pagination.jsx +11 -11
  413. package/packages/popconfirm/index.js +12 -12
  414. package/packages/popconfirm/src/Popconfirm.jsx +11 -11
  415. package/packages/popover/index.js +12 -12
  416. package/packages/popover/src/Popover.jsx +11 -11
  417. package/packages/progress/index.js +12 -12
  418. package/packages/progress/src/Progress.jsx +11 -11
  419. package/packages/radio/index.js +33 -33
  420. package/packages/radio/src/Group.jsx +11 -11
  421. package/packages/radio/src/Radio.jsx +11 -11
  422. package/packages/radio/src/RadioButton.jsx +11 -11
  423. package/packages/radio/src/RadioImg/index.vue +124 -124
  424. package/packages/rate/index.js +12 -12
  425. package/packages/rate/src/Rate.jsx +11 -11
  426. package/packages/result/index.js +12 -12
  427. package/packages/result/src/Result.jsx +11 -11
  428. package/packages/row/index.js +12 -12
  429. package/packages/row/src/Row.jsx +11 -11
  430. package/packages/scale-container/index.js +8 -8
  431. package/packages/scale-container/src/ScaleContainer.vue +197 -194
  432. package/packages/scale-view/NoData.vue +81 -81
  433. package/packages/scale-view/answerParse.vue +133 -133
  434. package/packages/scale-view/customList.vue +801 -801
  435. package/packages/scale-view/data.js +80 -80
  436. package/packages/scale-view/evaluateCountdown.vue +155 -155
  437. package/packages/scale-view/evaluatePage.vue +202 -202
  438. package/packages/scale-view/formitem/data.js +3991 -3991
  439. package/packages/scale-view/formitem/index.js +6 -6
  440. package/packages/scale-view/formitem/r-address.vue +238 -238
  441. package/packages/scale-view/formitem/r-choice.vue +726 -726
  442. package/packages/scale-view/formitem/r-input.vue +92 -92
  443. package/packages/scale-view/formitem/r-prompt.vue +52 -52
  444. package/packages/scale-view/formitem/r-time.vue +285 -285
  445. package/packages/scale-view/formitem/r-upload-custom-list.vue +242 -242
  446. package/packages/scale-view/formitem/r-upload.vue +287 -287
  447. package/packages/scale-view/formitem/text-over-tooltip/TextOverTooltip.vue +98 -98
  448. package/packages/scale-view/index.js +17 -17
  449. package/packages/scale-view/mixin/NoData.js +38 -38
  450. package/packages/scale-view/mixin/evaluate.js +146 -146
  451. package/packages/scale-view/mixin/index.js +337 -337
  452. package/packages/scale-view/mixin/judgeTypes.js +267 -267
  453. package/packages/scale-view/scaleView.vue +2010 -2010
  454. package/packages/select/index.js +27 -27
  455. package/packages/select/src/CustomSelect/index.vue +130 -130
  456. package/packages/select/src/OptGroup.jsx +11 -11
  457. package/packages/select/src/Option.jsx +11 -11
  458. package/packages/select/src/Select/Select.vue +231 -231
  459. package/packages/select/src/Select/index.js +12 -12
  460. package/packages/select/src/TableSelect/index.vue +514 -514
  461. package/packages/select-label/index.js +14 -14
  462. package/packages/select-label/label-classify.vue +129 -129
  463. package/packages/select-label/labelFormContent.vue +787 -787
  464. package/packages/select-label/select-label.vue +581 -581
  465. package/packages/select-person/index.js +10 -10
  466. package/packages/select-person/search-tree.vue +373 -373
  467. package/packages/select-person/select-person.vue +1696 -1696
  468. package/packages/shortcut-setter/index.js +12 -12
  469. package/packages/shortcut-setter/src/ShortcutSetter.vue +55 -55
  470. package/packages/shortcut-setter/src/ShortcutSetterItem.vue +84 -84
  471. package/packages/shortcut-setter/src/utils/index.js +63 -63
  472. package/packages/skeleton/index.js +12 -12
  473. package/packages/skeleton/src/Skeleton.jsx +11 -11
  474. package/packages/slider/index.js +12 -12
  475. package/packages/slider/src/Slider.jsx +11 -11
  476. package/packages/space/index.js +12 -12
  477. package/packages/space/src/Space.jsx +11 -11
  478. package/packages/spin/index.js +12 -12
  479. package/packages/spin/src/Spin.jsx +11 -11
  480. package/packages/statistic/index.js +18 -18
  481. package/packages/statistic/src/Countdown.jsx +11 -11
  482. package/packages/statistic/src/Statistic.jsx +11 -11
  483. package/packages/steps/index.js +18 -18
  484. package/packages/steps/src/Step.jsx +11 -11
  485. package/packages/steps/src/Steps.jsx +11 -11
  486. package/packages/switch/index.js +12 -12
  487. package/packages/switch/src/Switch.jsx +11 -11
  488. package/packages/table-filter/index.js +27 -27
  489. package/packages/table-filter/src/base-search-com/BaseSearch.vue +2572 -2572
  490. package/packages/table-filter/src/classification/Classification-com.vue +1756 -1756
  491. package/packages/table-filter/src/classification/search-class-name.vue +266 -266
  492. package/packages/table-filter/src/classification/search-professional-model.vue +680 -680
  493. package/packages/table-filter/src/components/TextOverTooltip.vue +107 -107
  494. package/packages/table-filter/src/components/age-com/index.vue +205 -205
  495. package/packages/table-filter/src/components/button-group/ButtonGroup.vue +162 -162
  496. package/packages/table-filter/src/components/button-icon/button-icon.js +33 -33
  497. package/packages/table-filter/src/components/button-icon/getBtnIcon.js +34 -34
  498. package/packages/table-filter/src/components/c-tree-select/tree-select.vue +336 -336
  499. package/packages/table-filter/src/components/drop-button/drop-button.vue +224 -224
  500. package/packages/table-filter/src/components/drop-button/head-btn-icon.js +33 -33
  501. package/packages/table-filter/src/components/drop-view/drop-view.vue +89 -89
  502. package/packages/table-filter/src/components/multi-select/multi-select.vue +227 -227
  503. package/packages/table-filter/src/components/out-quick-search/out-quick-search.vue +340 -340
  504. package/packages/table-filter/src/components/range-age/index.vue +172 -172
  505. package/packages/table-filter/src/components/search-condition/SearchCondition.vue +1897 -1897
  506. package/packages/table-filter/src/components/search-condition/fieldTypeList.js +169 -169
  507. package/packages/table-filter/src/components/search-filter/SearchFilter.vue +278 -278
  508. package/packages/table-filter/src/components/search-modal/set-classification.vue +310 -310
  509. package/packages/table-filter/src/components/table-modal/TableModal.vue +473 -463
  510. package/packages/table-filter/src/const/dataOptions.js +43 -43
  511. package/packages/table-filter/src/const/index.js +1 -1
  512. package/packages/table-filter/src/index.vue +584 -584
  513. package/packages/table-filter/src/mixins/mixins.js +694 -694
  514. package/packages/table-filter/src/mixins/tableSearchCon.js +128 -128
  515. package/packages/table-filter/src/mixins/wordBookutils.js +102 -102
  516. package/packages/table-filter/src/quick-search/QuickSearch.vue +2125 -2125
  517. package/packages/tabs/index.js +18 -18
  518. package/packages/tabs/src/TabPane.jsx +11 -11
  519. package/packages/tabs/src/Tabs.jsx +11 -11
  520. package/packages/tag/index.js +21 -21
  521. package/packages/tag/src/CheckableTag.jsx +11 -11
  522. package/packages/tag/src/Tag.jsx +11 -11
  523. package/packages/tag/src/TagGroup.vue +621 -621
  524. package/packages/time-picker/index.js +12 -12
  525. package/packages/time-picker/src/TimePicker.jsx +11 -11
  526. package/packages/timeline/index.js +14 -14
  527. package/packages/timeline/src/Item.jsx +11 -11
  528. package/packages/timeline/src/Timeline.jsx +11 -11
  529. package/packages/tooltip/index.js +12 -12
  530. package/packages/tooltip/src/Tooltip.jsx +11 -11
  531. package/packages/transfer/index.js +12 -12
  532. package/packages/transfer/src/Transfer.jsx +11 -11
  533. package/packages/tree/index.js +18 -18
  534. package/packages/tree/src/Tree.jsx +11 -11
  535. package/packages/tree/src/TreeNode.jsx +11 -11
  536. package/packages/tree-select/index.js +18 -18
  537. package/packages/tree-select/src/TreeNode.jsx +11 -11
  538. package/packages/tree-select/src/TreeSelect.jsx +11 -11
  539. package/packages/upload/chunk-upload/chunk-upload-new.vue +1001 -1001
  540. package/packages/upload/chunk-upload/vod-chunk-upload.vue +749 -749
  541. package/packages/upload/chunk-upload/vod-upload-modal.vue +100 -100
  542. package/packages/upload/index.js +12 -12
  543. package/packages/upload/src/Upload.jsx +11 -11
  544. package/packages/verification-code/SlideVerify.vue +306 -306
  545. package/packages/verification-code/index.js +17 -17
  546. package/packages/verification-code/verification-code.vue +147 -147
  547. package/src/component/player-vod/index.vue +57 -57
  548. package/src/component/player-vod/player.vue +188 -188
  549. package/src/component/player-vod/video-list.vue +262 -262
  550. package/src/component/player-vod/video-modal.vue +128 -128
  551. package/src/component/select-options/index.vue +430 -413
  552. package/src/component/select-pages/index.vue +95 -95
  553. package/src/component/svg/index.vue +59 -59
  554. package/src/core/create.js +6 -6
  555. package/src/core/event.js +23 -23
  556. package/src/core/table-methods.js +444 -444
  557. package/src/directive/flexibleResize.js +151 -151
  558. package/src/directive/preventReClick.js +12 -12
  559. package/src/directive/scroll.js +230 -230
  560. package/src/global/variable.js +2 -2
  561. package/src/style/normalize.css +424 -424
  562. package/src/style/style.less +49 -49
  563. package/src/utils/UniRTCv2.js +626 -626
  564. package/src/utils/chatFetch.js +61 -61
  565. package/src/utils/clickoutside.js +75 -75
  566. package/src/utils/crypto.js +25 -25
  567. package/src/utils/index.js +81 -81
  568. package/src/utils/kty-sdk.js +582 -582
  569. package/src/utils/kty.min-1.0.0.js +14378 -14378
  570. package/src/utils/sip-device.js +79 -79
  571. package/src/utils/time-domain.js +193 -193
  572. package/src/utils/trtc.js +1 -1
  573. package/src/utils/utils-map.js +484 -484
  574. package/src/utils/vexutils.js +836 -836
@@ -1,2010 +1,2010 @@
1
- <template>
2
- <div class="r-scale">
3
- <slot v-if="spinning">
4
- <a-spin :indicator="indicator" tip="加载中..." />
5
- </slot>
6
- <slot v-if="!spinning && !hasFrontAddress">
7
- <!-- <div v-if="noData">暂无数据</div> -->
8
- <NoData v-if="noData" :noDataImg="noDataImg" :noDataTip="noDataTip"></NoData>
9
- <template v-else>
10
- <evaluatePage
11
- v-if="showEvaluateEntry"
12
- :formArray="formArray"
13
- :evaluateResultConfig="config.evaluateResultConfig"
14
- :evaluateResultSetting="config.evaluateResultSetting"
15
- :isFinished="isFinished"
16
- :maxScore="maxScore"
17
- @writeGuage="writeGuage"
18
- ></evaluatePage>
19
- <template v-else>
20
- <evaluateCountdown
21
- v-if="showEvaluateCoundownPage"
22
- ref="evaluateCountdown"
23
- :formArray="formArray"
24
- :evaluateResultConfig="config.evaluateResultConfig"
25
- :evaluateResultSetting="config.evaluateResultSetting"
26
- :form="form"
27
- :isFinished="isFinished"
28
- :currentTime="currentTime"
29
- :showEvaluateCountdown="showEvaluateCountdown"
30
- @closeEvaluateCountdown="closeEvaluateCountdown"
31
- ></evaluateCountdown>
32
- <div
33
- class="scale-container"
34
- :class="{ 'scale-container-nopadding': handlePageClass }"
35
- :style="scaleStyle"
36
- >
37
- <div class="totalScore-warp" v-if="hasScore">
38
- <div>
39
- 测评总分:
40
- <span>{{ maxScore }}分</span>
41
- </div>
42
- <div>
43
- 测评分数:
44
- <span :style="{ color: getEvaResColor }">{{ config.totalScore }}分</span>
45
- </div>
46
- <template v-if="hasEvaluateSetting">
47
- <div>
48
- 测评结果:
49
- <span
50
- class="score-result"
51
- :style="{ color: getEvaResColor }"
52
- >{{ config.evaluateResult }}</span>
53
- </div>
54
- <div>
55
- 结果说明:
56
- <span>{{ config.evaluateResultExplain }}</span>
57
- </div>
58
- </template>
59
- </div>
60
- <a-form-model
61
- ref="ruleForm"
62
- :model="form"
63
- :rules="rules"
64
- :layout="form.layout"
65
- :colon="false"
66
- class="main"
67
- >
68
- <template v-for="(item, index) in formArray">
69
- <!-- 标题 -->
70
- <template v-if="item.type == 'TITLE'">
71
- <a-form-model-item
72
- v-if="isShowItem(item)"
73
- :colon="false"
74
- :key="item.id || item.seq"
75
- >
76
- <h1 class="lb-title">{{ item.title }}</h1>
77
- <div class="lb-title">{{ item.describe }}</div>
78
- </a-form-model-item>
79
- </template>
80
- <!-- 分线栏 -->
81
- <template v-else-if="item.type == 'LINEBAR'">
82
- <a-form-model-item
83
- v-if="isShowItem(item)"
84
- :colon="false"
85
- :key="item.id || item.seq"
86
- >
87
- <div class="linebar-div" v-if="item.title">
88
- <span>{{ item.title }}</span>
89
- <a-divider />
90
- </div>
91
- <template v-else>
92
- <a-divider />
93
- </template>
94
- </a-form-model-item>
95
- </template>
96
- <!-- 提示语 -->
97
- <template v-else-if="item.type == 'PROMPT'">
98
- <a-form-model-item
99
- v-if="isShowItem(item)"
100
- class="my-prompt"
101
- :colon="false"
102
- :key="item.id || item.seq"
103
- >
104
- <MyPrompt :key="item.id || item.seq" :options="item.setting" />
105
- </a-form-model-item>
106
- </template>
107
- <template v-else-if="item.type == 'IMGCARD'">
108
- <a-form-model-item
109
- v-if="isShowItem(item)"
110
- :colon="false"
111
- :key="item.id || item.seq"
112
- >
113
- <a v-if="item.setting.imgLink" :href="item.setting.imgLink" target="_blank">
114
- <img class="img-card" :src="item.setting.imgUrl" />
115
- </a>
116
- <img class="img-card" v-else :src="item.setting.imgUrl" />
117
- </a-form-model-item>
118
- </template>
119
- <!-- 富文本 -->
120
- <template v-else-if="item.type == 'RICH_TEXT'">
121
- <div
122
- :key="item.id || item.seq"
123
- class="rich-text-content"
124
- v-html="item.setting.defaultValue"
125
- ></div>
126
- </template>
127
- <template v-else>
128
- <a-form-model-item
129
- v-if="isShowItem(item)"
130
- :key="item.id || item.seq"
131
- :prop="formKey(item)"
132
- >
133
- <span slot="label">
134
- <span
135
- :class="{ 'scale-label-required': isFormBoldOpen(item) }"
136
- v-html="handleShowQuestionNumber(item)"
137
- ></span>
138
- <span class="required-text" v-if="isFormBoldOpen(item)">(必填)</span>
139
- <span
140
- class="evalute-label"
141
- v-if="showEvaluateLabel(item)"
142
- >{{ showEvaluateLabel(item) }}</span>
143
- <template v-if="showEvatip(item)">
144
- <span class="evalute-tip" @click="showEvaTipModal(item)">
145
- <svg-icon icon-class="a-xitongtubiaotishi" />查看提示
146
- </span>
147
- </template>
148
- </span>
149
- <!-- 输入框 -->
150
- <MyInput
151
- v-bind="$attrs"
152
- v-if="isInput(item.type)"
153
- v-model="form[formKey(item)]"
154
- :type="item.valueType"
155
- :row="item.setting.inputRow || 1"
156
- :defaultPlaceHolder="item.setting.defaultPlaceHolder"
157
- :isLock="componentDisable"
158
- />
159
-
160
- <!-- 单选/下拉/多选/级联 -->
161
- <MyChoice
162
- v-bind="$attrs"
163
- v-else-if="isChoice(item.type)"
164
- v-model="form[formKey(item)]"
165
- :item="item"
166
- :isLock="componentDisable"
167
- :curIndex="index"
168
- :openType="openType"
169
- @change="handleChoice($event, item)"
170
- @radioChange="radioChange"
171
- @checkboxChange="checkboxChange"
172
- />
173
- <!-- 日期/时间 -->
174
- <MyTime
175
- v-bind="$attrs"
176
- v-else-if="isTime(item.type)"
177
- :value="getTimeValue(item)"
178
- :type="item.type"
179
- :startToStop="item.setting.startToStop"
180
- :dateType="item.setting.dateType"
181
- :isLock="componentDisable"
182
- @change="changeTime($event, item)"
183
- />
184
- <!-- 上传附件 or 图片 -->
185
- <MyUpload
186
- v-bind="$attrs"
187
- v-else-if="isUpload(item.type)"
188
- :upType="item.type"
189
- :useFileList="item.dbValue"
190
- :limitPic="item.setting.limitPic"
191
- :isLock="componentDisable"
192
- @change="changeUpload($event, item)"
193
- />
194
- <!-- 地图 -->
195
- <div
196
- v-else-if="item.type === 'LOCATION'"
197
- @click="!isLock && (mapVisible = !mapVisible)"
198
- :class="{ 'map-container': !isLock }"
199
- >
200
- <a-input
201
- placeholder="请选择"
202
- :value="handleGetAddress(form[formKey(item)])"
203
- disabled
204
- >
205
- <a-icon slot="prefix" type="info-circle" />
206
- </a-input>
207
- <MapComp
208
- v-bind="$attrs"
209
- :visible.sync="mapVisible"
210
- :locationProp="form[formKey(item)]"
211
- :isLock="componentDisable"
212
- @selectLocation="handleSelectLocation($event, item)"
213
- />
214
- </div>
215
- <!-- 地址 -->
216
- <MyAddress
217
- v-bind="$attrs"
218
- v-else-if="item.type === 'ADDRESS'"
219
- :setting="item.setting"
220
- :defaultValue="defaultAddress"
221
- :isLock="componentDisable"
222
- @change="changeAddress($event, item)"
223
- />
224
- <!-- 标签 -->
225
- <label-form
226
- v-bind="$attrs"
227
- v-else-if="item.type === 'LABEL'"
228
- :item="item"
229
- :selectedList="labelSelectedList"
230
- :isLock="componentDisable"
231
- :sourceType="source"
232
- @onChange="labelChange($event, item)"
233
- />
234
- <!-- 视频 -->
235
- <vod-Chunk-upload
236
- v-bind="$attrs"
237
- v-else-if="item.type === 'VEDIO'"
238
- :source="'guage'"
239
- :formData="item"
240
- :limitNum="item.setting.limitPic"
241
- :defFileList="form[formKey(item)]"
242
- :isLock="componentDisable"
243
- @vodFileList="vodFileList($event, item)"
244
- />
245
- <!-- 答案解析 -->
246
- <answerParse v-if="showAnswerParse(item)" :item="item"></answerParse>
247
- </a-form-model-item>
248
- </template>
249
- </template>
250
- </a-form-model>
251
- </div>
252
- <template v-if="type === 'customList'">
253
- <div class="footer" v-if="!noBtn">
254
- <a-button @click="cancel" v-if="false" style="margin-right: 8px;">取消</a-button>
255
- <a-button @click="onSubmit" type="primary" :disabled="banSubmit">保存</a-button>
256
- </div>
257
- </template>
258
- <template v-else>
259
- <div class="footer" v-if="showSaveBtn">
260
- <a-button @click="cancel" style="margin-right: 8px;">取消</a-button>
261
- <a-button type="primary" v-if="!isLock" @click="onSubmit" :disabled="banSubmit">保存</a-button>
262
- </div>
263
- </template>
264
- </template>
265
- </template>
266
- </slot>
267
- </div>
268
- </template>
269
- <script>
270
- import { Icon, Checkbox, Tree, Tooltip, Input, Spin, FormModel, Divider, Button } from 'ant-design-vue';
271
- import create from '@/core/create';
272
- import { MyChoice, MyInput, MyAddress, MyUpload, MyTime, MyPrompt } from './formitem';
273
- import MapComp from '../map/src/popup-map';
274
- import labelForm from '~/select-label/select-label';
275
- import vodChunkUpload from '~/upload/chunk-upload/vod-chunk-upload.vue';
276
- // import { EventBus } from "@/common/utils/eventBus.js";
277
- import { judgeTypes } from './mixin/judgeTypes';
278
- import NoDataJs from './mixin/NoData';
279
- // import { mapGetters } from "vuex";
280
- import moment from 'moment';
281
- import utils from '@/utils/utils-map';
282
- import evaluatePage from './evaluatePage.vue';
283
- import evaluateCountdown from './evaluateCountdown.vue';
284
- import answerParse from './answerParse.vue';
285
- import vexutils from '@/utils/vexutils';
286
- import NoData from './NoData.vue';
287
- export default create({
288
- name: 'scale-view',
289
- mixins: [judgeTypes, NoDataJs],
290
- props: {
291
- ids: {
292
- type: Object,
293
- default: () => {
294
- return { guage_id: '', db_id: undefined };
295
- }
296
- },
297
- params: { default: () => ({}), type: Object },
298
- guageData: { type: Object, default: () => ({}) },
299
- noBtn: { type: Boolean, default: false },
300
- hideBtn: { type: Boolean, default: false },
301
- source: { type: String, default: '' },
302
- isLock: { type: Boolean, default: false },
303
- type: {
304
- type: String,
305
- default: ''
306
- },
307
- styleSetting: {
308
- type: Object,
309
- default: () => ({})
310
- },
311
-
312
- fontSizeObj: {
313
- type: Object,
314
- default: () => ({
315
- large: 1.25,
316
- medium: 1.1,
317
- small: 1,
318
- extrasmall: 0.9
319
- })
320
- },
321
- openType: { type: String, default: '' },
322
- scaleApiConfig: {
323
- type: Object,
324
- default: () => ({})
325
- }
326
- },
327
- components: {
328
- MyChoice,
329
- MyInput,
330
- MapComp,
331
- MyAddress,
332
- MyUpload,
333
- MyTime,
334
- MyPrompt,
335
- labelForm,
336
- vodChunkUpload,
337
- [Icon.name]: Icon,
338
- [Spin.name]: Spin,
339
- [Tree.name]: Tree,
340
- [Input.name]: Input,
341
- [Input.Search.name]: Input.Search,
342
- [Checkbox.name]: Checkbox,
343
- [Divider.name]: Divider,
344
- [Button.name]: Button,
345
- [FormModel.name]: FormModel,
346
- [FormModel.Item.name]: FormModel.Item,
347
- [Tooltip.name]: Tooltip,
348
- evaluatePage,
349
- evaluateCountdown,
350
- answerParse,
351
- NoData
352
- },
353
- computed: {
354
- queryformBoldOpen() {
355
- return this.$route.query?.formBoldOpen == 1;
356
- },
357
- showEvatip() {
358
- return function (item) {
359
- if (!this.isEvaluation(item.type)) return false;
360
- return this.$route.query?.evatip == 1 || this.params?.evatip == 1;
361
- };
362
- },
363
- isFormBoldOpen() {
364
- return function (item) {
365
- let res = item.required;
366
- // 量表未登录时 判断 url中是否有 formBoldOpen
367
- if (!this.styleSetting || !Object.keys(this.styleSetting).length || !('formBoldOpen' in this.styleSetting)) {
368
- return res && this.queryformBoldOpen;
369
- }
370
- return res && this.styleSetting.formBoldOpen;
371
- };
372
- },
373
- scaleStyle() {
374
- let fontSize = this.fontSize;
375
- if (!fontSize || fontSize === 'S') return null;
376
- const keyValue = {
377
- L: 'large',
378
- M: 'medium',
379
- XS: 'extrasmall'
380
- };
381
- fontSize = keyValue[fontSize];
382
- const scale = (fontSize && this.fontSizeObj[fontSize]) || 1;
383
- const size = 10000;
384
- const value = Math.floor((100 / scale) * size) / size;
385
- return {
386
- width: `${value}%`,
387
- height: `${value}%`,
388
- transform: `scale(${scale})`
389
- };
390
- },
391
- handlePageClass() {
392
- if (this.type == 'customList' && !this.noBtn) return false;
393
- if (!this.noBtn && !this.hideBtn) return false;
394
- return true;
395
- },
396
- isShowItem() {
397
- return item => this.showEvent(item);
398
- },
399
- handleShowQuestionNumber() {
400
- return function (item) {
401
- let { type } = item || {};
402
- let tempTile = this.config?.autoQuestionNumber === false ? item.showTitle : `${item.softcode}、${item.showTitle}`;
403
- if (!this.isEvaluation(type)) return tempTile;
404
-
405
- let score = this.handleEvaluationScore(item);
406
- return `${tempTile}&nbsp;<span style="color:#2d7aff;">${score}</span>`;
407
- // if (this.noBtn) {
408
- // let score = this.handleEvaluationScore(item);
409
- // return `${tempTile}&nbsp;<span style="color:#2d7aff;">${score}</span>`;
410
- // }
411
- // if (!this.isLock) {
412
- // let score = this.handleEvaluationScore(item);
413
- // return `${tempTile}&nbsp;<span style="color:#2d7aff;">${score}</span>`;
414
- // }
415
- // if (item.questionScore !== undefined) {
416
- // return `${tempTile}&nbsp;<span style="color:#2d7aff;">(${item.questionScore}分)</span>`;
417
- // }
418
- // return tempTile;
419
- };
420
- },
421
- hasScore() {
422
- let { config } = this;
423
- if (!config || !Object.keys(config).length) return false;
424
- if ('totalScore' in config) return true;
425
- return false;
426
- },
427
- // 预览按钮打开的量表页面
428
- isPreviewScale() {
429
- let guage_id = this.ids?.guage_id;
430
- return guage_id && this.noBtn;
431
- },
432
- hasEvaluateSetting() {
433
- let { config } = this;
434
- if (!config || !Object.keys(config).length) return false;
435
- if ('evaluateResult' in config && config.evaluateResult) return true;
436
- return false;
437
- },
438
- getTimeValue() {
439
- return function (item) {
440
- let value = this.form[this.formKey(item)];
441
- return value;
442
- };
443
- },
444
- // 是否展示考试入口
445
- showEvaluateEntry() {
446
- // 非预览
447
- // 有evaluateResultSetting || url中含有固定参数
448
- // 倒计时未结束
449
- // 未填写过
450
- return !this.isPreviewScale && this.showEvaluatePage && this.showEvaluateSettingWrap && !this.isFinished && !this.noBtn && !this.hideBtn;
451
- },
452
- // 是否展示倒计时
453
- showEvaluateCoundownPage() {
454
- return !this.isPreviewScale && !this.showEvaluateEntry && this.showEvaluateCountdownWrap && !this.isFinished && !this.noBtn && !this.hideBtn;
455
- },
456
- // 是否设置 evaluateResultSetting
457
- hasEvaluateResultSetting() {
458
- let { evaluateResultSetting = {} } = this.config;
459
- // 读取优先级为测评设置值(变量) > URL参数 > 测评设置值(固定值)
460
- // 是否设置 evaluateResultSetting
461
- let valueArr =
462
- Object.values(evaluateResultSetting).filter(item => {
463
- if (item) return true;
464
- }) || [];
465
- return valueArr.length;
466
- },
467
- hasparamsEvaluate() {
468
- return this.paramsEvaluate && Object.keys(this.paramsEvaluate).length;
469
- },
470
- // url中是否有默认值
471
- hasDefault() {
472
- let hash = window.location.hash;
473
- let defaultVariable = ['evaname', 'evadesc', 'evast', 'evadur', 'evaan'];
474
- let hasDefault = defaultVariable.find(item => hash.includes(item));
475
- return this.paramsEvaluate || hasDefault;
476
- },
477
- // 是否有提交按钮
478
- showSaveBtn() {
479
- // 无测评设置 && url中无固定参数
480
- if (!this.hasEvaluateResultSetting && !this.hasDefault) {
481
- return !this.noBtn && !this.hideBtn;
482
- }
483
- return !this.noBtn && !this.hideBtn && !this.isFinished;
484
- },
485
- // 组件是否 Disable
486
- componentDisable() {
487
- // 无测评设置 && url中无固定参数
488
- if (!this.hasEvaluateResultSetting && !this.hasDefault) {
489
- return this.hideBtn || this.isLock;
490
- }
491
- return this.hideBtn || this.isLock || this.isFinished;
492
- },
493
- showEvaluateLabel() {
494
- return function (item) {
495
- let obj = {
496
- EVALUATE_RADIO_BLOCK: '单选题',
497
- EVALUATE_CHECKBOX_BLOCK: '多选题'
498
- };
499
- return obj[item.type];
500
- };
501
- },
502
- showAnswerParse() {
503
- return function (item) {
504
- let { evaluateAnswer, checkAnswerMode, evaluateStartTime, evaluateTime } = this.config?.evaluateResultSetting || {};
505
- let arr = ['EVALUATE_RADIO_BLOCK', 'EVALUATE_CHECKBOX_BLOCK', 'EVALUATE_SELECT', 'EVALUATE_INPUT'];
506
- let maxScore = item?.scoreConfigs || 0;
507
- let isShow = evaluateAnswer && this.isFinished && arr.includes(item.type) && maxScore;
508
- if (!evaluateStartTime || !evaluateTime || (checkAnswerMode && checkAnswerMode == 1)) return isShow;
509
- if (!vexutils.isValidDate(new Date(evaluateStartTime))) return isShow;
510
- // 答案解析时间 考试时间结束后
511
- let endTime = moment(evaluateStartTime).add(evaluateTime, 'minutes');
512
- let isRang = endTime.diff(moment(), 'seconds', true);
513
- return isShow && isRang <= 0;
514
- };
515
- },
516
- tipMsg() {
517
- return this.type === 'customList' ? '保存' : '提交';
518
- },
519
- formKey() {
520
- return function (item) {
521
- return item.databaseTitle || item.title;
522
- };
523
- },
524
- getEvaResColor() {
525
- let { evaluateResultConfig = [], totalScore } = this.config || {};
526
- totalScore = +totalScore || 0;
527
- if (!evaluateResultConfig?.length || !totalScore) return '#2474FF';
528
- let matchItem = evaluateResultConfig.find(item => item.startScore <= totalScore && totalScore <= item.endScore);
529
- if (!matchItem) return '#2474FF';
530
- return matchItem.color || '#2474FF';
531
- }
532
- },
533
- watch: {
534
- ids: {
535
- immediate: true,
536
- deep: true,
537
- handler(newVal, oldVal) {
538
- if (oldVal) {
539
- if (newVal.guage_id) {
540
- if (newVal.guage_id != oldVal.guage_id) {
541
- this.init(newVal);
542
- }
543
- }
544
- } else {
545
- if (newVal.guage_id) this.init(newVal);
546
- }
547
- }
548
- },
549
- guageData: {
550
- immediate: true,
551
- deep: true,
552
- handler(value) {
553
- if (value) {
554
- if (Object.keys(value || {}).length) {
555
- // guageForm打开 重新请求重置之前的答案
556
- this.form = {};
557
- this.formArray = [];
558
- const data = JSON.parse(JSON.stringify(value));
559
- this.$nextTick(() => {
560
- this.initForm(data);
561
- });
562
- }
563
- }
564
- }
565
- }
566
- },
567
- data() {
568
- return {
569
- other: '',
570
- form: {},
571
- submitForm: {},
572
- rules: {},
573
- config: {},
574
- formArray: [],
575
- mapVisible: false,
576
- mapLocation: '',
577
- labelSelectedList: [],
578
- defaultFormArray: [],
579
- fontSize: '',
580
- filterArr: ['SUCCESS_TIP', 'CALLBACK_INTERFACE', 'SPREAD_PARAMS', 'REDIRECT', 'FRONT_ADDRESS', 'RETURN_PATH'],
581
- spinning: true,
582
- indicator: <a-icon type="loading" style="font-size: 24px" spin />,
583
- totalScore: undefined,
584
- shareId: '',
585
- currentTime: moment(),
586
- showEvaluatePage: false,
587
- showEvaluateSettingWrap: true,
588
- showEvaluateCountdownWrap: false,
589
- showEvaluateCountdown: false,
590
- banSubmit: false,
591
- isFinished: false,
592
- maxScore: 0,
593
- originConfig: {},
594
- paramsEvaluate: null,
595
- hasFrontAddress: true,
596
- choiceComObj: {},
597
- evatipMap: {} // 维护一个tip map避免重复请求
598
- };
599
- },
600
- mounted() {
601
- this.handleQuery();
602
- if (this.noBtn) {
603
- // EventBus.$on("guageSubmit", this.onSubmit);
604
- }
605
- },
606
- beforeDestroy() {
607
- // EventBus.$off("guageSubmit");
608
- },
609
- methods: {
610
- init(configData) {
611
- this.spinning = true;
612
- try {
613
- this.resetNodata();
614
- this.initForm(configData);
615
- } catch (error) {
616
- this.spinning = false;
617
- this.hasFrontAddress = false;
618
- this.setNoData(true, error?.resultMsg, error?.result);
619
- }
620
- },
621
- handleQuery() {
622
- let { id } = this.$route.query;
623
- id && (this.shareId = id);
624
- },
625
- initForm(data) {
626
- let { list = [], map = {}, isFinished = false } = data;
627
- let curUrl = this.handleFrontAddress(list);
628
- if (curUrl) {
629
- window.location.href = curUrl;
630
- return;
631
- }
632
- map.maxScore && (this.maxScore = map.maxScore);
633
- this.isFinished = isFinished;
634
- if (data.isNotFilled) {
635
- this.spinning = false;
636
- this.hasFrontAddress = false;
637
- this.setNoData(true, '未查询到量表填写记录');
638
- return;
639
- }
640
- if (data.isLackCustomer) {
641
- let _this = this;
642
- // 校验用户环境
643
- this.$info({
644
- title: '已设置填写次数限制',
645
- content: '请在包含用户信息的环境中打开此量表',
646
- onOk() {
647
- _this.$emit('onCloseSetting');
648
- }
649
- });
650
- }
651
- this.config = map;
652
-
653
- if ('evaluateResultConfig' in map && utils.isJSON(map.evaluateResultConfig)) {
654
- this.config.evaluateResultConfig = JSON.parse(map.evaluateResultConfig);
655
- }
656
- if ('evaluateResultSetting' in map && utils.isJSON(map.evaluateResultSetting)) {
657
- this.config.evaluateResultSetting = JSON.parse(map.evaluateResultSetting);
658
- // 随机测评
659
- if (this.config?.randomId && this.config.evaluateResultSetting) {
660
- this.config.evaluateResultSetting.evaluateName = this.config.name;
661
- this.config.evaluateResultSetting.evaluateExplain = this.config.remark;
662
- }
663
- }
664
-
665
- this.originConfig = JSON.parse(JSON.stringify(this.config));
666
-
667
- if (this.params && Object.keys(this.params).length) {
668
- let res = this.handleBtnParamsEvaluate(this.params);
669
- res && Object.keys(res).length && (this.paramsEvaluate = res);
670
- }
671
-
672
- this.handleEvaluateParams(this.config.evaluateResultSetting);
673
- this.handleShowEvaluate();
674
-
675
- this.defaultFormArray = JSON.parse(JSON.stringify(list));
676
- let filterArr = this.filterArr;
677
- list = list.filter(v => !filterArr.includes(v.type));
678
- this.formArray = this.formatArray(list || []);
679
- this.form = this.defaultFormValue(this.formArray);
680
- this.rules = this.formatRules(this.formArray);
681
- this.fontSize = data.fontSize;
682
- this.spinning = false;
683
- this.hasFrontAddress = false;
684
- },
685
- handleFrontAddress(list) {
686
- if (!list || !list.length) return;
687
- let matchItem = list.find(item => item.type === 'FRONT_ADDRESS');
688
- if (!matchItem || !Object.keys(matchItem).length) return;
689
- let setting;
690
- if (matchItem.setting && utils.isJSON(matchItem.setting)) {
691
- setting = JSON.parse(matchItem.setting);
692
- }
693
- if (!setting || !Object.keys(setting).length) return;
694
- let query = this.handleQueryParams();
695
- // redirect=1 代表从前置地址跳转回来了
696
- if (query?.redirect == 1) return;
697
- let { frontAddress } = setting;
698
- if (frontAddress) {
699
- let urlHref = window.location.href;
700
- let preStr = '?';
701
- if (frontAddress.includes('?')) {
702
- preStr = '&';
703
- }
704
- let curUrl = `${frontAddress}${preStr}redirect_url=${encodeURIComponent(urlHref)}`;
705
- return curUrl;
706
- }
707
- },
708
- handleBtnParamsEvaluate(params) {
709
- let defaultVariable = ['evaname', 'evadesc', 'evast', 'evadur', 'evaan'];
710
- let res = {};
711
- for (let key in params) {
712
- let value = params[key];
713
- if (defaultVariable.includes(key) && value) {
714
- res[key] = value;
715
- }
716
- }
717
- return res;
718
- },
719
- /** *
720
- * 解析测评参数
721
- */
722
- handleEvaluateParams(evaluateResultSetting) {
723
- if (!evaluateResultSetting || !Object.keys(evaluateResultSetting).length) return;
724
- // 分享测评量表链接URL支持传入测评名称-evaname 测评说明-evadesc 测评时间-evast 测评时长-evadur 固定参数
725
- let query = this.handleQueryParams();
726
- // 按钮传参
727
- if (this.hasparamsEvaluate) {
728
- query = this.paramsEvaluate;
729
- }
730
- let obj = {
731
- evaluateName: 'evaname',
732
- evaluateExplain: 'evadesc',
733
- evaluateStartTime: 'evast',
734
- evaluateTime: 'evadur',
735
- evaluateAnswer: 'evaan'
736
- };
737
- for (let key in evaluateResultSetting) {
738
- let value = evaluateResultSetting[key];
739
- let isParseKey = value && key != 'evaluateAnswer' && typeof value === 'string' && value.includes('${');
740
- if (isParseKey) {
741
- let parseValue = value.replace(/\$\{([^}]+)\}/g, (_v, $1) => {
742
- let param;
743
- if ($1.startsWith('form.')) {
744
- param = query[$1.split('.')[1]];
745
- }
746
- return param || '';
747
- });
748
- this.$set(evaluateResultSetting, key, parseValue);
749
- } else {
750
- let val = query[obj[key]];
751
- if (key == 'evaluateAnswer') {
752
- val = val === 'true' || val == 1 ? true : false;
753
- }
754
- query[obj[key]] && this.$set(evaluateResultSetting, key, val);
755
- }
756
- }
757
- // 部分evaluateResultSetting 但是却有url
758
- if (this.hasDefault) {
759
- let defaultVariable = ['evaname', 'evadesc', 'evast', 'evadur', 'evaan'];
760
- let defObj = {
761
- evaname: 'evaluateName',
762
- evadesc: 'evaluateExplain',
763
- evast: 'evaluateStartTime',
764
- evadur: 'evaluateTime',
765
- evaan: 'evaluateAnswer'
766
- };
767
- defaultVariable.forEach(item => {
768
- let key = defObj[item];
769
- if (!evaluateResultSetting[key]) {
770
- let val = query[item];
771
- if (item == 'evaan') {
772
- val = val === 'true' || val == 1 ? true : false;
773
- }
774
- query[item] && this.$set(evaluateResultSetting, key, val);
775
- }
776
- });
777
- }
778
- this.setEvaluateStartTime(evaluateResultSetting);
779
- },
780
- handleQueryParams() {
781
- let params = {};
782
- for (let [key, value] of new URLSearchParams(window.location.hash.split('?')[1]).entries()) {
783
- params[key] = decodeURIComponent(value);
784
- }
785
- return params;
786
- },
787
- handleShowEvaluate() {
788
- // 读取优先级为测评设置值(变量) > URL参数 > 测评设置值(固定值)
789
- // 无 evaluateResultSetting
790
- if (!this.hasEvaluateResultSetting) {
791
- // url中是否有默认值
792
- // 无默认值 不显示考试入口页面
793
- if (!this.hasDefault) return false;
794
- // 有默认值 显示考试入口页面
795
- if (!('evaluateResultSetting' in this.config)) {
796
- this.$set(this.config, 'evaluateResultSetting', {});
797
- }
798
- this.setDefaultEvaluate(this.config.evaluateResultSetting);
799
- this.showEvaluatePage = true;
800
- this.showEvaluateCountdownWrap = true;
801
- return;
802
- }
803
-
804
- let { evaluateResultSetting = {} } = this.config;
805
- if (!evaluateResultSetting || !Object.keys(evaluateResultSetting).length) return;
806
- this.showEvaluateCountdownWrap = true;
807
-
808
- // 只要有开始时间都显示测评组件
809
- let { evaluateStartTime } = evaluateResultSetting;
810
- let { evaluateName } = this.originConfig?.evaluateResultSetting || {};
811
- // 未设置开始时间 一直可以填写
812
- if (!evaluateStartTime) {
813
- this.showEvaluatePage = true;
814
- return;
815
- }
816
- if (!vexutils.isValidDate(new Date(evaluateStartTime))) {
817
- if (!evaluateName) return false;
818
- }
819
- this.showEvaluatePage = true;
820
- },
821
- setDefaultEvaluate(evaluateResultSetting) {
822
- let query = this.handleQueryParams();
823
- // 按钮传参
824
- if (this.hasparamsEvaluate) {
825
- query = this.paramsEvaluate;
826
- }
827
- if (query.evaname) {
828
- this.$set(evaluateResultSetting, 'evaluateName', query.evaname);
829
- }
830
- if (query.evadesc) {
831
- this.$set(evaluateResultSetting, 'evaluateExplain', query.evadesc);
832
- }
833
- if (query.evast) {
834
- this.$set(evaluateResultSetting, 'evaluateStartTime', query.evast);
835
- }
836
- if (query.evadur) {
837
- this.$set(evaluateResultSetting, 'evaluateTime', query.evadur);
838
- }
839
- if (query.evaan) {
840
- let evaan = query.evaan === 'true' || query.evaan == 1 ? true : false;
841
- this.$set(evaluateResultSetting, 'evaluateAnswer', evaan);
842
- }
843
-
844
- this.setEvaluateStartTime(evaluateResultSetting);
845
- },
846
- // 时间戳需要是数字
847
- setEvaluateStartTime(evaluateResultSetting) {
848
- let evaluateStartTime = evaluateResultSetting?.evaluateStartTime;
849
- if (!evaluateStartTime) return;
850
- if (!vexutils.isValidDate(new Date(evaluateStartTime)) && vexutils.isValidDate(new Date(Number(evaluateStartTime)))) {
851
- evaluateResultSetting.evaluateStartTime = Number(evaluateStartTime);
852
- }
853
- },
854
- // 量表提交数据
855
- defaultFormValue(formArray) {
856
- const formData = {};
857
- let val;
858
- formArray.forEach(item => {
859
- const key = this.formKey(item);
860
- const { type } = item;
861
- let defValue;
862
- if (item.dbValue) {
863
- defValue = item.dbValue;
864
- } else {
865
- if (item.setting?.defValType == 3) {
866
- let urlKey = item.setting?.outDefaultValue?.urlKey;
867
- if (urlKey) {
868
- let list = urlKey.split(',');
869
- if (list.length > 1) {
870
- let val = list
871
- .map(l => {
872
- let tempV = this.getQueryVariable(l);
873
- if (tempV) return decodeURIComponent(tempV);
874
- return null;
875
- })
876
- .filter(Boolean);
877
- val.length && (defValue = val);
878
- } else {
879
- let val = this.getQueryVariable(list[0]);
880
- if (val) {
881
- val = decodeURIComponent(val);
882
- defValue = item.type == 'CHECKBOX_BLOCK' ? val.split() : val;
883
- }
884
- }
885
- }
886
- }
887
- }
888
- switch (type) {
889
- case 'LOCATION':
890
- formData[key] = defValue || '';
891
- break;
892
- case 'SEARCH_CASCADE':
893
- formData[key] = defValue || [];
894
- break;
895
- case 'ADDRESS':
896
- formData[key] = defValue || '';
897
- this.defaultAddress = defValue || {};
898
- break;
899
- case 'LABEL':
900
- formData[key] = defValue || {};
901
- if (vexutils.isObject(defValue)) {
902
- this.labelSelectedList = defValue?.labels || [];
903
- } else if (Array.isArray(defValue)) {
904
- this.labelSelectedList = defValue;
905
- } else {
906
- this.labelSelectedList = [];
907
- }
908
- break;
909
- case 'TITLE':
910
- formData[key] = item.title;
911
- break;
912
- case 'IMGCARD':
913
- formData[key] = item.setting?.imgUrl || '';
914
- break;
915
- case 'UPFILE':
916
- case 'UPPICTURE':
917
- formData[key] = defValue || [];
918
- break;
919
- // 自定义列表特殊处理
920
- case 'CHECKBOX_BLOCK':
921
- if (defValue && !Array.isArray(defValue) && this.type === 'customList') {
922
- formData[key] = defValue.split(',').filter(ii => !!ii);
923
- } else {
924
- val = defValue || item.setting.defaultValue;
925
- if (vexutils.isJSON(val)) {
926
- val = JSON.parse(val);
927
- }
928
- formData[key] = val;
929
- }
930
- break;
931
- default:
932
- val = defValue || item.setting.defaultValue;
933
- if (vexutils.isJSON(val)) {
934
- val = JSON.parse(val);
935
- }
936
- formData[key] = val;
937
- break;
938
- }
939
- });
940
- return formData;
941
- },
942
- // 解析传参组件
943
- compileSpreadParams(spreadParams) {
944
- return spreadParams.domains.map(v => {
945
- let obj = {};
946
- if (v.valueType == '1') {
947
- obj[v.name] = v.value;
948
- } else if (v.valueType == '2') {
949
- obj[v.name] = this.getQueryVariable(v.value);
950
- }
951
- return obj;
952
- });
953
- },
954
- // 获取url链接参数
955
- getQueryVariable(variable) {
956
- let query = {};
957
- if (this.source == 'layout') {
958
- // 按钮传参
959
- query = this.params;
960
- } else {
961
- query = this.handleQueryParams() || {};
962
- }
963
- if (!query) return false;
964
- return query[variable] || false;
965
- },
966
- // 初始化量表
967
- formatArray(list) {
968
- let i = 1;
969
- const results = list.map(item => {
970
- const key = this.formKey(item);
971
- let title = (key || '').replace(/\n/g, '');
972
- this.$set(item, 'showTitle', item.title);
973
- // 表单校验rule prop如果有 . 会报错, 替换成 ~-~
974
- if (title.includes('.')) {
975
- let newTitle = title.replace(/\./g, '~-~');
976
- this.$set(item, 'title', newTitle);
977
- }
978
- this.$set(item, 'isShow', true);
979
- Object.keys(item).forEach(key => {
980
- if (utils.isJSON(item[key])) {
981
- if (item.type != 'LOCATION') {
982
- item[key] = JSON.parse(item[key]);
983
- }
984
- }
985
- });
986
- const notIndexArr = ['LINEBAR', 'TITLE', 'PROMPT', 'IMGCARD', 'RICH_TEXT'];
987
- if (notIndexArr.indexOf(item.type) < 0 && !item.hide) {
988
- this.$set(item, 'softcode', i++);
989
- }
990
-
991
- // "RADIO_BLOCK", "CHECKBOX_BLOCK" 将取值value改为key
992
- if (this.isChoice(item.type)) {
993
- this.handleFormatOptions(item.options, item.type);
994
- if (item.type != 'SEARCH_CASCADE') {
995
- if (item.dbValue) {
996
- this.nextLogicEvent(item.dbValue, item, results, true);
997
- } else {
998
- if (item.setting.defaultValue) {
999
- this.nextLogicEvent(item.setting.defaultValue, item, results, true);
1000
- }
1001
- }
1002
- }
1003
- }
1004
- return item;
1005
- });
1006
- return results.map(item => {
1007
- // 题目关联
1008
- let relationLogicObj = utils.isString(item.relationLogic) ? JSON.parse(item.relationLogic) : item.relationLogic;
1009
- this.handleRelationLogic(list, relationLogicObj);
1010
-
1011
- // 跳题逻辑
1012
- this.handLenextLogic(item);
1013
-
1014
- // 自定义列表特殊处理
1015
- if (item.type === 'CHECKBOX_BLOCK' && item.dbValue && !Array.isArray(item.dbValue) && this.type === 'customList') {
1016
- item.dbValue = item.dbValue.split(',').filter(ii => !!ii);
1017
- }
1018
- return item;
1019
- });
1020
- },
1021
- /**
1022
- * "RADIO_BLOCK", "CHECKBOX_BLOCK" 将取值value改为key, relationLogic需要重新处理
1023
- */
1024
- handleRelationLogic(list, relationLogicObj) {
1025
- let { condition } = relationLogicObj || {};
1026
- if (!condition || !condition.length) return;
1027
- condition.forEach(c => {
1028
- let matchItem = list.find(f => f.seq == c.subject_seq);
1029
- if (!matchItem) return;
1030
- let isChoice = this.isRadioOrCheckBox(matchItem.options, matchItem.type);
1031
- if (!isChoice) return;
1032
- let value = c.value;
1033
- if (Array.isArray(value)) {
1034
- value = value.map(v => {
1035
- return this.replaceConditionItem(matchItem.options, v);
1036
- });
1037
- c.value = value;
1038
- } else {
1039
- c.value = this.replaceConditionItem(matchItem.options, value);
1040
- }
1041
- });
1042
- },
1043
- /**
1044
- * "RADIO_BLOCK", "CHECKBOX_BLOCK" 将取值value改为key, nextLogic需要重新处理
1045
- */
1046
- handLenextLogic(item) {
1047
- let { nextLogic, options, type } = item || {};
1048
- let isChoice = this.isRadioOrCheckBox(options, type);
1049
- if (!nextLogic || !isChoice) return;
1050
- let { condition } = nextLogic || {};
1051
- if (!condition || !condition.length) return;
1052
- condition.forEach(c => {
1053
- let value = c.value;
1054
- if (Array.isArray(value)) {
1055
- value = value.map(v => {
1056
- return this.replaceConditionItem(options, v);
1057
- });
1058
- c.value = value;
1059
- } else {
1060
- c.value = this.replaceConditionItem(options, value);
1061
- }
1062
- });
1063
- },
1064
- replaceConditionItem(options, value) {
1065
- let matchOption = options.find(v => value === v.value);
1066
- if (!matchOption) return value;
1067
- return matchOption.key;
1068
- },
1069
- isRadioOrCheckBox(options, type) {
1070
- let typeArr = ['RADIO_BLOCK', 'CHECKBOX_BLOCK'];
1071
- if (!typeArr.includes(type)) return;
1072
- if (!options) return;
1073
- if (options && utils.isJSON(options)) {
1074
- options = JSON.parse(options);
1075
- }
1076
- if (!options.length) return;
1077
- return true;
1078
- },
1079
- handleFormatOptions(options, type) {
1080
- let isChoice = this.isRadioOrCheckBox(options, type);
1081
- if (!isChoice) return;
1082
-
1083
- options.forEach((item, i) => {
1084
- if (item.key !== 'other') {
1085
- item.key = i + 1;
1086
- }
1087
- if (item.prefix || item.suffix) {
1088
- item.value = item.prefix || item.suffix;
1089
- }
1090
- });
1091
- },
1092
- // 初始化rules
1093
- formatRules(formArray) {
1094
- const rules = {};
1095
- formArray.forEach(item => {
1096
- let newTitle = this.formKey(item);
1097
- // 表单校验rule prop如果有 . 会报错, 替换成 ~-~
1098
- if (newTitle.includes('.')) {
1099
- newTitle = newTitle.replace(/\./g, '~-~');
1100
- }
1101
- rules[newTitle] = [{ required: item.required, message: '必填', trigger: 'change' }];
1102
- if (item.type == 'MOBILE' && item.validation) {
1103
- rules[newTitle].push({
1104
- pattern: /^1[3456789]\d{9}$/,
1105
- message: '格式错误',
1106
- trigger: 'blur'
1107
- });
1108
- } else if (item.type == 'ID_CARD' && item.validation) {
1109
- rules[newTitle].push({
1110
- pattern: /^\d{6}(((19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])\d{3}([0-9]|x|X))|(\d{2}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])\d{3}))$/,
1111
- message: '格式错误',
1112
- trigger: 'blur'
1113
- });
1114
- } else if (item.type == 'ADDRESS' && item.required) {
1115
- if (this.handleAddressType(item)) {
1116
- rules[newTitle].push({
1117
- validator: this.checkAdress,
1118
- trigger: 'change'
1119
- });
1120
- }
1121
- } else if (item.type == 'LABEL' && item.required) {
1122
- rules[newTitle].push({
1123
- validator: this.checkLabel,
1124
- trigger: 'change'
1125
- });
1126
- } else if (item.type == 'DATETIME' && this.type == 'customList') {
1127
- // 自定义列表特殊处理日期时间 最大值
1128
- // dateMaxType 1当前日期时间 2指定日期时间 3其他日期时间字段
1129
- let dateMaxType = this.handleDateMaxType(item);
1130
- if (!dateMaxType) return;
1131
- let obj = {
1132
- 1: 'checkDateMaxCur',
1133
- 2: 'checkDateMaxSet',
1134
- 3: 'checkDateMaxOther'
1135
- };
1136
- let methodName = obj[dateMaxType];
1137
- rules[newTitle].push({
1138
- validator: (rule, value, callback) => this[methodName](rule, value, callback, item),
1139
- trigger: 'change'
1140
- });
1141
- } else if (item.type === 'RADIO_BLOCK') {
1142
- this.choiceComObj[this.formKey(item)] = {};
1143
- rules[newTitle].push({
1144
- validator: (rule, value, callback) => this.checkRadio(rule, value, callback, item),
1145
- trigger: 'change'
1146
- });
1147
- } else if (item.type === 'CHECKBOX_BLOCK') {
1148
- this.choiceComObj[this.formKey(item)] = {};
1149
- rules[newTitle].push({
1150
- validator: (rule, value, callback) => this.checkCheckbox(rule, value, callback, item),
1151
- trigger: 'change'
1152
- });
1153
- }
1154
- });
1155
- return rules;
1156
- },
1157
- handleAddressType(item) {
1158
- let setObj = { addressType: 'province-city-district-address' };
1159
- if (utils.isJSON(item.setting)) {
1160
- setObj = JSON.parse(item.setting);
1161
- } else {
1162
- setObj = item.setting;
1163
- }
1164
- let isAdress = setObj.addressType.includes('address');
1165
- return isAdress;
1166
- },
1167
- checkAdress(rule, value, callback) {
1168
- let { address } = value || {};
1169
- if (!address) {
1170
- return callback(new Error('必填'));
1171
- }
1172
- callback();
1173
- },
1174
- checkLabel(rule, value, callback) {
1175
- if (!value || !Object.keys(value).length) {
1176
- return callback(new Error('必填'));
1177
- }
1178
- let { labelStr, labels = [] } = value;
1179
- if (!labelStr || !labels.length) {
1180
- return callback(new Error('必填'));
1181
- }
1182
- callback();
1183
- },
1184
- handleDateMaxType(item) {
1185
- let setObj = item.setting;
1186
- if (utils.isJSON(setObj)) {
1187
- setObj = JSON.parse(setObj);
1188
- }
1189
- return setObj.dateMaxType;
1190
- },
1191
- // 自定义列表 日期时间 max 当前日期时间
1192
- checkDateMaxCur(rule, value, callback, item) {
1193
- if (!value) return callback();
1194
- let { dateType } = item.setting;
1195
- if (!dateType) return callback();
1196
- let dateMaxValue = this.currentTime;
1197
- if (dateType == 'time') {
1198
- dateMaxValue = this.currentTime.format('HH:mm:ss');
1199
- }
1200
- let isMax = this.handleMax(dateType, value, dateMaxValue);
1201
- if (!isMax) {
1202
- return callback(new Error('最大不能超过当前日期时间'));
1203
- }
1204
- callback();
1205
- },
1206
- // 自定义列表 日期时间 max 指定日期时间
1207
- checkDateMaxSet(rule, value, callback, item) {
1208
- if (!value) return callback();
1209
- let { dateMaxValue, dateType } = item.setting;
1210
- if (!dateMaxValue || !dateType) return callback();
1211
- let isMax = this.handleMax(dateType, value, dateMaxValue);
1212
- if (!isMax) {
1213
- return callback(new Error('最大不能超过指定日期时间'));
1214
- }
1215
- callback();
1216
- },
1217
- // 自定义列表 日期时间 max 其他日期时间字段
1218
- checkDateMaxOther(rule, value, callback, item) {
1219
- if (!value) return callback();
1220
- let { outDateMaxValue, dateType } = item.setting;
1221
- if (!outDateMaxValue || !dateType) return callback();
1222
- let matchDateItem = this.formArray.find(v => v.seq === outDateMaxValue);
1223
- if (!matchDateItem || matchDateItem.hide) return callback();
1224
- let matchValue = this.form[this.formKey(matchDateItem)];
1225
- if (!matchValue) return;
1226
- let isMax = this.handleMax(dateType, value, matchValue);
1227
- if (!isMax) {
1228
- return callback(new Error(`最大不能超过【${matchDateItem.title}】日期时间`));
1229
- }
1230
- callback();
1231
- },
1232
- checkRadio(rule, value, callback, item) {
1233
- if (!value) return callback();
1234
- let { options } = item;
1235
- if (!options.length || value === 'other') return callback();
1236
- const key = this.formKey(item);
1237
- let { optionsPreSuffixObj = {} } = this.choiceComObj[key] || {};
1238
- let matchItem = options.find((o, i) => {
1239
- if (i + 1 === value) {
1240
- return true;
1241
- }
1242
- return false;
1243
- });
1244
- if (!matchItem || matchItem.importability) return callback();
1245
- if (matchItem.prefix || matchItem.suffix) {
1246
- let inputValue = optionsPreSuffixObj[value];
1247
- if (!inputValue) {
1248
- return callback(new Error(`请完善选项`));
1249
- }
1250
- }
1251
- callback();
1252
- },
1253
- checkCheckbox(rule, value, callback, item) {
1254
- if (!value || !value.length) return callback();
1255
- let { options } = item;
1256
- if (!options.length) return callback();
1257
- let i = 0,
1258
- len = value.length,
1259
- v;
1260
- const key = this.formKey(item);
1261
- let { optionsPreSuffixObj = {} } = this.choiceComObj[key] || {};
1262
- for (; i < len; i++) {
1263
- v = value[i];
1264
- if (v === 'other') continue;
1265
- let matchItem = options.find((o, j) => {
1266
- if (j + 1 === v) {
1267
- return true;
1268
- }
1269
- return false;
1270
- });
1271
- if (!matchItem || matchItem.importability) continue;
1272
-
1273
- if (matchItem.prefix || matchItem.suffix) {
1274
- let inputValue = optionsPreSuffixObj[v];
1275
- if (!inputValue) {
1276
- return callback(new Error(`请完善选项`));
1277
- }
1278
- }
1279
- }
1280
- callback();
1281
- },
1282
- handleMax(dateType, value, dateMaxValue) {
1283
- let curValue = '';
1284
- let tempValue = '';
1285
- if (dateType == 'time') {
1286
- let curYMD = this.currentTime.format('YYYY MM DD ');
1287
- curValue = moment(curYMD + dateMaxValue).valueOf();
1288
- tempValue = moment(curYMD + value).valueOf();
1289
- } else if (dateType == 'date') {
1290
- curValue = moment(dateMaxValue).valueOf();
1291
- tempValue = moment(value).valueOf();
1292
- } else {
1293
- curValue = moment(dateMaxValue).valueOf();
1294
- tempValue = moment(value).valueOf();
1295
- }
1296
- if (tempValue > curValue) {
1297
- return false;
1298
- }
1299
- return true;
1300
- },
1301
- handleGetAddress(val) {
1302
- if (utils.isJSON(val)) {
1303
- const valObj = JSON.parse(val);
1304
- return valObj.address || valObj.name;
1305
- }
1306
- return '';
1307
- },
1308
- handleSelectLocation(e, item) {
1309
- const { locationProp, isInit } = e;
1310
- this.mapLocation = locationProp;
1311
- const key = this.formKey(item);
1312
- this.form[key] = locationProp;
1313
- this.mapVisible = isInit || false;
1314
- },
1315
- isInput(type) {
1316
- return type == 'INPUT' || type == 'ID_CARD' || type == 'MOBILE' || type == 'EVALUATE_INPUT';
1317
- },
1318
- isChoice(type) {
1319
- return (
1320
- type == 'SELECT' ||
1321
- type == 'RADIO_BLOCK' ||
1322
- type == 'CHECKBOX_BLOCK' ||
1323
- type == 'SEARCH_CASCADE' ||
1324
- type == 'EVALUATE_RADIO_BLOCK' ||
1325
- type == 'EVALUATE_CHECKBOX_BLOCK' ||
1326
- type == 'EVALUATE_SELECT'
1327
- );
1328
- },
1329
- isTime(type) {
1330
- return type == 'DATE' || type == 'TIME' || type == 'DATETIME';
1331
- },
1332
- isUpload(type) {
1333
- return type == 'UPFILE' || type == 'UPPICTURE';
1334
- },
1335
- writeGuage(showCountdown) {
1336
- this.showEvaluateSettingWrap = false;
1337
- this.showEvaluateCountdown = showCountdown;
1338
- },
1339
- closeEvaluateCountdown() {
1340
- // 倒计时结束自动提交 无需校验
1341
- this.showEvaluateCountdown = false;
1342
- if (this.isPreviewScale) return;
1343
- this.banSubmit = true;
1344
- this.submitMethod();
1345
- this.$warning({
1346
- title: '温馨提示',
1347
- content: '测评时间到了,结束测评!',
1348
- okText: '确定',
1349
- onOk: () => {}
1350
- });
1351
- },
1352
- async showEvaTipModal(item) {
1353
- if (this.evatipMap[item.id]) {
1354
- this.evatipConfirm(this.evatipMap[item.id]);
1355
- return;
1356
- }
1357
- let key = 'getSubjectAnswer';
1358
- const fn = this.scaleApiConfig?.[key] || null;
1359
- if (!fn || typeof fn !== 'function') {
1360
- this.$message.error(`${key} Is not a function`);
1361
- return;
1362
- }
1363
- let obj = await fn(item.id);
1364
- if (!obj) return;
1365
- if (!this.evatipMap[item.id]) {
1366
- this.evatipMap[item.id] = obj;
1367
- this.evatipConfirm(obj);
1368
- }
1369
- },
1370
- closeTip() {
1371
- this.$destroyAll();
1372
- },
1373
- evatipConfirm(str) {
1374
- let _this = this;
1375
- let content = h => (
1376
- <div class="evatip-container">
1377
- <a-icon type="close" class="tip-content-close" on-click={_this.closeTip} />
1378
- <span>答案解析:</span>
1379
- <p>{str}</p>
1380
- </div>
1381
- );
1382
- this.$confirm({
1383
- title: '提示',
1384
- icon: () => null,
1385
- content,
1386
- okText: '确定',
1387
- cancelText: '关闭',
1388
- onOk() {},
1389
- onCancel() {},
1390
- class: 'evatip-modal-wrap'
1391
- });
1392
- },
1393
- // 选择组件
1394
- handleChoice(choiceValue, formItem) {
1395
- let { value = '', list = [] } = choiceValue;
1396
- this.nextLogicEvent(value, formItem, this.formArray);
1397
- this.handleDynamicDataRelation(list, formItem, this.formArray);
1398
- },
1399
- // 下拉框 动态数据源关联字段
1400
- handleDynamicDataRelation(list, formItem, formArray) {
1401
- let { targetSource } = formItem;
1402
- if (!targetSource || !Object.keys(targetSource).length) return;
1403
- if (!targetSource.target_id) return;
1404
- let { relationParam = [] } = targetSource;
1405
- if (!relationParam.length) return;
1406
- relationParam.forEach(item => {
1407
- let matchEle = formArray.find(v => v.seq === item.relationElement);
1408
- const key = this.formKey(matchEle);
1409
- if (matchEle) {
1410
- if (!list.length) {
1411
- this.form[key] = '';
1412
- } else {
1413
- let relationFieldList = list.map(v => v[item.relationField] || '/') || '';
1414
- this.form[key] = relationFieldList.join(',');
1415
- }
1416
- }
1417
- });
1418
- },
1419
- // 设置的logic condition 最大next_subject
1420
- handleLogicMaxNext(condition = []) {
1421
- const arr = condition.map(({ next_subject }) => (next_subject == 'end' ? 9999 : +(next_subject || 9999)));
1422
- const max = Math.max.call(null, ...arr);
1423
- return max;
1424
- },
1425
- // 当前formItem 下一个触发logicCodition item 的seq
1426
- handleLogicList(formItem, formArray) {
1427
- const { seq } = formItem;
1428
- let list = formArray.map(item => {
1429
- if (item.seq > seq && item.isShow && item.__isLogic__) return item;
1430
- return false;
1431
- });
1432
- let nextItemMax = 0;
1433
- let i = 0,
1434
- len = list.length,
1435
- item;
1436
- for (; i < len; i++) {
1437
- item = list[i];
1438
- let curVal = this.form[this.formKey(item)];
1439
- if (!curVal) continue;
1440
- if (Array.isArray(curVal)) {
1441
- if (!curVal.length) continue;
1442
- }
1443
- const { nextLogic, seq, __isLogic__, __lastSeq__ } = item;
1444
- if (!nextLogic.next_logic_is || !nextLogic.condition.length) continue;
1445
- if (__lastSeq__) {
1446
- nextItemMax = __lastSeq__;
1447
- break;
1448
- }
1449
- }
1450
- return nextItemMax;
1451
- },
1452
- // 跳题逻辑
1453
- nextLogicEvent(choiceValue, formItem, formArray = [], isInit) {
1454
- const { nextLogic, seq } = formItem;
1455
- if (!nextLogic) return;
1456
- if (nextLogic.next_logic_is && nextLogic.condition.length) {
1457
- let nextMax = 9999,
1458
- nextItemMax = 0;
1459
- if (!isInit) {
1460
- nextMax = this.handleLogicMaxNext(nextLogic.condition);
1461
- nextItemMax = this.handleLogicList(formItem, formArray);
1462
- }
1463
- nextLogic.condition.some(con => {
1464
- const { value, next_subject } = con;
1465
- const lastSeq = next_subject == 'end' ? 9999 : next_subject;
1466
- if (nextItemMax && nextItemMax > seq && nextItemMax < nextMax) {
1467
- nextMax = nextItemMax;
1468
- }
1469
- if (nextLogic.next_logic == 'condition') {
1470
- let hasValue = false;
1471
- if (Array.isArray(choiceValue)) {
1472
- hasValue = choiceValue.includes(value);
1473
- } else {
1474
- hasValue = choiceValue === value;
1475
- }
1476
-
1477
- // 添加非响应式key __isLogic__ __lastSeq__
1478
- Object.defineProperty(formItem, '__isLogic__', {
1479
- value: hasValue,
1480
- writable: true
1481
- });
1482
- Object.defineProperty(formItem, '__lastSeq__', {
1483
- value: seq + 1,
1484
- writable: true
1485
- });
1486
-
1487
- if (hasValue) {
1488
- formArray.forEach(item => {
1489
- if (item.seq > seq && item.seq < lastSeq) {
1490
- item.isShow = false;
1491
- // 跳过时 清空已填内容
1492
- const key = this.formKey(item);
1493
- this.form[key] && (this.form[key] = '');
1494
- } else if (item.seq >= lastSeq && item.seq < nextMax) {
1495
- this.$set(item, 'isShow', true);
1496
- }
1497
- });
1498
- return true;
1499
- } else {
1500
- formArray.forEach(item => {
1501
- if (item.seq > seq && item.seq < lastSeq) {
1502
- item.isShow = true;
1503
- }
1504
- });
1505
- }
1506
- } else if (nextLogic.next_logic == 'uncondition') {
1507
- let res = utils.isEmpty(choiceValue);
1508
-
1509
- // 添加非响应式key __isLogic__ __lastSeq__
1510
- Object.defineProperty(formItem, '__isLogic__', {
1511
- value: !res,
1512
- writable: true
1513
- });
1514
- Object.defineProperty(formItem, '__lastSeq__', {
1515
- value: seq + 1,
1516
- writable: true
1517
- });
1518
-
1519
- formArray.forEach(item => {
1520
- const key = this.formKey(item);
1521
- if (item.seq > seq && item.seq < lastSeq) {
1522
- item.isShow = res;
1523
- // 跳过时 清空已填内容
1524
- if (!res) {
1525
- this.form[key] && (this.form[key] = '');
1526
- }
1527
- }
1528
- });
1529
- }
1530
- });
1531
- }
1532
- },
1533
- // 关联逻辑
1534
- showEvent(formItem, isSubmitCallback) {
1535
- if (formItem.hide) return false;
1536
- const { form } = this;
1537
- let relationLogicObj = {};
1538
- // 回调接口
1539
- if (isSubmitCallback) {
1540
- let setting = formItem.setting;
1541
- if (formItem.setting && utils.isJSON(formItem.setting)) {
1542
- setting = JSON.parse(formItem.setting);
1543
- }
1544
- relationLogicObj = utils.isString(setting.callbackCondition) ? JSON.parse(setting.callbackCondition) : setting.callbackCondition;
1545
- if (!relationLogicObj || !relationLogicObj.condition || !relationLogicObj.condition.length) return true;
1546
- } else {
1547
- relationLogicObj = utils.isString(formItem.relationLogic) ? JSON.parse(formItem.relationLogic) : formItem.relationLogic;
1548
- }
1549
- if (!relationLogicObj || !Object.keys(relationLogicObj).length) return true;
1550
- const { relation_logic_is, condition, relation_logic } = relationLogicObj;
1551
- if (relation_logic_is) {
1552
- const results = condition.map(c => {
1553
- let key = this.formKey(this.formArray.filter(f => f.seq == c.subject_seq)[0]);
1554
- if (utils.isArray(form[key])) {
1555
- return form[key].some(v => c.value.includes(v));
1556
- } else {
1557
- return c.value.includes(form[key]);
1558
- }
1559
- });
1560
- if (relation_logic == 'OR') {
1561
- formItem.isShow = results.some(el => el);
1562
- } else if (relation_logic == 'AND') {
1563
- formItem.isShow = results.every(el => el);
1564
- } else {
1565
- formItem.isShow = results[0];
1566
- }
1567
- }
1568
- return formItem.isShow;
1569
- },
1570
- // 单选组件回调
1571
- radioChange(val, item, obj) {
1572
- const key = this.formKey(item);
1573
- this.form[key] = val;
1574
- item.type === 'RADIO_BLOCK' && this.$set(this.choiceComObj, key, obj);
1575
- this.nextLogicEvent(val, item, this.formArray);
1576
- },
1577
- // 多选组件回调
1578
- checkboxChange(val, item, obj) {
1579
- const key = this.formKey(item);
1580
- this.form[key] = val;
1581
- item.type === 'CHECKBOX_BLOCK' && this.$set(this.choiceComObj, key, obj);
1582
- this.nextLogicEvent(val, item, this.formArray);
1583
- },
1584
- // 标签组件回调
1585
- labelChange(labelList, item) {
1586
- const key = this.formKey(item);
1587
- this.form[key] = this.handleGetLabelSubmit(labelList);
1588
- },
1589
- // 视频组件回调
1590
- vodFileList(list, item) {
1591
- const key = this.formKey(item);
1592
- this.form[key] = list;
1593
- },
1594
- handleGetLabelSubmit(labelSelectedList) {
1595
- if (!labelSelectedList || !labelSelectedList.length)
1596
- return {
1597
- labelStr: '',
1598
- labels: []
1599
- };
1600
- const selectedList = labelSelectedList || [];
1601
- const labelStrList = [];
1602
- const labels = [];
1603
- // "cacheKey":"label_标签","isSelect":true
1604
- selectedList.forEach(v => {
1605
- labels.push(v);
1606
- labelStrList.push(v.labelName);
1607
- });
1608
- this.labelSelectedList = selectedList;
1609
- return {
1610
- labelStr: labelStrList.join(','),
1611
- labels: labels
1612
- };
1613
- },
1614
- // 地址回调
1615
- changeAddress(allValue, item) {
1616
- const key = this.formKey(item);
1617
- this.form[key] = allValue;
1618
- },
1619
- // 上传回调
1620
- changeUpload(value, item) {
1621
- const key = this.formKey(item);
1622
- this.form[key] = value;
1623
- },
1624
- // 时间回调
1625
- changeTime(value, item) {
1626
- const key = this.formKey(item);
1627
- this.form[key] = value;
1628
- this.submitForm[key] = value;
1629
- },
1630
- // 保存
1631
- onSubmit() {
1632
- // 不包含测评组件,点击提交,弹出二次确认对话框,确认要提交吗?
1633
- let hasEvaluate = this.formArray.find(item => this.isEvaluation(item.type));
1634
- if (!hasEvaluate) {
1635
- this.confirmSubmit('确认要提交吗?');
1636
- return;
1637
- }
1638
-
1639
- // 包含测评组件,不包含考试时长,点击提交,弹出二次确认对话框,确认要结束测评吗?
1640
- // 判断有无测评配置 并且在测评时间内
1641
- let { evaluateResultSetting } = this.config;
1642
- if (!evaluateResultSetting || (!Object.keys(evaluateResultSetting).length && !this.showEvaluateEntry)) {
1643
- this.confirmSubmit('确认要结束测评吗?');
1644
- return;
1645
- }
1646
-
1647
- // 表单内嵌量表, 没有开始答题, 不需要调用保存接口
1648
- if (this.openType == 'formIframe' && this.showEvaluateEntry) {
1649
- this.$emit('submitNoRequest');
1650
- return;
1651
- }
1652
-
1653
- // 无倒计时
1654
- let countdownDom = this.$refs.evaluateCountdown;
1655
- if (!countdownDom?.showEvaluateCountdown) {
1656
- this.confirmSubmit('确认要结束测评吗?');
1657
- return;
1658
- }
1659
-
1660
- // 在倒计时内
1661
- let message = '确认要提前结束测评吗?';
1662
- let setAnswered = this.$refs.evaluateCountdown?.setAnswered;
1663
- let totalLen = this.$refs.evaluateCountdown?.totalLen;
1664
- // 存在未解答题目
1665
- if (setAnswered < totalLen) {
1666
- message = '存在未解答的题目,确定要提前结束吗?';
1667
- }
1668
- this.confirmSubmit(message);
1669
- },
1670
- confirmSubmit(message) {
1671
- let _this = this;
1672
- this.$confirm({
1673
- title: '温馨提示',
1674
- content: message,
1675
- okText: '确定',
1676
- cancelText: '取消',
1677
- onOk: () => {
1678
- _this.onSubmitForm();
1679
- },
1680
- onCancel() {}
1681
- });
1682
- },
1683
- onSubmitForm() {
1684
- this.$refs['ruleForm'].validate((valid, keys) => {
1685
- if (valid) {
1686
- this.submitMethod();
1687
- } else {
1688
- if (Object.keys(keys).length > 0) {
1689
- let key = Object.keys(keys)[0];
1690
- let field = keys[key][0].field,
1691
- message = keys[key][0].message;
1692
- let matchItem = this.formArray.find(v => v.databaseTitle === field);
1693
- if (matchItem) {
1694
- field = matchItem.title;
1695
- }
1696
- this.$message.error(field + message);
1697
- }
1698
- return false;
1699
- }
1700
- });
1701
- },
1702
- submitMethod() {
1703
- const hasSpreadParams = this.defaultFormArray.find(v => v.type === 'SPREAD_PARAMS');
1704
- if (hasSpreadParams) {
1705
- if (utils.isJSON(hasSpreadParams.setting)) {
1706
- hasSpreadParams.setting = JSON.parse(hasSpreadParams.setting);
1707
- }
1708
- let spreadKey = this.formKey(hasSpreadParams);
1709
- this.submitForm[spreadKey] = this.compileSpreadParams(hasSpreadParams.setting.spreadParams);
1710
- }
1711
- // 自定义列表新增时多选特殊处理
1712
- let checkBoxKey = this.defaultFormArray.find(ii => ii.type == 'CHECKBOX_BLOCK');
1713
- if (checkBoxKey && Array.isArray(this.form[checkBoxKey.title]) && this.type === 'customList') {
1714
- this.form[checkBoxKey.title] = this.form[checkBoxKey.title].join(',');
1715
- }
1716
- const scoreJson = this.handleScoreJson();
1717
- let params;
1718
- if (this.type === 'customList') {
1719
- params = {
1720
- definedListId: this.ids.guage_id,
1721
- dbId: this.ids.db_id,
1722
- scoreJson: JSON.stringify(scoreJson)
1723
- };
1724
- } else {
1725
- const { guageId, randomId } = this.config;
1726
- params = Object.assign(this.params, {
1727
- guageId,
1728
- scoreJson: JSON.stringify(scoreJson),
1729
- randomId
1730
- });
1731
- }
1732
- if (this.shareId) {
1733
- params.shareId = this.shareId;
1734
- }
1735
- const tipSetting = this.defaultFormArray.find(item => item.type === 'SUCCESS_TIP');
1736
- if (tipSetting) {
1737
- // 提交保存成功提示设置
1738
- const tip = utils.isJSON(tipSetting.setting) ? JSON.parse(tipSetting.setting) : tipSetting.setting;
1739
- params.tipSetting = JSON.stringify({
1740
- tipMode: tip.tipMode,
1741
- tipType: tip.tipType,
1742
- tipText: tip.tipText,
1743
- tipApi: tip.tipApi
1744
- });
1745
- }
1746
- let hasCallbackItem = this.defaultFormArray.find(v => v.type === 'CALLBACK_INTERFACE');
1747
- let isCallback = false;
1748
- if (hasCallbackItem) {
1749
- isCallback = this.showEvent(hasCallbackItem, true);
1750
- }
1751
- /**
1752
- * NOTE:
1753
- * 提交数据往外推
1754
- */
1755
- this.$emit('onSubmit', params, hasCallbackItem, isCallback);
1756
- },
1757
- handleScoreJson() {
1758
- let tempObj = Object.assign({}, this.form, this.submitForm);
1759
- let res = {};
1760
- if (!Object.keys(tempObj).length) return {};
1761
- for (let key in tempObj) {
1762
- let itemTemp = this.formArray.find(item => this.formKey(item) == key);
1763
- let curValue = tempObj[key];
1764
- if (key && itemTemp) {
1765
- let keyTemp;
1766
- if (itemTemp && itemTemp.databaseTitle) keyTemp = itemTemp.databaseTitle;
1767
- if (this.type == 'customList' && itemTemp && itemTemp.setting && itemTemp.setting.startToStop != 1 && curValue && itemTemp.type == 'DATETIME') {
1768
- if (itemTemp.setting && itemTemp.setting.dateType == 'time' && curValue) curValue = moment().format('YYYY-MM-DD ') + curValue;
1769
- if (itemTemp.setting && itemTemp.setting.dateType == 'date' && curValue) curValue = moment(curValue).format('YYYY-MM-DD ') + moment().format('HH:mm:ss');
1770
- }
1771
-
1772
- // 处理choice选项 将key替换为value
1773
- let isChoice = ['RADIO_BLOCK', 'CHECKBOX_BLOCK'].includes(itemTemp.type);
1774
- if (isChoice) {
1775
- let { options } = itemTemp;
1776
- let obj = this.choiceComObj[key];
1777
- if (itemTemp.type === 'RADIO_BLOCK' && curValue) {
1778
- curValue = this.handleChoiceItem(curValue, options, obj);
1779
- }
1780
- if (itemTemp.type === 'CHECKBOX_BLOCK' && curValue?.length) {
1781
- let resArr = this.handleCheckboxParams(curValue, options, obj);
1782
- curValue = resArr;
1783
- }
1784
- }
1785
-
1786
- if (key.includes('~-~')) {
1787
- let newKey = keyTemp ? keyTemp.replace(/~-~/g, '.') : key.replace(/~-~/g, '.');
1788
- res[newKey] = curValue;
1789
- } else {
1790
- res[keyTemp || key] = !curValue ? null : curValue;
1791
- }
1792
- } else {
1793
- res[key] = curValue;
1794
- }
1795
- }
1796
- console.log('res', res);
1797
- return res;
1798
- },
1799
- handleCheckboxParams(value, options, obj) {
1800
- let res = [];
1801
- let i = 0,
1802
- len = value.length,
1803
- v;
1804
- for (; i < len; i++) {
1805
- v = value[i];
1806
- let matchItem = options.find((o, i) => {
1807
- if (i + 1 === v) {
1808
- return true;
1809
- }
1810
- return false;
1811
- });
1812
- if (matchItem && !matchItem.prefix && !matchItem.suffix) {
1813
- res.push(matchItem.value);
1814
- continue;
1815
- }
1816
- let tempValue = this.handleChoiceItem(v, options, obj);
1817
- res.push(tempValue);
1818
- }
1819
- return res;
1820
- },
1821
- handleChoiceItem(value, options, obj) {
1822
- let { othersText, optionsPreSuffixObj = {} } = obj || {};
1823
- if (value === 'other') {
1824
- return othersText || '其他';
1825
- }
1826
- let matchItem = options.find((o, i) => {
1827
- if (i + 1 === value) {
1828
- return true;
1829
- }
1830
- return false;
1831
- });
1832
- if (!matchItem) return;
1833
- if (!matchItem.prefix && !matchItem.suffix) return matchItem.value;
1834
- let resValue = optionsPreSuffixObj[value] || '';
1835
- if (matchItem.prefix) {
1836
- resValue = matchItem.prefix + resValue;
1837
- } else {
1838
- resValue += matchItem.suffix;
1839
- }
1840
- return resValue;
1841
- },
1842
- resetForm() {
1843
- this.$refs.ruleForm.resetFields();
1844
- },
1845
- cancel() {
1846
- this.$emit('onCloseSetting');
1847
- },
1848
- handleEvaluationScore(ele) {
1849
- let { minScore = 0, maxScore = 0, scoreType } = ele.scoreConfigs || {};
1850
- return `(${maxScore}分)`;
1851
- }
1852
- }
1853
- });
1854
- </script>
1855
- <style lang="less" scoped>
1856
- .r-scale {
1857
- position: relative;
1858
- width: 100%;
1859
- height: 100%;
1860
- overflow: hidden;
1861
- padding-top: 4px;
1862
- padding-bottom: 50px;
1863
- .scale-container {
1864
- width: 100%;
1865
- height: 100%;
1866
- padding-bottom: 10px;
1867
- transform-origin: 0 0;
1868
- overflow-y: auto;
1869
- box-sizing: border-box;
1870
- &.scale-container-nopadding {
1871
- height: 100%;
1872
- }
1873
- &::-webkit-scrollbar {
1874
- width: 10px;
1875
- }
1876
- }
1877
- /deep/ .no-data-tip {
1878
- width: 100%;
1879
- height: 100%;
1880
- }
1881
- .totalScore-warp {
1882
- padding: 16px;
1883
- margin-bottom: 16px;
1884
- font-weight: 400;
1885
- color: #666666;
1886
- background: #f2f2f4;
1887
- font-size: 14px;
1888
- border-radius: 6px;
1889
- div + div {
1890
- margin-top: 4px;
1891
- }
1892
- span {
1893
- font-weight: 500;
1894
- color: #090909;
1895
- }
1896
- .score-result {
1897
- color: #2d7aff;
1898
- }
1899
- }
1900
- /deep/ .ant-spin-spinning {
1901
- height: 100%;
1902
- width: 100%;
1903
- padding-top: 88px;
1904
- }
1905
- /deep/ .ant-select ~ div {
1906
- position: relative !important;
1907
- }
1908
- // /deep/.ant-select-dropdown {
1909
- // top: 0px !important;
1910
- // left: 1px !important;
1911
- // }
1912
- .lb-title {
1913
- text-align: center;
1914
- }
1915
- .map-container {
1916
- cursor: pointer;
1917
- /deep/ .ant-input-disabled {
1918
- color: rgba(0, 0, 0, 0.65);
1919
- background-color: #fff;
1920
- cursor: pointer;
1921
- }
1922
- }
1923
- .linebar-div {
1924
- text-align: center;
1925
- margin-top: 24px;
1926
- /deep/ .ant-divider {
1927
- margin-top: -4px;
1928
- }
1929
- }
1930
- .my-prompt {
1931
- padding: 10px;
1932
- box-shadow: 0 5px 13px rgba(0, 0, 0, 0.14);
1933
- background-color: #fff;
1934
- border-radius: 4px;
1935
- }
1936
- .img-card {
1937
- width: 100%;
1938
- }
1939
- }
1940
- .main {
1941
- // overflow: auto;
1942
- // overflow-x: hidden;
1943
- padding: 0 16px;
1944
- box-sizing: border-box;
1945
- /deep/.ant-form-item-required::before {
1946
- color: #e02828;
1947
- }
1948
- .scale-label-required {
1949
- font-weight: 700;
1950
- }
1951
- .required-text {
1952
- color: #e02828;
1953
- }
1954
- .evalute-label {
1955
- display: inline-block;
1956
- height: 20px;
1957
- line-height: 20px;
1958
- padding: 0 5px;
1959
- margin-left: 4px;
1960
- font-size: 12px;
1961
- color: #2d7aff;
1962
- border-radius: 4px;
1963
- border: 1px solid rgba(45, 122, 255, 0.5);
1964
- background: rgba(45, 122, 255, 0.1);
1965
- }
1966
- .evalute-tip {
1967
- display: inline-block;
1968
- padding: 0 5px;
1969
- margin-left: 8px;
1970
- color: #fe9626;
1971
- border-radius: 2px;
1972
- background: rgba(255, 194, 0, 0.15);
1973
- cursor: pointer;
1974
- .ant-icon {
1975
- margin-right: 2px;
1976
- }
1977
- }
1978
- /deep/ .ant-form-item-label {
1979
- // white-space: break-spaces;
1980
- white-space: unset;
1981
- text-align: left;
1982
- line-height: 20px;
1983
- padding: 6px 0;
1984
- width: 100%;
1985
- .ant-form-item-no-colon {
1986
- width: 100%;
1987
- }
1988
- }
1989
- }
1990
- .footer {
1991
- position: absolute;
1992
- bottom: 0;
1993
- left: 0;
1994
- width: 100%;
1995
- border-top: 1px solid #e8e8e8;
1996
- padding-top: 12px;
1997
- height: 50px;
1998
- box-sizing: border-box;
1999
- background: #fff;
2000
- }
2001
- .rich-text-content {
2002
- word-break: break-all;
2003
- /deep/ p {
2004
- margin-bottom: 0;
2005
- }
2006
- /deep/ img {
2007
- max-width: 100%;
2008
- }
2009
- }
2010
- </style>
1
+ <template>
2
+ <div class="r-scale">
3
+ <slot v-if="spinning">
4
+ <a-spin :indicator="indicator" tip="加载中..." />
5
+ </slot>
6
+ <slot v-if="!spinning && !hasFrontAddress">
7
+ <!-- <div v-if="noData">暂无数据</div> -->
8
+ <NoData v-if="noData" :noDataImg="noDataImg" :noDataTip="noDataTip"></NoData>
9
+ <template v-else>
10
+ <evaluatePage
11
+ v-if="showEvaluateEntry"
12
+ :formArray="formArray"
13
+ :evaluateResultConfig="config.evaluateResultConfig"
14
+ :evaluateResultSetting="config.evaluateResultSetting"
15
+ :isFinished="isFinished"
16
+ :maxScore="maxScore"
17
+ @writeGuage="writeGuage"
18
+ ></evaluatePage>
19
+ <template v-else>
20
+ <evaluateCountdown
21
+ v-if="showEvaluateCoundownPage"
22
+ ref="evaluateCountdown"
23
+ :formArray="formArray"
24
+ :evaluateResultConfig="config.evaluateResultConfig"
25
+ :evaluateResultSetting="config.evaluateResultSetting"
26
+ :form="form"
27
+ :isFinished="isFinished"
28
+ :currentTime="currentTime"
29
+ :showEvaluateCountdown="showEvaluateCountdown"
30
+ @closeEvaluateCountdown="closeEvaluateCountdown"
31
+ ></evaluateCountdown>
32
+ <div
33
+ class="scale-container"
34
+ :class="{ 'scale-container-nopadding': handlePageClass }"
35
+ :style="scaleStyle"
36
+ >
37
+ <div class="totalScore-warp" v-if="hasScore">
38
+ <div>
39
+ 测评总分:
40
+ <span>{{ maxScore }}分</span>
41
+ </div>
42
+ <div>
43
+ 测评分数:
44
+ <span :style="{ color: getEvaResColor }">{{ config.totalScore }}分</span>
45
+ </div>
46
+ <template v-if="hasEvaluateSetting">
47
+ <div>
48
+ 测评结果:
49
+ <span
50
+ class="score-result"
51
+ :style="{ color: getEvaResColor }"
52
+ >{{ config.evaluateResult }}</span>
53
+ </div>
54
+ <div>
55
+ 结果说明:
56
+ <span>{{ config.evaluateResultExplain }}</span>
57
+ </div>
58
+ </template>
59
+ </div>
60
+ <a-form-model
61
+ ref="ruleForm"
62
+ :model="form"
63
+ :rules="rules"
64
+ :layout="form.layout"
65
+ :colon="false"
66
+ class="main"
67
+ >
68
+ <template v-for="(item, index) in formArray">
69
+ <!-- 标题 -->
70
+ <template v-if="item.type == 'TITLE'">
71
+ <a-form-model-item
72
+ v-if="isShowItem(item)"
73
+ :colon="false"
74
+ :key="item.id || item.seq"
75
+ >
76
+ <h1 class="lb-title">{{ item.title }}</h1>
77
+ <div class="lb-title">{{ item.describe }}</div>
78
+ </a-form-model-item>
79
+ </template>
80
+ <!-- 分线栏 -->
81
+ <template v-else-if="item.type == 'LINEBAR'">
82
+ <a-form-model-item
83
+ v-if="isShowItem(item)"
84
+ :colon="false"
85
+ :key="item.id || item.seq"
86
+ >
87
+ <div class="linebar-div" v-if="item.title">
88
+ <span>{{ item.title }}</span>
89
+ <a-divider />
90
+ </div>
91
+ <template v-else>
92
+ <a-divider />
93
+ </template>
94
+ </a-form-model-item>
95
+ </template>
96
+ <!-- 提示语 -->
97
+ <template v-else-if="item.type == 'PROMPT'">
98
+ <a-form-model-item
99
+ v-if="isShowItem(item)"
100
+ class="my-prompt"
101
+ :colon="false"
102
+ :key="item.id || item.seq"
103
+ >
104
+ <MyPrompt :key="item.id || item.seq" :options="item.setting" />
105
+ </a-form-model-item>
106
+ </template>
107
+ <template v-else-if="item.type == 'IMGCARD'">
108
+ <a-form-model-item
109
+ v-if="isShowItem(item)"
110
+ :colon="false"
111
+ :key="item.id || item.seq"
112
+ >
113
+ <a v-if="item.setting.imgLink" :href="item.setting.imgLink" target="_blank">
114
+ <img class="img-card" :src="item.setting.imgUrl" />
115
+ </a>
116
+ <img class="img-card" v-else :src="item.setting.imgUrl" />
117
+ </a-form-model-item>
118
+ </template>
119
+ <!-- 富文本 -->
120
+ <template v-else-if="item.type == 'RICH_TEXT'">
121
+ <div
122
+ :key="item.id || item.seq"
123
+ class="rich-text-content"
124
+ v-html="item.setting.defaultValue"
125
+ ></div>
126
+ </template>
127
+ <template v-else>
128
+ <a-form-model-item
129
+ v-if="isShowItem(item)"
130
+ :key="item.id || item.seq"
131
+ :prop="formKey(item)"
132
+ >
133
+ <span slot="label">
134
+ <span
135
+ :class="{ 'scale-label-required': isFormBoldOpen(item) }"
136
+ v-html="handleShowQuestionNumber(item)"
137
+ ></span>
138
+ <span class="required-text" v-if="isFormBoldOpen(item)">(必填)</span>
139
+ <span
140
+ class="evalute-label"
141
+ v-if="showEvaluateLabel(item)"
142
+ >{{ showEvaluateLabel(item) }}</span>
143
+ <template v-if="showEvatip(item)">
144
+ <span class="evalute-tip" @click="showEvaTipModal(item)">
145
+ <svg-icon icon-class="a-xitongtubiaotishi" />查看提示
146
+ </span>
147
+ </template>
148
+ </span>
149
+ <!-- 输入框 -->
150
+ <MyInput
151
+ v-bind="$attrs"
152
+ v-if="isInput(item.type)"
153
+ v-model="form[formKey(item)]"
154
+ :type="item.valueType"
155
+ :row="item.setting.inputRow || 1"
156
+ :defaultPlaceHolder="item.setting.defaultPlaceHolder"
157
+ :isLock="componentDisable"
158
+ />
159
+
160
+ <!-- 单选/下拉/多选/级联 -->
161
+ <MyChoice
162
+ v-bind="$attrs"
163
+ v-else-if="isChoice(item.type)"
164
+ v-model="form[formKey(item)]"
165
+ :item="item"
166
+ :isLock="componentDisable"
167
+ :curIndex="index"
168
+ :openType="openType"
169
+ @change="handleChoice($event, item)"
170
+ @radioChange="radioChange"
171
+ @checkboxChange="checkboxChange"
172
+ />
173
+ <!-- 日期/时间 -->
174
+ <MyTime
175
+ v-bind="$attrs"
176
+ v-else-if="isTime(item.type)"
177
+ :value="getTimeValue(item)"
178
+ :type="item.type"
179
+ :startToStop="item.setting.startToStop"
180
+ :dateType="item.setting.dateType"
181
+ :isLock="componentDisable"
182
+ @change="changeTime($event, item)"
183
+ />
184
+ <!-- 上传附件 or 图片 -->
185
+ <MyUpload
186
+ v-bind="$attrs"
187
+ v-else-if="isUpload(item.type)"
188
+ :upType="item.type"
189
+ :useFileList="item.dbValue"
190
+ :limitPic="item.setting.limitPic"
191
+ :isLock="componentDisable"
192
+ @change="changeUpload($event, item)"
193
+ />
194
+ <!-- 地图 -->
195
+ <div
196
+ v-else-if="item.type === 'LOCATION'"
197
+ @click="!isLock && (mapVisible = !mapVisible)"
198
+ :class="{ 'map-container': !isLock }"
199
+ >
200
+ <a-input
201
+ placeholder="请选择"
202
+ :value="handleGetAddress(form[formKey(item)])"
203
+ disabled
204
+ >
205
+ <a-icon slot="prefix" type="info-circle" />
206
+ </a-input>
207
+ <MapComp
208
+ v-bind="$attrs"
209
+ :visible.sync="mapVisible"
210
+ :locationProp="form[formKey(item)]"
211
+ :isLock="componentDisable"
212
+ @selectLocation="handleSelectLocation($event, item)"
213
+ />
214
+ </div>
215
+ <!-- 地址 -->
216
+ <MyAddress
217
+ v-bind="$attrs"
218
+ v-else-if="item.type === 'ADDRESS'"
219
+ :setting="item.setting"
220
+ :defaultValue="defaultAddress"
221
+ :isLock="componentDisable"
222
+ @change="changeAddress($event, item)"
223
+ />
224
+ <!-- 标签 -->
225
+ <label-form
226
+ v-bind="$attrs"
227
+ v-else-if="item.type === 'LABEL'"
228
+ :item="item"
229
+ :selectedList="labelSelectedList"
230
+ :isLock="componentDisable"
231
+ :sourceType="source"
232
+ @onChange="labelChange($event, item)"
233
+ />
234
+ <!-- 视频 -->
235
+ <vod-Chunk-upload
236
+ v-bind="$attrs"
237
+ v-else-if="item.type === 'VEDIO'"
238
+ :source="'guage'"
239
+ :formData="item"
240
+ :limitNum="item.setting.limitPic"
241
+ :defFileList="form[formKey(item)]"
242
+ :isLock="componentDisable"
243
+ @vodFileList="vodFileList($event, item)"
244
+ />
245
+ <!-- 答案解析 -->
246
+ <answerParse v-if="showAnswerParse(item)" :item="item"></answerParse>
247
+ </a-form-model-item>
248
+ </template>
249
+ </template>
250
+ </a-form-model>
251
+ </div>
252
+ <template v-if="type === 'customList'">
253
+ <div class="footer" v-if="!noBtn">
254
+ <a-button @click="cancel" v-if="false" style="margin-right: 8px;">取消</a-button>
255
+ <a-button @click="onSubmit" type="primary" :disabled="banSubmit">保存</a-button>
256
+ </div>
257
+ </template>
258
+ <template v-else>
259
+ <div class="footer" v-if="showSaveBtn">
260
+ <a-button @click="cancel" style="margin-right: 8px;">取消</a-button>
261
+ <a-button type="primary" v-if="!isLock" @click="onSubmit" :disabled="banSubmit">保存</a-button>
262
+ </div>
263
+ </template>
264
+ </template>
265
+ </template>
266
+ </slot>
267
+ </div>
268
+ </template>
269
+ <script>
270
+ import { Icon, Checkbox, Tree, Tooltip, Input, Spin, FormModel, Divider, Button } from 'ant-design-vue';
271
+ import create from '@/core/create';
272
+ import { MyChoice, MyInput, MyAddress, MyUpload, MyTime, MyPrompt } from './formitem';
273
+ import MapComp from '../map/src/popup-map';
274
+ import labelForm from '~/select-label/select-label';
275
+ import vodChunkUpload from '~/upload/chunk-upload/vod-chunk-upload.vue';
276
+ // import { EventBus } from "@/common/utils/eventBus.js";
277
+ import { judgeTypes } from './mixin/judgeTypes';
278
+ import NoDataJs from './mixin/NoData';
279
+ // import { mapGetters } from "vuex";
280
+ import moment from 'moment';
281
+ import utils from '@/utils/utils-map';
282
+ import evaluatePage from './evaluatePage.vue';
283
+ import evaluateCountdown from './evaluateCountdown.vue';
284
+ import answerParse from './answerParse.vue';
285
+ import vexutils from '@/utils/vexutils';
286
+ import NoData from './NoData.vue';
287
+ export default create({
288
+ name: 'scale-view',
289
+ mixins: [judgeTypes, NoDataJs],
290
+ props: {
291
+ ids: {
292
+ type: Object,
293
+ default: () => {
294
+ return { guage_id: '', db_id: undefined };
295
+ }
296
+ },
297
+ params: { default: () => ({}), type: Object },
298
+ guageData: { type: Object, default: () => ({}) },
299
+ noBtn: { type: Boolean, default: false },
300
+ hideBtn: { type: Boolean, default: false },
301
+ source: { type: String, default: '' },
302
+ isLock: { type: Boolean, default: false },
303
+ type: {
304
+ type: String,
305
+ default: ''
306
+ },
307
+ styleSetting: {
308
+ type: Object,
309
+ default: () => ({})
310
+ },
311
+
312
+ fontSizeObj: {
313
+ type: Object,
314
+ default: () => ({
315
+ large: 1.25,
316
+ medium: 1.1,
317
+ small: 1,
318
+ extrasmall: 0.9
319
+ })
320
+ },
321
+ openType: { type: String, default: '' },
322
+ scaleApiConfig: {
323
+ type: Object,
324
+ default: () => ({})
325
+ }
326
+ },
327
+ components: {
328
+ MyChoice,
329
+ MyInput,
330
+ MapComp,
331
+ MyAddress,
332
+ MyUpload,
333
+ MyTime,
334
+ MyPrompt,
335
+ labelForm,
336
+ vodChunkUpload,
337
+ [Icon.name]: Icon,
338
+ [Spin.name]: Spin,
339
+ [Tree.name]: Tree,
340
+ [Input.name]: Input,
341
+ [Input.Search.name]: Input.Search,
342
+ [Checkbox.name]: Checkbox,
343
+ [Divider.name]: Divider,
344
+ [Button.name]: Button,
345
+ [FormModel.name]: FormModel,
346
+ [FormModel.Item.name]: FormModel.Item,
347
+ [Tooltip.name]: Tooltip,
348
+ evaluatePage,
349
+ evaluateCountdown,
350
+ answerParse,
351
+ NoData
352
+ },
353
+ computed: {
354
+ queryformBoldOpen() {
355
+ return this.$route.query?.formBoldOpen == 1;
356
+ },
357
+ showEvatip() {
358
+ return function (item) {
359
+ if (!this.isEvaluation(item.type)) return false;
360
+ return this.$route.query?.evatip == 1 || this.params?.evatip == 1;
361
+ };
362
+ },
363
+ isFormBoldOpen() {
364
+ return function (item) {
365
+ let res = item.required;
366
+ // 量表未登录时 判断 url中是否有 formBoldOpen
367
+ if (!this.styleSetting || !Object.keys(this.styleSetting).length || !('formBoldOpen' in this.styleSetting)) {
368
+ return res && this.queryformBoldOpen;
369
+ }
370
+ return res && this.styleSetting.formBoldOpen;
371
+ };
372
+ },
373
+ scaleStyle() {
374
+ let fontSize = this.fontSize;
375
+ if (!fontSize || fontSize === 'S') return null;
376
+ const keyValue = {
377
+ L: 'large',
378
+ M: 'medium',
379
+ XS: 'extrasmall'
380
+ };
381
+ fontSize = keyValue[fontSize];
382
+ const scale = (fontSize && this.fontSizeObj[fontSize]) || 1;
383
+ const size = 10000;
384
+ const value = Math.floor((100 / scale) * size) / size;
385
+ return {
386
+ width: `${value}%`,
387
+ height: `${value}%`,
388
+ transform: `scale(${scale})`
389
+ };
390
+ },
391
+ handlePageClass() {
392
+ if (this.type == 'customList' && !this.noBtn) return false;
393
+ if (!this.noBtn && !this.hideBtn) return false;
394
+ return true;
395
+ },
396
+ isShowItem() {
397
+ return item => this.showEvent(item);
398
+ },
399
+ handleShowQuestionNumber() {
400
+ return function (item) {
401
+ let { type } = item || {};
402
+ let tempTile = this.config?.autoQuestionNumber === false ? item.showTitle : `${item.softcode}、${item.showTitle}`;
403
+ if (!this.isEvaluation(type)) return tempTile;
404
+
405
+ let score = this.handleEvaluationScore(item);
406
+ return `${tempTile}&nbsp;<span style="color:#2d7aff;">${score}</span>`;
407
+ // if (this.noBtn) {
408
+ // let score = this.handleEvaluationScore(item);
409
+ // return `${tempTile}&nbsp;<span style="color:#2d7aff;">${score}</span>`;
410
+ // }
411
+ // if (!this.isLock) {
412
+ // let score = this.handleEvaluationScore(item);
413
+ // return `${tempTile}&nbsp;<span style="color:#2d7aff;">${score}</span>`;
414
+ // }
415
+ // if (item.questionScore !== undefined) {
416
+ // return `${tempTile}&nbsp;<span style="color:#2d7aff;">(${item.questionScore}分)</span>`;
417
+ // }
418
+ // return tempTile;
419
+ };
420
+ },
421
+ hasScore() {
422
+ let { config } = this;
423
+ if (!config || !Object.keys(config).length) return false;
424
+ if ('totalScore' in config) return true;
425
+ return false;
426
+ },
427
+ // 预览按钮打开的量表页面
428
+ isPreviewScale() {
429
+ let guage_id = this.ids?.guage_id;
430
+ return guage_id && this.noBtn;
431
+ },
432
+ hasEvaluateSetting() {
433
+ let { config } = this;
434
+ if (!config || !Object.keys(config).length) return false;
435
+ if ('evaluateResult' in config && config.evaluateResult) return true;
436
+ return false;
437
+ },
438
+ getTimeValue() {
439
+ return function (item) {
440
+ let value = this.form[this.formKey(item)];
441
+ return value;
442
+ };
443
+ },
444
+ // 是否展示考试入口
445
+ showEvaluateEntry() {
446
+ // 非预览
447
+ // 有evaluateResultSetting || url中含有固定参数
448
+ // 倒计时未结束
449
+ // 未填写过
450
+ return !this.isPreviewScale && this.showEvaluatePage && this.showEvaluateSettingWrap && !this.isFinished && !this.noBtn && !this.hideBtn;
451
+ },
452
+ // 是否展示倒计时
453
+ showEvaluateCoundownPage() {
454
+ return !this.isPreviewScale && !this.showEvaluateEntry && this.showEvaluateCountdownWrap && !this.isFinished && !this.noBtn && !this.hideBtn;
455
+ },
456
+ // 是否设置 evaluateResultSetting
457
+ hasEvaluateResultSetting() {
458
+ let { evaluateResultSetting = {} } = this.config;
459
+ // 读取优先级为测评设置值(变量) > URL参数 > 测评设置值(固定值)
460
+ // 是否设置 evaluateResultSetting
461
+ let valueArr =
462
+ Object.values(evaluateResultSetting).filter(item => {
463
+ if (item) return true;
464
+ }) || [];
465
+ return valueArr.length;
466
+ },
467
+ hasparamsEvaluate() {
468
+ return this.paramsEvaluate && Object.keys(this.paramsEvaluate).length;
469
+ },
470
+ // url中是否有默认值
471
+ hasDefault() {
472
+ let hash = window.location.hash;
473
+ let defaultVariable = ['evaname', 'evadesc', 'evast', 'evadur', 'evaan'];
474
+ let hasDefault = defaultVariable.find(item => hash.includes(item));
475
+ return this.paramsEvaluate || hasDefault;
476
+ },
477
+ // 是否有提交按钮
478
+ showSaveBtn() {
479
+ // 无测评设置 && url中无固定参数
480
+ if (!this.hasEvaluateResultSetting && !this.hasDefault) {
481
+ return !this.noBtn && !this.hideBtn;
482
+ }
483
+ return !this.noBtn && !this.hideBtn && !this.isFinished;
484
+ },
485
+ // 组件是否 Disable
486
+ componentDisable() {
487
+ // 无测评设置 && url中无固定参数
488
+ if (!this.hasEvaluateResultSetting && !this.hasDefault) {
489
+ return this.hideBtn || this.isLock;
490
+ }
491
+ return this.hideBtn || this.isLock || this.isFinished;
492
+ },
493
+ showEvaluateLabel() {
494
+ return function (item) {
495
+ let obj = {
496
+ EVALUATE_RADIO_BLOCK: '单选题',
497
+ EVALUATE_CHECKBOX_BLOCK: '多选题'
498
+ };
499
+ return obj[item.type];
500
+ };
501
+ },
502
+ showAnswerParse() {
503
+ return function (item) {
504
+ let { evaluateAnswer, checkAnswerMode, evaluateStartTime, evaluateTime } = this.config?.evaluateResultSetting || {};
505
+ let arr = ['EVALUATE_RADIO_BLOCK', 'EVALUATE_CHECKBOX_BLOCK', 'EVALUATE_SELECT', 'EVALUATE_INPUT'];
506
+ let maxScore = item?.scoreConfigs || 0;
507
+ let isShow = evaluateAnswer && this.isFinished && arr.includes(item.type) && maxScore;
508
+ if (!evaluateStartTime || !evaluateTime || (checkAnswerMode && checkAnswerMode == 1)) return isShow;
509
+ if (!vexutils.isValidDate(new Date(evaluateStartTime))) return isShow;
510
+ // 答案解析时间 考试时间结束后
511
+ let endTime = moment(evaluateStartTime).add(evaluateTime, 'minutes');
512
+ let isRang = endTime.diff(moment(), 'seconds', true);
513
+ return isShow && isRang <= 0;
514
+ };
515
+ },
516
+ tipMsg() {
517
+ return this.type === 'customList' ? '保存' : '提交';
518
+ },
519
+ formKey() {
520
+ return function (item) {
521
+ return item.databaseTitle || item.title;
522
+ };
523
+ },
524
+ getEvaResColor() {
525
+ let { evaluateResultConfig = [], totalScore } = this.config || {};
526
+ totalScore = +totalScore || 0;
527
+ if (!evaluateResultConfig?.length || !totalScore) return '#2474FF';
528
+ let matchItem = evaluateResultConfig.find(item => item.startScore <= totalScore && totalScore <= item.endScore);
529
+ if (!matchItem) return '#2474FF';
530
+ return matchItem.color || '#2474FF';
531
+ }
532
+ },
533
+ watch: {
534
+ ids: {
535
+ immediate: true,
536
+ deep: true,
537
+ handler(newVal, oldVal) {
538
+ if (oldVal) {
539
+ if (newVal.guage_id) {
540
+ if (newVal.guage_id != oldVal.guage_id) {
541
+ this.init(newVal);
542
+ }
543
+ }
544
+ } else {
545
+ if (newVal.guage_id) this.init(newVal);
546
+ }
547
+ }
548
+ },
549
+ guageData: {
550
+ immediate: true,
551
+ deep: true,
552
+ handler(value) {
553
+ if (value) {
554
+ if (Object.keys(value || {}).length) {
555
+ // guageForm打开 重新请求重置之前的答案
556
+ this.form = {};
557
+ this.formArray = [];
558
+ const data = JSON.parse(JSON.stringify(value));
559
+ this.$nextTick(() => {
560
+ this.initForm(data);
561
+ });
562
+ }
563
+ }
564
+ }
565
+ }
566
+ },
567
+ data() {
568
+ return {
569
+ other: '',
570
+ form: {},
571
+ submitForm: {},
572
+ rules: {},
573
+ config: {},
574
+ formArray: [],
575
+ mapVisible: false,
576
+ mapLocation: '',
577
+ labelSelectedList: [],
578
+ defaultFormArray: [],
579
+ fontSize: '',
580
+ filterArr: ['SUCCESS_TIP', 'CALLBACK_INTERFACE', 'SPREAD_PARAMS', 'REDIRECT', 'FRONT_ADDRESS', 'RETURN_PATH'],
581
+ spinning: true,
582
+ indicator: <a-icon type="loading" style="font-size: 24px" spin />,
583
+ totalScore: undefined,
584
+ shareId: '',
585
+ currentTime: moment(),
586
+ showEvaluatePage: false,
587
+ showEvaluateSettingWrap: true,
588
+ showEvaluateCountdownWrap: false,
589
+ showEvaluateCountdown: false,
590
+ banSubmit: false,
591
+ isFinished: false,
592
+ maxScore: 0,
593
+ originConfig: {},
594
+ paramsEvaluate: null,
595
+ hasFrontAddress: true,
596
+ choiceComObj: {},
597
+ evatipMap: {} // 维护一个tip map避免重复请求
598
+ };
599
+ },
600
+ mounted() {
601
+ this.handleQuery();
602
+ if (this.noBtn) {
603
+ // EventBus.$on("guageSubmit", this.onSubmit);
604
+ }
605
+ },
606
+ beforeDestroy() {
607
+ // EventBus.$off("guageSubmit");
608
+ },
609
+ methods: {
610
+ init(configData) {
611
+ this.spinning = true;
612
+ try {
613
+ this.resetNodata();
614
+ this.initForm(configData);
615
+ } catch (error) {
616
+ this.spinning = false;
617
+ this.hasFrontAddress = false;
618
+ this.setNoData(true, error?.resultMsg, error?.result);
619
+ }
620
+ },
621
+ handleQuery() {
622
+ let { id } = this.$route.query;
623
+ id && (this.shareId = id);
624
+ },
625
+ initForm(data) {
626
+ let { list = [], map = {}, isFinished = false } = data;
627
+ let curUrl = this.handleFrontAddress(list);
628
+ if (curUrl) {
629
+ window.location.href = curUrl;
630
+ return;
631
+ }
632
+ map.maxScore && (this.maxScore = map.maxScore);
633
+ this.isFinished = isFinished;
634
+ if (data.isNotFilled) {
635
+ this.spinning = false;
636
+ this.hasFrontAddress = false;
637
+ this.setNoData(true, '未查询到量表填写记录');
638
+ return;
639
+ }
640
+ if (data.isLackCustomer) {
641
+ let _this = this;
642
+ // 校验用户环境
643
+ this.$info({
644
+ title: '已设置填写次数限制',
645
+ content: '请在包含用户信息的环境中打开此量表',
646
+ onOk() {
647
+ _this.$emit('onCloseSetting');
648
+ }
649
+ });
650
+ }
651
+ this.config = map;
652
+
653
+ if ('evaluateResultConfig' in map && utils.isJSON(map.evaluateResultConfig)) {
654
+ this.config.evaluateResultConfig = JSON.parse(map.evaluateResultConfig);
655
+ }
656
+ if ('evaluateResultSetting' in map && utils.isJSON(map.evaluateResultSetting)) {
657
+ this.config.evaluateResultSetting = JSON.parse(map.evaluateResultSetting);
658
+ // 随机测评
659
+ if (this.config?.randomId && this.config.evaluateResultSetting) {
660
+ this.config.evaluateResultSetting.evaluateName = this.config.name;
661
+ this.config.evaluateResultSetting.evaluateExplain = this.config.remark;
662
+ }
663
+ }
664
+
665
+ this.originConfig = JSON.parse(JSON.stringify(this.config));
666
+
667
+ if (this.params && Object.keys(this.params).length) {
668
+ let res = this.handleBtnParamsEvaluate(this.params);
669
+ res && Object.keys(res).length && (this.paramsEvaluate = res);
670
+ }
671
+
672
+ this.handleEvaluateParams(this.config.evaluateResultSetting);
673
+ this.handleShowEvaluate();
674
+
675
+ this.defaultFormArray = JSON.parse(JSON.stringify(list));
676
+ let filterArr = this.filterArr;
677
+ list = list.filter(v => !filterArr.includes(v.type));
678
+ this.formArray = this.formatArray(list || []);
679
+ this.form = this.defaultFormValue(this.formArray);
680
+ this.rules = this.formatRules(this.formArray);
681
+ this.fontSize = data.fontSize;
682
+ this.spinning = false;
683
+ this.hasFrontAddress = false;
684
+ },
685
+ handleFrontAddress(list) {
686
+ if (!list || !list.length) return;
687
+ let matchItem = list.find(item => item.type === 'FRONT_ADDRESS');
688
+ if (!matchItem || !Object.keys(matchItem).length) return;
689
+ let setting;
690
+ if (matchItem.setting && utils.isJSON(matchItem.setting)) {
691
+ setting = JSON.parse(matchItem.setting);
692
+ }
693
+ if (!setting || !Object.keys(setting).length) return;
694
+ let query = this.handleQueryParams();
695
+ // redirect=1 代表从前置地址跳转回来了
696
+ if (query?.redirect == 1) return;
697
+ let { frontAddress } = setting;
698
+ if (frontAddress) {
699
+ let urlHref = window.location.href;
700
+ let preStr = '?';
701
+ if (frontAddress.includes('?')) {
702
+ preStr = '&';
703
+ }
704
+ let curUrl = `${frontAddress}${preStr}redirect_url=${encodeURIComponent(urlHref)}`;
705
+ return curUrl;
706
+ }
707
+ },
708
+ handleBtnParamsEvaluate(params) {
709
+ let defaultVariable = ['evaname', 'evadesc', 'evast', 'evadur', 'evaan'];
710
+ let res = {};
711
+ for (let key in params) {
712
+ let value = params[key];
713
+ if (defaultVariable.includes(key) && value) {
714
+ res[key] = value;
715
+ }
716
+ }
717
+ return res;
718
+ },
719
+ /** *
720
+ * 解析测评参数
721
+ */
722
+ handleEvaluateParams(evaluateResultSetting) {
723
+ if (!evaluateResultSetting || !Object.keys(evaluateResultSetting).length) return;
724
+ // 分享测评量表链接URL支持传入测评名称-evaname 测评说明-evadesc 测评时间-evast 测评时长-evadur 固定参数
725
+ let query = this.handleQueryParams();
726
+ // 按钮传参
727
+ if (this.hasparamsEvaluate) {
728
+ query = this.paramsEvaluate;
729
+ }
730
+ let obj = {
731
+ evaluateName: 'evaname',
732
+ evaluateExplain: 'evadesc',
733
+ evaluateStartTime: 'evast',
734
+ evaluateTime: 'evadur',
735
+ evaluateAnswer: 'evaan'
736
+ };
737
+ for (let key in evaluateResultSetting) {
738
+ let value = evaluateResultSetting[key];
739
+ let isParseKey = value && key != 'evaluateAnswer' && typeof value === 'string' && value.includes('${');
740
+ if (isParseKey) {
741
+ let parseValue = value.replace(/\$\{([^}]+)\}/g, (_v, $1) => {
742
+ let param;
743
+ if ($1.startsWith('form.')) {
744
+ param = query[$1.split('.')[1]];
745
+ }
746
+ return param || '';
747
+ });
748
+ this.$set(evaluateResultSetting, key, parseValue);
749
+ } else {
750
+ let val = query[obj[key]];
751
+ if (key == 'evaluateAnswer') {
752
+ val = val === 'true' || val == 1 ? true : false;
753
+ }
754
+ query[obj[key]] && this.$set(evaluateResultSetting, key, val);
755
+ }
756
+ }
757
+ // 部分evaluateResultSetting 但是却有url
758
+ if (this.hasDefault) {
759
+ let defaultVariable = ['evaname', 'evadesc', 'evast', 'evadur', 'evaan'];
760
+ let defObj = {
761
+ evaname: 'evaluateName',
762
+ evadesc: 'evaluateExplain',
763
+ evast: 'evaluateStartTime',
764
+ evadur: 'evaluateTime',
765
+ evaan: 'evaluateAnswer'
766
+ };
767
+ defaultVariable.forEach(item => {
768
+ let key = defObj[item];
769
+ if (!evaluateResultSetting[key]) {
770
+ let val = query[item];
771
+ if (item == 'evaan') {
772
+ val = val === 'true' || val == 1 ? true : false;
773
+ }
774
+ query[item] && this.$set(evaluateResultSetting, key, val);
775
+ }
776
+ });
777
+ }
778
+ this.setEvaluateStartTime(evaluateResultSetting);
779
+ },
780
+ handleQueryParams() {
781
+ let params = {};
782
+ for (let [key, value] of new URLSearchParams(window.location.hash.split('?')[1]).entries()) {
783
+ params[key] = decodeURIComponent(value);
784
+ }
785
+ return params;
786
+ },
787
+ handleShowEvaluate() {
788
+ // 读取优先级为测评设置值(变量) > URL参数 > 测评设置值(固定值)
789
+ // 无 evaluateResultSetting
790
+ if (!this.hasEvaluateResultSetting) {
791
+ // url中是否有默认值
792
+ // 无默认值 不显示考试入口页面
793
+ if (!this.hasDefault) return false;
794
+ // 有默认值 显示考试入口页面
795
+ if (!('evaluateResultSetting' in this.config)) {
796
+ this.$set(this.config, 'evaluateResultSetting', {});
797
+ }
798
+ this.setDefaultEvaluate(this.config.evaluateResultSetting);
799
+ this.showEvaluatePage = true;
800
+ this.showEvaluateCountdownWrap = true;
801
+ return;
802
+ }
803
+
804
+ let { evaluateResultSetting = {} } = this.config;
805
+ if (!evaluateResultSetting || !Object.keys(evaluateResultSetting).length) return;
806
+ this.showEvaluateCountdownWrap = true;
807
+
808
+ // 只要有开始时间都显示测评组件
809
+ let { evaluateStartTime } = evaluateResultSetting;
810
+ let { evaluateName } = this.originConfig?.evaluateResultSetting || {};
811
+ // 未设置开始时间 一直可以填写
812
+ if (!evaluateStartTime) {
813
+ this.showEvaluatePage = true;
814
+ return;
815
+ }
816
+ if (!vexutils.isValidDate(new Date(evaluateStartTime))) {
817
+ if (!evaluateName) return false;
818
+ }
819
+ this.showEvaluatePage = true;
820
+ },
821
+ setDefaultEvaluate(evaluateResultSetting) {
822
+ let query = this.handleQueryParams();
823
+ // 按钮传参
824
+ if (this.hasparamsEvaluate) {
825
+ query = this.paramsEvaluate;
826
+ }
827
+ if (query.evaname) {
828
+ this.$set(evaluateResultSetting, 'evaluateName', query.evaname);
829
+ }
830
+ if (query.evadesc) {
831
+ this.$set(evaluateResultSetting, 'evaluateExplain', query.evadesc);
832
+ }
833
+ if (query.evast) {
834
+ this.$set(evaluateResultSetting, 'evaluateStartTime', query.evast);
835
+ }
836
+ if (query.evadur) {
837
+ this.$set(evaluateResultSetting, 'evaluateTime', query.evadur);
838
+ }
839
+ if (query.evaan) {
840
+ let evaan = query.evaan === 'true' || query.evaan == 1 ? true : false;
841
+ this.$set(evaluateResultSetting, 'evaluateAnswer', evaan);
842
+ }
843
+
844
+ this.setEvaluateStartTime(evaluateResultSetting);
845
+ },
846
+ // 时间戳需要是数字
847
+ setEvaluateStartTime(evaluateResultSetting) {
848
+ let evaluateStartTime = evaluateResultSetting?.evaluateStartTime;
849
+ if (!evaluateStartTime) return;
850
+ if (!vexutils.isValidDate(new Date(evaluateStartTime)) && vexutils.isValidDate(new Date(Number(evaluateStartTime)))) {
851
+ evaluateResultSetting.evaluateStartTime = Number(evaluateStartTime);
852
+ }
853
+ },
854
+ // 量表提交数据
855
+ defaultFormValue(formArray) {
856
+ const formData = {};
857
+ let val;
858
+ formArray.forEach(item => {
859
+ const key = this.formKey(item);
860
+ const { type } = item;
861
+ let defValue;
862
+ if (item.dbValue) {
863
+ defValue = item.dbValue;
864
+ } else {
865
+ if (item.setting?.defValType == 3) {
866
+ let urlKey = item.setting?.outDefaultValue?.urlKey;
867
+ if (urlKey) {
868
+ let list = urlKey.split(',');
869
+ if (list.length > 1) {
870
+ let val = list
871
+ .map(l => {
872
+ let tempV = this.getQueryVariable(l);
873
+ if (tempV) return decodeURIComponent(tempV);
874
+ return null;
875
+ })
876
+ .filter(Boolean);
877
+ val.length && (defValue = val);
878
+ } else {
879
+ let val = this.getQueryVariable(list[0]);
880
+ if (val) {
881
+ val = decodeURIComponent(val);
882
+ defValue = item.type == 'CHECKBOX_BLOCK' ? val.split() : val;
883
+ }
884
+ }
885
+ }
886
+ }
887
+ }
888
+ switch (type) {
889
+ case 'LOCATION':
890
+ formData[key] = defValue || '';
891
+ break;
892
+ case 'SEARCH_CASCADE':
893
+ formData[key] = defValue || [];
894
+ break;
895
+ case 'ADDRESS':
896
+ formData[key] = defValue || '';
897
+ this.defaultAddress = defValue || {};
898
+ break;
899
+ case 'LABEL':
900
+ formData[key] = defValue || {};
901
+ if (vexutils.isObject(defValue)) {
902
+ this.labelSelectedList = defValue?.labels || [];
903
+ } else if (Array.isArray(defValue)) {
904
+ this.labelSelectedList = defValue;
905
+ } else {
906
+ this.labelSelectedList = [];
907
+ }
908
+ break;
909
+ case 'TITLE':
910
+ formData[key] = item.title;
911
+ break;
912
+ case 'IMGCARD':
913
+ formData[key] = item.setting?.imgUrl || '';
914
+ break;
915
+ case 'UPFILE':
916
+ case 'UPPICTURE':
917
+ formData[key] = defValue || [];
918
+ break;
919
+ // 自定义列表特殊处理
920
+ case 'CHECKBOX_BLOCK':
921
+ if (defValue && !Array.isArray(defValue) && this.type === 'customList') {
922
+ formData[key] = defValue.split(',').filter(ii => !!ii);
923
+ } else {
924
+ val = defValue || item.setting.defaultValue;
925
+ if (vexutils.isJSON(val)) {
926
+ val = JSON.parse(val);
927
+ }
928
+ formData[key] = val;
929
+ }
930
+ break;
931
+ default:
932
+ val = defValue || item.setting.defaultValue;
933
+ if (vexutils.isJSON(val)) {
934
+ val = JSON.parse(val);
935
+ }
936
+ formData[key] = val;
937
+ break;
938
+ }
939
+ });
940
+ return formData;
941
+ },
942
+ // 解析传参组件
943
+ compileSpreadParams(spreadParams) {
944
+ return spreadParams.domains.map(v => {
945
+ let obj = {};
946
+ if (v.valueType == '1') {
947
+ obj[v.name] = v.value;
948
+ } else if (v.valueType == '2') {
949
+ obj[v.name] = this.getQueryVariable(v.value);
950
+ }
951
+ return obj;
952
+ });
953
+ },
954
+ // 获取url链接参数
955
+ getQueryVariable(variable) {
956
+ let query = {};
957
+ if (this.source == 'layout') {
958
+ // 按钮传参
959
+ query = this.params;
960
+ } else {
961
+ query = this.handleQueryParams() || {};
962
+ }
963
+ if (!query) return false;
964
+ return query[variable] || false;
965
+ },
966
+ // 初始化量表
967
+ formatArray(list) {
968
+ let i = 1;
969
+ const results = list.map(item => {
970
+ const key = this.formKey(item);
971
+ let title = (key || '').replace(/\n/g, '');
972
+ this.$set(item, 'showTitle', item.title);
973
+ // 表单校验rule prop如果有 . 会报错, 替换成 ~-~
974
+ if (title.includes('.')) {
975
+ let newTitle = title.replace(/\./g, '~-~');
976
+ this.$set(item, 'title', newTitle);
977
+ }
978
+ this.$set(item, 'isShow', true);
979
+ Object.keys(item).forEach(key => {
980
+ if (utils.isJSON(item[key])) {
981
+ if (item.type != 'LOCATION') {
982
+ item[key] = JSON.parse(item[key]);
983
+ }
984
+ }
985
+ });
986
+ const notIndexArr = ['LINEBAR', 'TITLE', 'PROMPT', 'IMGCARD', 'RICH_TEXT'];
987
+ if (notIndexArr.indexOf(item.type) < 0 && !item.hide) {
988
+ this.$set(item, 'softcode', i++);
989
+ }
990
+
991
+ // "RADIO_BLOCK", "CHECKBOX_BLOCK" 将取值value改为key
992
+ if (this.isChoice(item.type)) {
993
+ this.handleFormatOptions(item.options, item.type);
994
+ if (item.type != 'SEARCH_CASCADE') {
995
+ if (item.dbValue) {
996
+ this.nextLogicEvent(item.dbValue, item, results, true);
997
+ } else {
998
+ if (item.setting.defaultValue) {
999
+ this.nextLogicEvent(item.setting.defaultValue, item, results, true);
1000
+ }
1001
+ }
1002
+ }
1003
+ }
1004
+ return item;
1005
+ });
1006
+ return results.map(item => {
1007
+ // 题目关联
1008
+ let relationLogicObj = utils.isString(item.relationLogic) ? JSON.parse(item.relationLogic) : item.relationLogic;
1009
+ this.handleRelationLogic(list, relationLogicObj);
1010
+
1011
+ // 跳题逻辑
1012
+ this.handLenextLogic(item);
1013
+
1014
+ // 自定义列表特殊处理
1015
+ if (item.type === 'CHECKBOX_BLOCK' && item.dbValue && !Array.isArray(item.dbValue) && this.type === 'customList') {
1016
+ item.dbValue = item.dbValue.split(',').filter(ii => !!ii);
1017
+ }
1018
+ return item;
1019
+ });
1020
+ },
1021
+ /**
1022
+ * "RADIO_BLOCK", "CHECKBOX_BLOCK" 将取值value改为key, relationLogic需要重新处理
1023
+ */
1024
+ handleRelationLogic(list, relationLogicObj) {
1025
+ let { condition } = relationLogicObj || {};
1026
+ if (!condition || !condition.length) return;
1027
+ condition.forEach(c => {
1028
+ let matchItem = list.find(f => f.seq == c.subject_seq);
1029
+ if (!matchItem) return;
1030
+ let isChoice = this.isRadioOrCheckBox(matchItem.options, matchItem.type);
1031
+ if (!isChoice) return;
1032
+ let value = c.value;
1033
+ if (Array.isArray(value)) {
1034
+ value = value.map(v => {
1035
+ return this.replaceConditionItem(matchItem.options, v);
1036
+ });
1037
+ c.value = value;
1038
+ } else {
1039
+ c.value = this.replaceConditionItem(matchItem.options, value);
1040
+ }
1041
+ });
1042
+ },
1043
+ /**
1044
+ * "RADIO_BLOCK", "CHECKBOX_BLOCK" 将取值value改为key, nextLogic需要重新处理
1045
+ */
1046
+ handLenextLogic(item) {
1047
+ let { nextLogic, options, type } = item || {};
1048
+ let isChoice = this.isRadioOrCheckBox(options, type);
1049
+ if (!nextLogic || !isChoice) return;
1050
+ let { condition } = nextLogic || {};
1051
+ if (!condition || !condition.length) return;
1052
+ condition.forEach(c => {
1053
+ let value = c.value;
1054
+ if (Array.isArray(value)) {
1055
+ value = value.map(v => {
1056
+ return this.replaceConditionItem(options, v);
1057
+ });
1058
+ c.value = value;
1059
+ } else {
1060
+ c.value = this.replaceConditionItem(options, value);
1061
+ }
1062
+ });
1063
+ },
1064
+ replaceConditionItem(options, value) {
1065
+ let matchOption = options.find(v => value === v.value);
1066
+ if (!matchOption) return value;
1067
+ return matchOption.key;
1068
+ },
1069
+ isRadioOrCheckBox(options, type) {
1070
+ let typeArr = ['RADIO_BLOCK', 'CHECKBOX_BLOCK'];
1071
+ if (!typeArr.includes(type)) return;
1072
+ if (!options) return;
1073
+ if (options && utils.isJSON(options)) {
1074
+ options = JSON.parse(options);
1075
+ }
1076
+ if (!options.length) return;
1077
+ return true;
1078
+ },
1079
+ handleFormatOptions(options, type) {
1080
+ let isChoice = this.isRadioOrCheckBox(options, type);
1081
+ if (!isChoice) return;
1082
+
1083
+ options.forEach((item, i) => {
1084
+ if (item.key !== 'other') {
1085
+ item.key = i + 1;
1086
+ }
1087
+ if (item.prefix || item.suffix) {
1088
+ item.value = item.prefix || item.suffix;
1089
+ }
1090
+ });
1091
+ },
1092
+ // 初始化rules
1093
+ formatRules(formArray) {
1094
+ const rules = {};
1095
+ formArray.forEach(item => {
1096
+ let newTitle = this.formKey(item);
1097
+ // 表单校验rule prop如果有 . 会报错, 替换成 ~-~
1098
+ if (newTitle.includes('.')) {
1099
+ newTitle = newTitle.replace(/\./g, '~-~');
1100
+ }
1101
+ rules[newTitle] = [{ required: item.required, message: '必填', trigger: 'change' }];
1102
+ if (item.type == 'MOBILE' && item.validation) {
1103
+ rules[newTitle].push({
1104
+ pattern: /^1[3456789]\d{9}$/,
1105
+ message: '格式错误',
1106
+ trigger: 'blur'
1107
+ });
1108
+ } else if (item.type == 'ID_CARD' && item.validation) {
1109
+ rules[newTitle].push({
1110
+ pattern: /^\d{6}(((19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])\d{3}([0-9]|x|X))|(\d{2}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])\d{3}))$/,
1111
+ message: '格式错误',
1112
+ trigger: 'blur'
1113
+ });
1114
+ } else if (item.type == 'ADDRESS' && item.required) {
1115
+ if (this.handleAddressType(item)) {
1116
+ rules[newTitle].push({
1117
+ validator: this.checkAdress,
1118
+ trigger: 'change'
1119
+ });
1120
+ }
1121
+ } else if (item.type == 'LABEL' && item.required) {
1122
+ rules[newTitle].push({
1123
+ validator: this.checkLabel,
1124
+ trigger: 'change'
1125
+ });
1126
+ } else if (item.type == 'DATETIME' && this.type == 'customList') {
1127
+ // 自定义列表特殊处理日期时间 最大值
1128
+ // dateMaxType 1当前日期时间 2指定日期时间 3其他日期时间字段
1129
+ let dateMaxType = this.handleDateMaxType(item);
1130
+ if (!dateMaxType) return;
1131
+ let obj = {
1132
+ 1: 'checkDateMaxCur',
1133
+ 2: 'checkDateMaxSet',
1134
+ 3: 'checkDateMaxOther'
1135
+ };
1136
+ let methodName = obj[dateMaxType];
1137
+ rules[newTitle].push({
1138
+ validator: (rule, value, callback) => this[methodName](rule, value, callback, item),
1139
+ trigger: 'change'
1140
+ });
1141
+ } else if (item.type === 'RADIO_BLOCK') {
1142
+ this.choiceComObj[this.formKey(item)] = {};
1143
+ rules[newTitle].push({
1144
+ validator: (rule, value, callback) => this.checkRadio(rule, value, callback, item),
1145
+ trigger: 'change'
1146
+ });
1147
+ } else if (item.type === 'CHECKBOX_BLOCK') {
1148
+ this.choiceComObj[this.formKey(item)] = {};
1149
+ rules[newTitle].push({
1150
+ validator: (rule, value, callback) => this.checkCheckbox(rule, value, callback, item),
1151
+ trigger: 'change'
1152
+ });
1153
+ }
1154
+ });
1155
+ return rules;
1156
+ },
1157
+ handleAddressType(item) {
1158
+ let setObj = { addressType: 'province-city-district-address' };
1159
+ if (utils.isJSON(item.setting)) {
1160
+ setObj = JSON.parse(item.setting);
1161
+ } else {
1162
+ setObj = item.setting;
1163
+ }
1164
+ let isAdress = setObj.addressType.includes('address');
1165
+ return isAdress;
1166
+ },
1167
+ checkAdress(rule, value, callback) {
1168
+ let { address } = value || {};
1169
+ if (!address) {
1170
+ return callback(new Error('必填'));
1171
+ }
1172
+ callback();
1173
+ },
1174
+ checkLabel(rule, value, callback) {
1175
+ if (!value || !Object.keys(value).length) {
1176
+ return callback(new Error('必填'));
1177
+ }
1178
+ let { labelStr, labels = [] } = value;
1179
+ if (!labelStr || !labels.length) {
1180
+ return callback(new Error('必填'));
1181
+ }
1182
+ callback();
1183
+ },
1184
+ handleDateMaxType(item) {
1185
+ let setObj = item.setting;
1186
+ if (utils.isJSON(setObj)) {
1187
+ setObj = JSON.parse(setObj);
1188
+ }
1189
+ return setObj.dateMaxType;
1190
+ },
1191
+ // 自定义列表 日期时间 max 当前日期时间
1192
+ checkDateMaxCur(rule, value, callback, item) {
1193
+ if (!value) return callback();
1194
+ let { dateType } = item.setting;
1195
+ if (!dateType) return callback();
1196
+ let dateMaxValue = this.currentTime;
1197
+ if (dateType == 'time') {
1198
+ dateMaxValue = this.currentTime.format('HH:mm:ss');
1199
+ }
1200
+ let isMax = this.handleMax(dateType, value, dateMaxValue);
1201
+ if (!isMax) {
1202
+ return callback(new Error('最大不能超过当前日期时间'));
1203
+ }
1204
+ callback();
1205
+ },
1206
+ // 自定义列表 日期时间 max 指定日期时间
1207
+ checkDateMaxSet(rule, value, callback, item) {
1208
+ if (!value) return callback();
1209
+ let { dateMaxValue, dateType } = item.setting;
1210
+ if (!dateMaxValue || !dateType) return callback();
1211
+ let isMax = this.handleMax(dateType, value, dateMaxValue);
1212
+ if (!isMax) {
1213
+ return callback(new Error('最大不能超过指定日期时间'));
1214
+ }
1215
+ callback();
1216
+ },
1217
+ // 自定义列表 日期时间 max 其他日期时间字段
1218
+ checkDateMaxOther(rule, value, callback, item) {
1219
+ if (!value) return callback();
1220
+ let { outDateMaxValue, dateType } = item.setting;
1221
+ if (!outDateMaxValue || !dateType) return callback();
1222
+ let matchDateItem = this.formArray.find(v => v.seq === outDateMaxValue);
1223
+ if (!matchDateItem || matchDateItem.hide) return callback();
1224
+ let matchValue = this.form[this.formKey(matchDateItem)];
1225
+ if (!matchValue) return;
1226
+ let isMax = this.handleMax(dateType, value, matchValue);
1227
+ if (!isMax) {
1228
+ return callback(new Error(`最大不能超过【${matchDateItem.title}】日期时间`));
1229
+ }
1230
+ callback();
1231
+ },
1232
+ checkRadio(rule, value, callback, item) {
1233
+ if (!value) return callback();
1234
+ let { options } = item;
1235
+ if (!options.length || value === 'other') return callback();
1236
+ const key = this.formKey(item);
1237
+ let { optionsPreSuffixObj = {} } = this.choiceComObj[key] || {};
1238
+ let matchItem = options.find((o, i) => {
1239
+ if (i + 1 === value) {
1240
+ return true;
1241
+ }
1242
+ return false;
1243
+ });
1244
+ if (!matchItem || matchItem.importability) return callback();
1245
+ if (matchItem.prefix || matchItem.suffix) {
1246
+ let inputValue = optionsPreSuffixObj[value];
1247
+ if (!inputValue) {
1248
+ return callback(new Error(`请完善选项`));
1249
+ }
1250
+ }
1251
+ callback();
1252
+ },
1253
+ checkCheckbox(rule, value, callback, item) {
1254
+ if (!value || !value.length) return callback();
1255
+ let { options } = item;
1256
+ if (!options.length) return callback();
1257
+ let i = 0,
1258
+ len = value.length,
1259
+ v;
1260
+ const key = this.formKey(item);
1261
+ let { optionsPreSuffixObj = {} } = this.choiceComObj[key] || {};
1262
+ for (; i < len; i++) {
1263
+ v = value[i];
1264
+ if (v === 'other') continue;
1265
+ let matchItem = options.find((o, j) => {
1266
+ if (j + 1 === v) {
1267
+ return true;
1268
+ }
1269
+ return false;
1270
+ });
1271
+ if (!matchItem || matchItem.importability) continue;
1272
+
1273
+ if (matchItem.prefix || matchItem.suffix) {
1274
+ let inputValue = optionsPreSuffixObj[v];
1275
+ if (!inputValue) {
1276
+ return callback(new Error(`请完善选项`));
1277
+ }
1278
+ }
1279
+ }
1280
+ callback();
1281
+ },
1282
+ handleMax(dateType, value, dateMaxValue) {
1283
+ let curValue = '';
1284
+ let tempValue = '';
1285
+ if (dateType == 'time') {
1286
+ let curYMD = this.currentTime.format('YYYY MM DD ');
1287
+ curValue = moment(curYMD + dateMaxValue).valueOf();
1288
+ tempValue = moment(curYMD + value).valueOf();
1289
+ } else if (dateType == 'date') {
1290
+ curValue = moment(dateMaxValue).valueOf();
1291
+ tempValue = moment(value).valueOf();
1292
+ } else {
1293
+ curValue = moment(dateMaxValue).valueOf();
1294
+ tempValue = moment(value).valueOf();
1295
+ }
1296
+ if (tempValue > curValue) {
1297
+ return false;
1298
+ }
1299
+ return true;
1300
+ },
1301
+ handleGetAddress(val) {
1302
+ if (utils.isJSON(val)) {
1303
+ const valObj = JSON.parse(val);
1304
+ return valObj.address || valObj.name;
1305
+ }
1306
+ return '';
1307
+ },
1308
+ handleSelectLocation(e, item) {
1309
+ const { locationProp, isInit } = e;
1310
+ this.mapLocation = locationProp;
1311
+ const key = this.formKey(item);
1312
+ this.form[key] = locationProp;
1313
+ this.mapVisible = isInit || false;
1314
+ },
1315
+ isInput(type) {
1316
+ return type == 'INPUT' || type == 'ID_CARD' || type == 'MOBILE' || type == 'EVALUATE_INPUT';
1317
+ },
1318
+ isChoice(type) {
1319
+ return (
1320
+ type == 'SELECT' ||
1321
+ type == 'RADIO_BLOCK' ||
1322
+ type == 'CHECKBOX_BLOCK' ||
1323
+ type == 'SEARCH_CASCADE' ||
1324
+ type == 'EVALUATE_RADIO_BLOCK' ||
1325
+ type == 'EVALUATE_CHECKBOX_BLOCK' ||
1326
+ type == 'EVALUATE_SELECT'
1327
+ );
1328
+ },
1329
+ isTime(type) {
1330
+ return type == 'DATE' || type == 'TIME' || type == 'DATETIME';
1331
+ },
1332
+ isUpload(type) {
1333
+ return type == 'UPFILE' || type == 'UPPICTURE';
1334
+ },
1335
+ writeGuage(showCountdown) {
1336
+ this.showEvaluateSettingWrap = false;
1337
+ this.showEvaluateCountdown = showCountdown;
1338
+ },
1339
+ closeEvaluateCountdown() {
1340
+ // 倒计时结束自动提交 无需校验
1341
+ this.showEvaluateCountdown = false;
1342
+ if (this.isPreviewScale) return;
1343
+ this.banSubmit = true;
1344
+ this.submitMethod();
1345
+ this.$warning({
1346
+ title: '温馨提示',
1347
+ content: '测评时间到了,结束测评!',
1348
+ okText: '确定',
1349
+ onOk: () => {}
1350
+ });
1351
+ },
1352
+ async showEvaTipModal(item) {
1353
+ if (this.evatipMap[item.id]) {
1354
+ this.evatipConfirm(this.evatipMap[item.id]);
1355
+ return;
1356
+ }
1357
+ let key = 'getSubjectAnswer';
1358
+ const fn = this.scaleApiConfig?.[key] || null;
1359
+ if (!fn || typeof fn !== 'function') {
1360
+ this.$message.error(`${key} Is not a function`);
1361
+ return;
1362
+ }
1363
+ let obj = await fn(item.id);
1364
+ if (!obj) return;
1365
+ if (!this.evatipMap[item.id]) {
1366
+ this.evatipMap[item.id] = obj;
1367
+ this.evatipConfirm(obj);
1368
+ }
1369
+ },
1370
+ closeTip() {
1371
+ this.$destroyAll();
1372
+ },
1373
+ evatipConfirm(str) {
1374
+ let _this = this;
1375
+ let content = h => (
1376
+ <div class="evatip-container">
1377
+ <a-icon type="close" class="tip-content-close" on-click={_this.closeTip} />
1378
+ <span>答案解析:</span>
1379
+ <p>{str}</p>
1380
+ </div>
1381
+ );
1382
+ this.$confirm({
1383
+ title: '提示',
1384
+ icon: () => null,
1385
+ content,
1386
+ okText: '确定',
1387
+ cancelText: '关闭',
1388
+ onOk() {},
1389
+ onCancel() {},
1390
+ class: 'evatip-modal-wrap'
1391
+ });
1392
+ },
1393
+ // 选择组件
1394
+ handleChoice(choiceValue, formItem) {
1395
+ let { value = '', list = [] } = choiceValue;
1396
+ this.nextLogicEvent(value, formItem, this.formArray);
1397
+ this.handleDynamicDataRelation(list, formItem, this.formArray);
1398
+ },
1399
+ // 下拉框 动态数据源关联字段
1400
+ handleDynamicDataRelation(list, formItem, formArray) {
1401
+ let { targetSource } = formItem;
1402
+ if (!targetSource || !Object.keys(targetSource).length) return;
1403
+ if (!targetSource.target_id) return;
1404
+ let { relationParam = [] } = targetSource;
1405
+ if (!relationParam.length) return;
1406
+ relationParam.forEach(item => {
1407
+ let matchEle = formArray.find(v => v.seq === item.relationElement);
1408
+ const key = this.formKey(matchEle);
1409
+ if (matchEle) {
1410
+ if (!list.length) {
1411
+ this.form[key] = '';
1412
+ } else {
1413
+ let relationFieldList = list.map(v => v[item.relationField] || '/') || '';
1414
+ this.form[key] = relationFieldList.join(',');
1415
+ }
1416
+ }
1417
+ });
1418
+ },
1419
+ // 设置的logic condition 最大next_subject
1420
+ handleLogicMaxNext(condition = []) {
1421
+ const arr = condition.map(({ next_subject }) => (next_subject == 'end' ? 9999 : +(next_subject || 9999)));
1422
+ const max = Math.max.call(null, ...arr);
1423
+ return max;
1424
+ },
1425
+ // 当前formItem 下一个触发logicCodition item 的seq
1426
+ handleLogicList(formItem, formArray) {
1427
+ const { seq } = formItem;
1428
+ let list = formArray.map(item => {
1429
+ if (item.seq > seq && item.isShow && item.__isLogic__) return item;
1430
+ return false;
1431
+ });
1432
+ let nextItemMax = 0;
1433
+ let i = 0,
1434
+ len = list.length,
1435
+ item;
1436
+ for (; i < len; i++) {
1437
+ item = list[i];
1438
+ let curVal = this.form[this.formKey(item)];
1439
+ if (!curVal) continue;
1440
+ if (Array.isArray(curVal)) {
1441
+ if (!curVal.length) continue;
1442
+ }
1443
+ const { nextLogic, seq, __isLogic__, __lastSeq__ } = item;
1444
+ if (!nextLogic.next_logic_is || !nextLogic.condition.length) continue;
1445
+ if (__lastSeq__) {
1446
+ nextItemMax = __lastSeq__;
1447
+ break;
1448
+ }
1449
+ }
1450
+ return nextItemMax;
1451
+ },
1452
+ // 跳题逻辑
1453
+ nextLogicEvent(choiceValue, formItem, formArray = [], isInit) {
1454
+ const { nextLogic, seq } = formItem;
1455
+ if (!nextLogic) return;
1456
+ if (nextLogic.next_logic_is && nextLogic.condition.length) {
1457
+ let nextMax = 9999,
1458
+ nextItemMax = 0;
1459
+ if (!isInit) {
1460
+ nextMax = this.handleLogicMaxNext(nextLogic.condition);
1461
+ nextItemMax = this.handleLogicList(formItem, formArray);
1462
+ }
1463
+ nextLogic.condition.some(con => {
1464
+ const { value, next_subject } = con;
1465
+ const lastSeq = next_subject == 'end' ? 9999 : next_subject;
1466
+ if (nextItemMax && nextItemMax > seq && nextItemMax < nextMax) {
1467
+ nextMax = nextItemMax;
1468
+ }
1469
+ if (nextLogic.next_logic == 'condition') {
1470
+ let hasValue = false;
1471
+ if (Array.isArray(choiceValue)) {
1472
+ hasValue = choiceValue.includes(value);
1473
+ } else {
1474
+ hasValue = choiceValue === value;
1475
+ }
1476
+
1477
+ // 添加非响应式key __isLogic__ __lastSeq__
1478
+ Object.defineProperty(formItem, '__isLogic__', {
1479
+ value: hasValue,
1480
+ writable: true
1481
+ });
1482
+ Object.defineProperty(formItem, '__lastSeq__', {
1483
+ value: seq + 1,
1484
+ writable: true
1485
+ });
1486
+
1487
+ if (hasValue) {
1488
+ formArray.forEach(item => {
1489
+ if (item.seq > seq && item.seq < lastSeq) {
1490
+ item.isShow = false;
1491
+ // 跳过时 清空已填内容
1492
+ const key = this.formKey(item);
1493
+ this.form[key] && (this.form[key] = '');
1494
+ } else if (item.seq >= lastSeq && item.seq < nextMax) {
1495
+ this.$set(item, 'isShow', true);
1496
+ }
1497
+ });
1498
+ return true;
1499
+ } else {
1500
+ formArray.forEach(item => {
1501
+ if (item.seq > seq && item.seq < lastSeq) {
1502
+ item.isShow = true;
1503
+ }
1504
+ });
1505
+ }
1506
+ } else if (nextLogic.next_logic == 'uncondition') {
1507
+ let res = utils.isEmpty(choiceValue);
1508
+
1509
+ // 添加非响应式key __isLogic__ __lastSeq__
1510
+ Object.defineProperty(formItem, '__isLogic__', {
1511
+ value: !res,
1512
+ writable: true
1513
+ });
1514
+ Object.defineProperty(formItem, '__lastSeq__', {
1515
+ value: seq + 1,
1516
+ writable: true
1517
+ });
1518
+
1519
+ formArray.forEach(item => {
1520
+ const key = this.formKey(item);
1521
+ if (item.seq > seq && item.seq < lastSeq) {
1522
+ item.isShow = res;
1523
+ // 跳过时 清空已填内容
1524
+ if (!res) {
1525
+ this.form[key] && (this.form[key] = '');
1526
+ }
1527
+ }
1528
+ });
1529
+ }
1530
+ });
1531
+ }
1532
+ },
1533
+ // 关联逻辑
1534
+ showEvent(formItem, isSubmitCallback) {
1535
+ if (formItem.hide) return false;
1536
+ const { form } = this;
1537
+ let relationLogicObj = {};
1538
+ // 回调接口
1539
+ if (isSubmitCallback) {
1540
+ let setting = formItem.setting;
1541
+ if (formItem.setting && utils.isJSON(formItem.setting)) {
1542
+ setting = JSON.parse(formItem.setting);
1543
+ }
1544
+ relationLogicObj = utils.isString(setting.callbackCondition) ? JSON.parse(setting.callbackCondition) : setting.callbackCondition;
1545
+ if (!relationLogicObj || !relationLogicObj.condition || !relationLogicObj.condition.length) return true;
1546
+ } else {
1547
+ relationLogicObj = utils.isString(formItem.relationLogic) ? JSON.parse(formItem.relationLogic) : formItem.relationLogic;
1548
+ }
1549
+ if (!relationLogicObj || !Object.keys(relationLogicObj).length) return true;
1550
+ const { relation_logic_is, condition, relation_logic } = relationLogicObj;
1551
+ if (relation_logic_is) {
1552
+ const results = condition.map(c => {
1553
+ let key = this.formKey(this.formArray.filter(f => f.seq == c.subject_seq)[0]);
1554
+ if (utils.isArray(form[key])) {
1555
+ return form[key].some(v => c.value.includes(v));
1556
+ } else {
1557
+ return c.value.includes(form[key]);
1558
+ }
1559
+ });
1560
+ if (relation_logic == 'OR') {
1561
+ formItem.isShow = results.some(el => el);
1562
+ } else if (relation_logic == 'AND') {
1563
+ formItem.isShow = results.every(el => el);
1564
+ } else {
1565
+ formItem.isShow = results[0];
1566
+ }
1567
+ }
1568
+ return formItem.isShow;
1569
+ },
1570
+ // 单选组件回调
1571
+ radioChange(val, item, obj) {
1572
+ const key = this.formKey(item);
1573
+ this.form[key] = val;
1574
+ item.type === 'RADIO_BLOCK' && this.$set(this.choiceComObj, key, obj);
1575
+ this.nextLogicEvent(val, item, this.formArray);
1576
+ },
1577
+ // 多选组件回调
1578
+ checkboxChange(val, item, obj) {
1579
+ const key = this.formKey(item);
1580
+ this.form[key] = val;
1581
+ item.type === 'CHECKBOX_BLOCK' && this.$set(this.choiceComObj, key, obj);
1582
+ this.nextLogicEvent(val, item, this.formArray);
1583
+ },
1584
+ // 标签组件回调
1585
+ labelChange(labelList, item) {
1586
+ const key = this.formKey(item);
1587
+ this.form[key] = this.handleGetLabelSubmit(labelList);
1588
+ },
1589
+ // 视频组件回调
1590
+ vodFileList(list, item) {
1591
+ const key = this.formKey(item);
1592
+ this.form[key] = list;
1593
+ },
1594
+ handleGetLabelSubmit(labelSelectedList) {
1595
+ if (!labelSelectedList || !labelSelectedList.length)
1596
+ return {
1597
+ labelStr: '',
1598
+ labels: []
1599
+ };
1600
+ const selectedList = labelSelectedList || [];
1601
+ const labelStrList = [];
1602
+ const labels = [];
1603
+ // "cacheKey":"label_标签","isSelect":true
1604
+ selectedList.forEach(v => {
1605
+ labels.push(v);
1606
+ labelStrList.push(v.labelName);
1607
+ });
1608
+ this.labelSelectedList = selectedList;
1609
+ return {
1610
+ labelStr: labelStrList.join(','),
1611
+ labels: labels
1612
+ };
1613
+ },
1614
+ // 地址回调
1615
+ changeAddress(allValue, item) {
1616
+ const key = this.formKey(item);
1617
+ this.form[key] = allValue;
1618
+ },
1619
+ // 上传回调
1620
+ changeUpload(value, item) {
1621
+ const key = this.formKey(item);
1622
+ this.form[key] = value;
1623
+ },
1624
+ // 时间回调
1625
+ changeTime(value, item) {
1626
+ const key = this.formKey(item);
1627
+ this.form[key] = value;
1628
+ this.submitForm[key] = value;
1629
+ },
1630
+ // 保存
1631
+ onSubmit() {
1632
+ // 不包含测评组件,点击提交,弹出二次确认对话框,确认要提交吗?
1633
+ let hasEvaluate = this.formArray.find(item => this.isEvaluation(item.type));
1634
+ if (!hasEvaluate) {
1635
+ this.confirmSubmit('确认要提交吗?');
1636
+ return;
1637
+ }
1638
+
1639
+ // 包含测评组件,不包含考试时长,点击提交,弹出二次确认对话框,确认要结束测评吗?
1640
+ // 判断有无测评配置 并且在测评时间内
1641
+ let { evaluateResultSetting } = this.config;
1642
+ if (!evaluateResultSetting || (!Object.keys(evaluateResultSetting).length && !this.showEvaluateEntry)) {
1643
+ this.confirmSubmit('确认要结束测评吗?');
1644
+ return;
1645
+ }
1646
+
1647
+ // 表单内嵌量表, 没有开始答题, 不需要调用保存接口
1648
+ if (this.openType == 'formIframe' && this.showEvaluateEntry) {
1649
+ this.$emit('submitNoRequest');
1650
+ return;
1651
+ }
1652
+
1653
+ // 无倒计时
1654
+ let countdownDom = this.$refs.evaluateCountdown;
1655
+ if (!countdownDom?.showEvaluateCountdown) {
1656
+ this.confirmSubmit('确认要结束测评吗?');
1657
+ return;
1658
+ }
1659
+
1660
+ // 在倒计时内
1661
+ let message = '确认要提前结束测评吗?';
1662
+ let setAnswered = this.$refs.evaluateCountdown?.setAnswered;
1663
+ let totalLen = this.$refs.evaluateCountdown?.totalLen;
1664
+ // 存在未解答题目
1665
+ if (setAnswered < totalLen) {
1666
+ message = '存在未解答的题目,确定要提前结束吗?';
1667
+ }
1668
+ this.confirmSubmit(message);
1669
+ },
1670
+ confirmSubmit(message) {
1671
+ let _this = this;
1672
+ this.$confirm({
1673
+ title: '温馨提示',
1674
+ content: message,
1675
+ okText: '确定',
1676
+ cancelText: '取消',
1677
+ onOk: () => {
1678
+ _this.onSubmitForm();
1679
+ },
1680
+ onCancel() {}
1681
+ });
1682
+ },
1683
+ onSubmitForm() {
1684
+ this.$refs['ruleForm'].validate((valid, keys) => {
1685
+ if (valid) {
1686
+ this.submitMethod();
1687
+ } else {
1688
+ if (Object.keys(keys).length > 0) {
1689
+ let key = Object.keys(keys)[0];
1690
+ let field = keys[key][0].field,
1691
+ message = keys[key][0].message;
1692
+ let matchItem = this.formArray.find(v => v.databaseTitle === field);
1693
+ if (matchItem) {
1694
+ field = matchItem.title;
1695
+ }
1696
+ this.$message.error(field + message);
1697
+ }
1698
+ return false;
1699
+ }
1700
+ });
1701
+ },
1702
+ submitMethod() {
1703
+ const hasSpreadParams = this.defaultFormArray.find(v => v.type === 'SPREAD_PARAMS');
1704
+ if (hasSpreadParams) {
1705
+ if (utils.isJSON(hasSpreadParams.setting)) {
1706
+ hasSpreadParams.setting = JSON.parse(hasSpreadParams.setting);
1707
+ }
1708
+ let spreadKey = this.formKey(hasSpreadParams);
1709
+ this.submitForm[spreadKey] = this.compileSpreadParams(hasSpreadParams.setting.spreadParams);
1710
+ }
1711
+ // 自定义列表新增时多选特殊处理
1712
+ let checkBoxKey = this.defaultFormArray.find(ii => ii.type == 'CHECKBOX_BLOCK');
1713
+ if (checkBoxKey && Array.isArray(this.form[checkBoxKey.title]) && this.type === 'customList') {
1714
+ this.form[checkBoxKey.title] = this.form[checkBoxKey.title].join(',');
1715
+ }
1716
+ const scoreJson = this.handleScoreJson();
1717
+ let params;
1718
+ if (this.type === 'customList') {
1719
+ params = {
1720
+ definedListId: this.ids.guage_id,
1721
+ dbId: this.ids.db_id,
1722
+ scoreJson: JSON.stringify(scoreJson)
1723
+ };
1724
+ } else {
1725
+ const { guageId, randomId } = this.config;
1726
+ params = Object.assign(this.params, {
1727
+ guageId,
1728
+ scoreJson: JSON.stringify(scoreJson),
1729
+ randomId
1730
+ });
1731
+ }
1732
+ if (this.shareId) {
1733
+ params.shareId = this.shareId;
1734
+ }
1735
+ const tipSetting = this.defaultFormArray.find(item => item.type === 'SUCCESS_TIP');
1736
+ if (tipSetting) {
1737
+ // 提交保存成功提示设置
1738
+ const tip = utils.isJSON(tipSetting.setting) ? JSON.parse(tipSetting.setting) : tipSetting.setting;
1739
+ params.tipSetting = JSON.stringify({
1740
+ tipMode: tip.tipMode,
1741
+ tipType: tip.tipType,
1742
+ tipText: tip.tipText,
1743
+ tipApi: tip.tipApi
1744
+ });
1745
+ }
1746
+ let hasCallbackItem = this.defaultFormArray.find(v => v.type === 'CALLBACK_INTERFACE');
1747
+ let isCallback = false;
1748
+ if (hasCallbackItem) {
1749
+ isCallback = this.showEvent(hasCallbackItem, true);
1750
+ }
1751
+ /**
1752
+ * NOTE:
1753
+ * 提交数据往外推
1754
+ */
1755
+ this.$emit('onSubmit', params, hasCallbackItem, isCallback);
1756
+ },
1757
+ handleScoreJson() {
1758
+ let tempObj = Object.assign({}, this.form, this.submitForm);
1759
+ let res = {};
1760
+ if (!Object.keys(tempObj).length) return {};
1761
+ for (let key in tempObj) {
1762
+ let itemTemp = this.formArray.find(item => this.formKey(item) == key);
1763
+ let curValue = tempObj[key];
1764
+ if (key && itemTemp) {
1765
+ let keyTemp;
1766
+ if (itemTemp && itemTemp.databaseTitle) keyTemp = itemTemp.databaseTitle;
1767
+ if (this.type == 'customList' && itemTemp && itemTemp.setting && itemTemp.setting.startToStop != 1 && curValue && itemTemp.type == 'DATETIME') {
1768
+ if (itemTemp.setting && itemTemp.setting.dateType == 'time' && curValue) curValue = moment().format('YYYY-MM-DD ') + curValue;
1769
+ if (itemTemp.setting && itemTemp.setting.dateType == 'date' && curValue) curValue = moment(curValue).format('YYYY-MM-DD ') + moment().format('HH:mm:ss');
1770
+ }
1771
+
1772
+ // 处理choice选项 将key替换为value
1773
+ let isChoice = ['RADIO_BLOCK', 'CHECKBOX_BLOCK'].includes(itemTemp.type);
1774
+ if (isChoice) {
1775
+ let { options } = itemTemp;
1776
+ let obj = this.choiceComObj[key];
1777
+ if (itemTemp.type === 'RADIO_BLOCK' && curValue) {
1778
+ curValue = this.handleChoiceItem(curValue, options, obj);
1779
+ }
1780
+ if (itemTemp.type === 'CHECKBOX_BLOCK' && curValue?.length) {
1781
+ let resArr = this.handleCheckboxParams(curValue, options, obj);
1782
+ curValue = resArr;
1783
+ }
1784
+ }
1785
+
1786
+ if (key.includes('~-~')) {
1787
+ let newKey = keyTemp ? keyTemp.replace(/~-~/g, '.') : key.replace(/~-~/g, '.');
1788
+ res[newKey] = curValue;
1789
+ } else {
1790
+ res[keyTemp || key] = !curValue ? null : curValue;
1791
+ }
1792
+ } else {
1793
+ res[key] = curValue;
1794
+ }
1795
+ }
1796
+ console.log('res', res);
1797
+ return res;
1798
+ },
1799
+ handleCheckboxParams(value, options, obj) {
1800
+ let res = [];
1801
+ let i = 0,
1802
+ len = value.length,
1803
+ v;
1804
+ for (; i < len; i++) {
1805
+ v = value[i];
1806
+ let matchItem = options.find((o, i) => {
1807
+ if (i + 1 === v) {
1808
+ return true;
1809
+ }
1810
+ return false;
1811
+ });
1812
+ if (matchItem && !matchItem.prefix && !matchItem.suffix) {
1813
+ res.push(matchItem.value);
1814
+ continue;
1815
+ }
1816
+ let tempValue = this.handleChoiceItem(v, options, obj);
1817
+ res.push(tempValue);
1818
+ }
1819
+ return res;
1820
+ },
1821
+ handleChoiceItem(value, options, obj) {
1822
+ let { othersText, optionsPreSuffixObj = {} } = obj || {};
1823
+ if (value === 'other') {
1824
+ return othersText || '其他';
1825
+ }
1826
+ let matchItem = options.find((o, i) => {
1827
+ if (i + 1 === value) {
1828
+ return true;
1829
+ }
1830
+ return false;
1831
+ });
1832
+ if (!matchItem) return;
1833
+ if (!matchItem.prefix && !matchItem.suffix) return matchItem.value;
1834
+ let resValue = optionsPreSuffixObj[value] || '';
1835
+ if (matchItem.prefix) {
1836
+ resValue = matchItem.prefix + resValue;
1837
+ } else {
1838
+ resValue += matchItem.suffix;
1839
+ }
1840
+ return resValue;
1841
+ },
1842
+ resetForm() {
1843
+ this.$refs.ruleForm.resetFields();
1844
+ },
1845
+ cancel() {
1846
+ this.$emit('onCloseSetting');
1847
+ },
1848
+ handleEvaluationScore(ele) {
1849
+ let { minScore = 0, maxScore = 0, scoreType } = ele.scoreConfigs || {};
1850
+ return `(${maxScore}分)`;
1851
+ }
1852
+ }
1853
+ });
1854
+ </script>
1855
+ <style lang="less" scoped>
1856
+ .r-scale {
1857
+ position: relative;
1858
+ width: 100%;
1859
+ height: 100%;
1860
+ overflow: hidden;
1861
+ padding-top: 4px;
1862
+ padding-bottom: 50px;
1863
+ .scale-container {
1864
+ width: 100%;
1865
+ height: 100%;
1866
+ padding-bottom: 10px;
1867
+ transform-origin: 0 0;
1868
+ overflow-y: auto;
1869
+ box-sizing: border-box;
1870
+ &.scale-container-nopadding {
1871
+ height: 100%;
1872
+ }
1873
+ &::-webkit-scrollbar {
1874
+ width: 10px;
1875
+ }
1876
+ }
1877
+ /deep/ .no-data-tip {
1878
+ width: 100%;
1879
+ height: 100%;
1880
+ }
1881
+ .totalScore-warp {
1882
+ padding: 16px;
1883
+ margin-bottom: 16px;
1884
+ font-weight: 400;
1885
+ color: #666666;
1886
+ background: #f2f2f4;
1887
+ font-size: 14px;
1888
+ border-radius: 6px;
1889
+ div + div {
1890
+ margin-top: 4px;
1891
+ }
1892
+ span {
1893
+ font-weight: 500;
1894
+ color: #090909;
1895
+ }
1896
+ .score-result {
1897
+ color: #2d7aff;
1898
+ }
1899
+ }
1900
+ /deep/ .ant-spin-spinning {
1901
+ height: 100%;
1902
+ width: 100%;
1903
+ padding-top: 88px;
1904
+ }
1905
+ /deep/ .ant-select ~ div {
1906
+ position: relative !important;
1907
+ }
1908
+ // /deep/.ant-select-dropdown {
1909
+ // top: 0px !important;
1910
+ // left: 1px !important;
1911
+ // }
1912
+ .lb-title {
1913
+ text-align: center;
1914
+ }
1915
+ .map-container {
1916
+ cursor: pointer;
1917
+ /deep/ .ant-input-disabled {
1918
+ color: rgba(0, 0, 0, 0.65);
1919
+ background-color: #fff;
1920
+ cursor: pointer;
1921
+ }
1922
+ }
1923
+ .linebar-div {
1924
+ text-align: center;
1925
+ margin-top: 24px;
1926
+ /deep/ .ant-divider {
1927
+ margin-top: -4px;
1928
+ }
1929
+ }
1930
+ .my-prompt {
1931
+ padding: 10px;
1932
+ box-shadow: 0 5px 13px rgba(0, 0, 0, 0.14);
1933
+ background-color: #fff;
1934
+ border-radius: 4px;
1935
+ }
1936
+ .img-card {
1937
+ width: 100%;
1938
+ }
1939
+ }
1940
+ .main {
1941
+ // overflow: auto;
1942
+ // overflow-x: hidden;
1943
+ padding: 0 16px;
1944
+ box-sizing: border-box;
1945
+ /deep/.ant-form-item-required::before {
1946
+ color: #e02828;
1947
+ }
1948
+ .scale-label-required {
1949
+ font-weight: 700;
1950
+ }
1951
+ .required-text {
1952
+ color: #e02828;
1953
+ }
1954
+ .evalute-label {
1955
+ display: inline-block;
1956
+ height: 20px;
1957
+ line-height: 20px;
1958
+ padding: 0 5px;
1959
+ margin-left: 4px;
1960
+ font-size: 12px;
1961
+ color: #2d7aff;
1962
+ border-radius: 4px;
1963
+ border: 1px solid rgba(45, 122, 255, 0.5);
1964
+ background: rgba(45, 122, 255, 0.1);
1965
+ }
1966
+ .evalute-tip {
1967
+ display: inline-block;
1968
+ padding: 0 5px;
1969
+ margin-left: 8px;
1970
+ color: #fe9626;
1971
+ border-radius: 2px;
1972
+ background: rgba(255, 194, 0, 0.15);
1973
+ cursor: pointer;
1974
+ .ant-icon {
1975
+ margin-right: 2px;
1976
+ }
1977
+ }
1978
+ /deep/ .ant-form-item-label {
1979
+ // white-space: break-spaces;
1980
+ white-space: unset;
1981
+ text-align: left;
1982
+ line-height: 20px;
1983
+ padding: 6px 0;
1984
+ width: 100%;
1985
+ .ant-form-item-no-colon {
1986
+ width: 100%;
1987
+ }
1988
+ }
1989
+ }
1990
+ .footer {
1991
+ position: absolute;
1992
+ bottom: 0;
1993
+ left: 0;
1994
+ width: 100%;
1995
+ border-top: 1px solid #e8e8e8;
1996
+ padding-top: 12px;
1997
+ height: 50px;
1998
+ box-sizing: border-box;
1999
+ background: #fff;
2000
+ }
2001
+ .rich-text-content {
2002
+ word-break: break-all;
2003
+ /deep/ p {
2004
+ margin-bottom: 0;
2005
+ }
2006
+ /deep/ img {
2007
+ max-width: 100%;
2008
+ }
2009
+ }
2010
+ </style>