st-comp 0.0.277 → 0.0.279

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 (319) hide show
  1. package/README.md +19 -19
  2. package/es/ChartLayout.cjs +1 -1
  3. package/es/ChartLayout.js +1 -1
  4. package/es/ConfigProvider.cjs +1 -1
  5. package/es/ConfigProvider.js +3 -3
  6. package/es/Contextmenu.cjs +1 -1
  7. package/es/Contextmenu.js +7 -7
  8. package/es/CustomFunction.cjs +2 -2
  9. package/es/CustomFunction.js +514 -308
  10. package/es/FactorWarning.cjs +1 -1
  11. package/es/FactorWarning.js +37 -37
  12. package/es/HeatMap.cjs +1 -1
  13. package/es/HeatMap.js +7 -7
  14. package/es/Kline.cjs +1 -1
  15. package/es/Kline.js +18 -18
  16. package/es/KlineBasic.cjs +1 -1
  17. package/es/KlineBasic.js +93 -93
  18. package/es/KlineConfig.cjs +1 -1
  19. package/es/KlineConfig.js +17 -17
  20. package/es/KlineNew.cjs +1 -1
  21. package/es/KlineNew.js +14 -14
  22. package/es/KlinePlus.cjs +4 -4
  23. package/es/KlinePlus.js +760 -656
  24. package/es/LinearLegend.cjs +1 -1
  25. package/es/LinearLegend.js +1 -1
  26. package/es/Map.cjs +1 -1
  27. package/es/Map.js +1 -1
  28. package/es/MonacoEditor.cjs +1 -1
  29. package/es/MonacoEditor.js +18 -18
  30. package/es/Pagination.cjs +1 -1
  31. package/es/Pagination.js +76 -76
  32. package/es/PasswordPrompt.cjs +1 -1
  33. package/es/PasswordPrompt.js +2 -2
  34. package/es/Pie.cjs +2 -2
  35. package/es/Pie.js +14 -14
  36. package/es/Table.cjs +1 -1
  37. package/es/Table.js +22 -22
  38. package/es/TreeMap.cjs +1 -1
  39. package/es/TreeMap.js +4 -4
  40. package/es/User.cjs +1 -1
  41. package/es/User.js +73 -73
  42. package/es/VarSelectDialog.cjs +2 -2
  43. package/es/VarSelectDialog.js +21 -21
  44. package/es/VarietyAiHelper.cjs +4 -4
  45. package/es/VarietyAiHelper.js +139 -138
  46. package/es/VarietyAutoComplete.cjs +1 -1
  47. package/es/VarietyAutoComplete.js +16 -16
  48. package/es/VarietySearch.cjs +4 -4
  49. package/es/VarietySearch.js +861 -857
  50. package/es/{VarietySelect-6a166293.js → VarietySelect-41daac7b.js} +10 -10
  51. package/es/{VarietySelect-610903f0.cjs → VarietySelect-d58eee29.cjs} +1 -1
  52. package/es/VarietyTextCopy.cjs +2 -2
  53. package/es/VarietyTextCopy.js +25 -25
  54. package/es/VirtualTable.cjs +1 -1
  55. package/es/VirtualTable.js +6 -6
  56. package/es/{_initCloneObject-152b4f4e.js → _initCloneObject-5e73c9c8.js} +2 -2
  57. package/es/{_initCloneObject-76e116d0.cjs → _initCloneObject-a5832933.cjs} +1 -1
  58. package/es/aiTools-229609fb.cjs +2 -0
  59. package/es/aiTools-ce2f9281.js +115 -0
  60. package/es/aiTools.js +179 -176
  61. package/es/{config-provider-4c784baf.cjs → config-provider-06ea6b42.cjs} +1 -1
  62. package/es/{config-provider-7a3aca55.js → config-provider-88b637a8.js} +3 -3
  63. package/es/{dropdown-987c47fb.cjs → dropdown-4ce4c3e2.cjs} +1 -1
  64. package/es/{dropdown-01e09205.js → dropdown-72fbc15d.js} +2 -2
  65. package/es/{el-autocomplete-342ae823.js → el-autocomplete-6cafcdf1.js} +5 -5
  66. package/es/{el-autocomplete-16f66b34.cjs → el-autocomplete-e0857c5b.cjs} +1 -1
  67. package/es/{el-button-13dc915f.cjs → el-button-613e0bb2.cjs} +1 -1
  68. package/es/{el-button-314171a0.js → el-button-94d3de38.js} +3 -3
  69. package/es/{el-checkbox-5899681f.js → el-checkbox-6d4cb393.js} +3 -3
  70. package/es/{el-checkbox-bdf64663.cjs → el-checkbox-e90762df.cjs} +1 -1
  71. package/es/{el-dialog-0ef95df6.cjs → el-dialog-02942e22.cjs} +1 -1
  72. package/es/{el-dialog-86a3eec2.js → el-dialog-5e30161f.js} +4 -4
  73. package/es/{el-form-item-77ef6784.cjs → el-form-item-44f060d8.cjs} +1 -1
  74. package/es/{el-form-item-cda4d93c.js → el-form-item-9e8969ea.js} +5 -5
  75. package/es/{el-input-fa1445ad.js → el-input-342b2def.js} +13 -13
  76. package/es/{el-input-89222943.cjs → el-input-9a9a7f7f.cjs} +1 -1
  77. package/es/{el-input-number-d3338e5e.cjs → el-input-number-65c847d6.cjs} +1 -1
  78. package/es/{el-input-number-8f6dbf74.js → el-input-number-c22b803a.js} +35 -35
  79. package/es/{el-loading-84dde1a8.cjs → el-loading-8179b497.cjs} +1 -1
  80. package/es/{el-loading-9b671203.js → el-loading-bcc51e3d.js} +1 -1
  81. package/es/{el-menu-item-535fef90.js → el-menu-item-339baf6d.js} +21 -21
  82. package/es/{el-menu-item-4531fd0e.cjs → el-menu-item-83186444.cjs} +1 -1
  83. package/es/{el-message-box-621ed2f1.js → el-message-box-035b699c.js} +9 -9
  84. package/es/{el-message-box-f5717070.cjs → el-message-box-c62d3217.cjs} +1 -1
  85. package/es/{el-overlay-23de4324.js → el-overlay-3e17604b.js} +3 -3
  86. package/es/{el-overlay-151708cb.cjs → el-overlay-8f1da9e8.cjs} +1 -1
  87. package/es/{el-popconfirm-b8aa490e.cjs → el-popconfirm-4e32ec1b.cjs} +1 -1
  88. package/es/{el-popconfirm-bcff0aa5.js → el-popconfirm-f8a86e2c.js} +4 -4
  89. package/es/{el-popper-43ec37f4.cjs → el-popper-a4f3ae4d.cjs} +1 -1
  90. package/es/{el-popper-03988662.js → el-popper-fbd0dcea.js} +1 -1
  91. package/es/{el-segmented-db3a86be.js → el-segmented-56bd58a8.js} +2 -2
  92. package/es/{el-segmented-79a1367c.cjs → el-segmented-833ac177.cjs} +1 -1
  93. package/es/{el-select-4bd0010d.js → el-select-44fa547d.js} +8 -8
  94. package/es/{el-select-ec04e7ce.cjs → el-select-70806166.cjs} +1 -1
  95. package/es/{el-table-column-35e47229.cjs → el-table-column-3e2cdfca.cjs} +1 -1
  96. package/es/{el-table-column-7af2bec7.js → el-table-column-b74a857d.js} +9 -9
  97. package/es/{el-tag-bef9e83d.js → el-tag-66c83156.js} +2 -2
  98. package/es/{el-tag-5d5608e0.cjs → el-tag-9c2f329f.cjs} +1 -1
  99. package/es/{el-text-f998902c.js → el-text-034bd3f4.js} +1 -1
  100. package/es/{el-text-abf10fdf.cjs → el-text-6b2374bb.cjs} +1 -1
  101. package/es/index-00f6ca75.cjs +1 -0
  102. package/es/{index-a00e0534.cjs → index-185792a7.cjs} +1 -1
  103. package/es/{index-d1b554ac.js → index-1e2a38ab.js} +2 -2
  104. package/es/{index-0986e373.cjs → index-3153c1db.cjs} +1 -1
  105. package/es/{index-936e7dec.js → index-44a382a5.js} +2 -2
  106. package/es/{index-ce21e2ce.js → index-5216d5f5.js} +5 -5
  107. package/es/{index-7ed0999e.js → index-53cc4e43.js} +720 -716
  108. package/es/{index-cfcd60ca.cjs → index-5c0dd943.cjs} +1 -1
  109. package/es/{index-cfd00899.cjs → index-870b6c9d.cjs} +1 -1
  110. package/es/{index-a83ec4b7.js → index-8c2d7e05.js} +1 -1
  111. package/es/{index-8901a38c.cjs → index-94131fd7.cjs} +30 -30
  112. package/es/{index-db846633.cjs → index-9d16cea8.cjs} +1 -1
  113. package/es/{index-f3f6ee27.js → index-a33b2fb8.js} +178 -178
  114. package/es/{index-2d7ac156.cjs → index-a9246d17.cjs} +17 -17
  115. package/es/{index-60c69dd1.cjs → index-ac8dc53d.cjs} +1 -1
  116. package/es/{index-102edf6c.js → index-c5f2d372.js} +2 -2
  117. package/es/{index-6290ae0f.js → index-c6584658.js} +2 -2
  118. package/es/{index-5c44d71a.js → index-eb96e074.js} +149 -119
  119. package/es/{index-5ed42e9c.js → index-f034b910.js} +2 -2
  120. package/es/{index-c58e90e9.cjs → index-f58b2920.cjs} +1 -1
  121. package/es/{python-6cc6ec1b.js → python-8a1664e6.js} +18 -18
  122. package/es/{python-71f59893.cjs → python-a3db9620.cjs} +1 -1
  123. package/es/style.css +1 -1
  124. package/es/{use-form-common-props-02be4928.cjs → use-form-common-props-ac666630.cjs} +1 -1
  125. package/es/{use-form-common-props-76a09d89.js → use-form-common-props-ed72e914.js} +11 -11
  126. package/es/{use-global-config-31b3ec57.cjs → use-global-config-23472471.cjs} +1 -1
  127. package/es/{use-global-config-0f43458b.js → use-global-config-ee406d58.js} +2 -2
  128. package/es/{validator-ea292506.cjs → validator-366dbf39.cjs} +1 -1
  129. package/es/{validator-0e037618.js → validator-c60a8956.js} +1 -1
  130. package/es/{zh-cn-1227eb8a.js → zh-cn-b59a0910.js} +1 -1
  131. package/es/{zh-cn-0edc7234.cjs → zh-cn-c21d12d8.cjs} +1 -1
  132. package/lib/aiTools.js +179 -176
  133. package/lib/bundle.js +1 -1
  134. package/lib/bundle.umd.cjs +230 -230
  135. package/lib/{index-2a269748.js → index-62fa175a.js} +30149 -29800
  136. package/lib/{python-41da18e5.js → python-4a48fa39.js} +1 -1
  137. package/lib/style.css +1 -1
  138. package/package.json +53 -44
  139. package/auto-imports.d.ts +0 -13
  140. package/components.d.ts +0 -59
  141. package/es/aiTools-a3b095f6.js +0 -113
  142. package/es/aiTools-f36136a4.cjs +0 -2
  143. package/es/index-476c4459.cjs +0 -1
  144. package/index.html +0 -13
  145. package/packages/ChartLayout/index.ts +0 -8
  146. package/packages/ChartLayout/index.vue +0 -63
  147. package/packages/ConfigProvider/index.ts +0 -8
  148. package/packages/ConfigProvider/index.vue +0 -66
  149. package/packages/Contextmenu/index.ts +0 -8
  150. package/packages/Contextmenu/index.vue +0 -134
  151. package/packages/CustomFunction/components/ManageDialog.vue +0 -706
  152. package/packages/CustomFunction/index.ts +0 -8
  153. package/packages/CustomFunction/index.vue +0 -200
  154. package/packages/FactorWarning/index.ts +0 -8
  155. package/packages/FactorWarning/index.vue +0 -754
  156. package/packages/FactorWarning/tools.js +0 -10
  157. package/packages/HeatMap/index.ts +0 -8
  158. package/packages/HeatMap/index.vue +0 -141
  159. package/packages/Kline/components/Contextmenu/index.vue +0 -110
  160. package/packages/Kline/components/Tips/index.vue +0 -40
  161. package/packages/Kline/componentsNew/KlineSlide/index.vue +0 -155
  162. package/packages/Kline/componentsNew/KlineSub/index.vue +0 -297
  163. package/packages/Kline/componentsNew/KlineTips/index.vue +0 -66
  164. package/packages/Kline/componentsNew/KlineUtils/index.vue +0 -84
  165. package/packages/Kline/componentsNew/Tips/index.vue +0 -33
  166. package/packages/Kline/formatKlineData.ts +0 -109
  167. package/packages/Kline/images/buy.svg +0 -1
  168. package/packages/Kline/images/pen.png +0 -0
  169. package/packages/Kline/images/sell.svg +0 -1
  170. package/packages/Kline/images/t.svg +0 -1
  171. package/packages/Kline/index.ts +0 -16
  172. package/packages/Kline/index.vue +0 -891
  173. package/packages/Kline/option.ts +0 -539
  174. package/packages/Kline/type.d.ts +0 -219
  175. package/packages/Kline/utils.ts +0 -682
  176. package/packages/KlineBasic/api.js +0 -58
  177. package/packages/KlineBasic/components/AverageTips/index.vue +0 -33
  178. package/packages/KlineBasic/components/Contextmenu/index.vue +0 -105
  179. package/packages/KlineBasic/components/KlineSub/index.vue +0 -332
  180. package/packages/KlineBasic/components/KlineTips/index.vue +0 -99
  181. package/packages/KlineBasic/components/Tips/index.vue +0 -56
  182. package/packages/KlineBasic/index.ts +0 -8
  183. package/packages/KlineBasic/index.vue +0 -839
  184. package/packages/KlineBasic/utils.js +0 -258
  185. package/packages/KlineConfig/config.js +0 -46
  186. package/packages/KlineConfig/index.ts +0 -8
  187. package/packages/KlineConfig/index.vue +0 -356
  188. package/packages/KlineNew/components/KlineSlide/index.vue +0 -156
  189. package/packages/KlineNew/components/KlineSub/index.vue +0 -335
  190. package/packages/KlineNew/components/KlineTips/index.vue +0 -96
  191. package/packages/KlineNew/components/KlineUtils/index.vue +0 -341
  192. package/packages/KlineNew/components/Tips/index.vue +0 -33
  193. package/packages/KlineNew/index.ts +0 -14
  194. package/packages/KlinePlus/components/SliderChart.vue +0 -208
  195. package/packages/KlinePlus/components/Tips.vue +0 -36
  196. package/packages/KlinePlus/images/buy.svg +0 -1
  197. package/packages/KlinePlus/images/sell.svg +0 -1
  198. package/packages/KlinePlus/images/t.svg +0 -1
  199. package/packages/KlinePlus/index.ts +0 -8
  200. package/packages/KlinePlus/index.vue +0 -1067
  201. package/packages/KlinePlus/utils.js +0 -771
  202. package/packages/LinearLegend/index.ts +0 -8
  203. package/packages/LinearLegend/index.vue +0 -112
  204. package/packages/Map/China.json +0 -1
  205. package/packages/Map/index.ts +0 -8
  206. package/packages/Map/index.vue +0 -147
  207. package/packages/MonacoEditor/index.ts +0 -8
  208. package/packages/MonacoEditor/index.vue +0 -1141
  209. package/packages/MonacoEditor/tools.js +0 -18
  210. package/packages/Pagination/index.ts +0 -8
  211. package/packages/Pagination/index.vue +0 -87
  212. package/packages/PasswordPrompt/index.ts +0 -8
  213. package/packages/PasswordPrompt/index.vue +0 -267
  214. package/packages/Pie/index.ts +0 -8
  215. package/packages/Pie/index.vue +0 -148
  216. package/packages/Table/components/Button/index.vue +0 -61
  217. package/packages/Table/components/Formatter/index.vue +0 -26
  218. package/packages/Table/index.d.ts +0 -0
  219. package/packages/Table/index.ts +0 -8
  220. package/packages/Table/index.vue +0 -133
  221. package/packages/TreeMap/index.ts +0 -8
  222. package/packages/TreeMap/index.vue +0 -186
  223. package/packages/User/components/EditInfoDialog/Mobile.vue +0 -214
  224. package/packages/User/components/EditInfoDialog/index.vue +0 -161
  225. package/packages/User/components/EditPasswordDialog.vue +0 -168
  226. package/packages/User/components/SetPasswordDialog.vue +0 -160
  227. package/packages/User/index.ts +0 -8
  228. package/packages/User/index.vue +0 -117
  229. package/packages/VarSelectDialog/Mock.js +0 -495
  230. package/packages/VarSelectDialog/VarietySelect.vue +0 -78
  231. package/packages/VarSelectDialog/index.ts +0 -8
  232. package/packages/VarSelectDialog/index.vue +0 -323
  233. package/packages/VarietyAiHelper/images/like.png +0 -0
  234. package/packages/VarietyAiHelper/images/like_no.png +0 -0
  235. package/packages/VarietyAiHelper/index.ts +0 -8
  236. package/packages/VarietyAiHelper/index.vue +0 -910
  237. package/packages/VarietyAutoComplete/index.ts +0 -8
  238. package/packages/VarietyAutoComplete/index.vue +0 -89
  239. package/packages/VarietySearch/components/AddTag/index.vue +0 -268
  240. package/packages/VarietySearch/components/CommonIndicator/IndicatorTags.vue +0 -52
  241. package/packages/VarietySearch/components/CommonIndicator/index.vue +0 -697
  242. package/packages/VarietySearch/components/CommonIndicator/tools.js +0 -260
  243. package/packages/VarietySearch/components/CompositeOrder/index.vue +0 -260
  244. package/packages/VarietySearch/components/FactorScreen/FactorDescription.vue +0 -70
  245. package/packages/VarietySearch/components/FactorScreen/index.vue +0 -1158
  246. package/packages/VarietySearch/components/FactorScreen/tools.js +0 -34
  247. package/packages/VarietySearch/config.js +0 -539
  248. package/packages/VarietySearch/index.ts +0 -8
  249. package/packages/VarietySearch/index.vue +0 -688
  250. package/packages/VarietyTextCopy/index.ts +0 -8
  251. package/packages/VarietyTextCopy/index.vue +0 -136
  252. package/packages/VirtualTable/index.ts +0 -8
  253. package/packages/VirtualTable/index.vue +0 -241
  254. package/packages/index.ts +0 -59
  255. package/public/aiTools.js +0 -176
  256. package/public/talib.wasm +0 -0
  257. package/public/vite.svg +0 -1
  258. package/src/App.vue +0 -140
  259. package/src/assets/vue.svg +0 -1
  260. package/src/components/Dialog/index.vue +0 -16
  261. package/src/components/Kline/index.vue +0 -21
  262. package/src/components/Table/index.vue +0 -27
  263. package/src/main.ts +0 -17
  264. package/src/pages/ChartLayout/index.vue +0 -22
  265. package/src/pages/ConfigProvider/index.vue +0 -9
  266. package/src/pages/Contextmenu/index.vue +0 -46
  267. package/src/pages/CustomFunction/index.vue +0 -13
  268. package/src/pages/FactorWarning/index.vue +0 -203
  269. package/src/pages/HeatMap/index.vue +0 -128
  270. package/src/pages/Kline/index.vue +0 -12
  271. package/src/pages/KlineBasic/api.js +0 -48
  272. package/src/pages/KlineBasic/index.vue +0 -366
  273. package/src/pages/KlineBasic/indicator.js +0 -114
  274. package/src/pages/KlineConfig/index.vue +0 -20
  275. package/src/pages/KlineNew/components/KlineAction/components/ContextMenu/index.vue +0 -91
  276. package/src/pages/KlineNew/components/KlineAction/components/YearChart/index.vue +0 -532
  277. package/src/pages/KlineNew/components/KlineAction/images/pen.png +0 -0
  278. package/src/pages/KlineNew/components/KlineAction/index.vue +0 -716
  279. package/src/pages/KlineNew/components/KlineAction/mockApi/index.js +0 -13
  280. package/src/pages/KlineNew/components/KlineAction/utils.js +0 -571
  281. package/src/pages/KlineNew/components/KlineBasic/index.vue +0 -336
  282. package/src/pages/KlineNew/components/KlineBasic/utils.js +0 -46
  283. package/src/pages/KlineNew/components/KlineNew/index.vue +0 -316
  284. package/src/pages/KlineNew/components/KlineNew/utils.js +0 -31
  285. package/src/pages/KlineNew/components/KlineSlide/index.vue +0 -448
  286. package/src/pages/KlineNew/components/KlineSlide/utils.js +0 -78
  287. package/src/pages/KlineNew/components/KlineSlideNew/index.vue +0 -430
  288. package/src/pages/KlineNew/components/KlineSlideNew/utils.js +0 -78
  289. package/src/pages/KlineNew/index.vue +0 -92
  290. package/src/pages/KlinePlus/KlineDialog/MultiCycle.vue +0 -312
  291. package/src/pages/KlinePlus/KlineDialog/api.js +0 -108
  292. package/src/pages/KlinePlus/KlineDialog/index.vue +0 -582
  293. package/src/pages/KlinePlus/KlineDialog/indicator.js +0 -109
  294. package/src/pages/KlinePlus/KlineDialog/tools.js +0 -86
  295. package/src/pages/KlinePlus/index.vue +0 -30
  296. package/src/pages/KlinePlus/tradeLogMock.js +0 -1927
  297. package/src/pages/LinearLegend/index.vue +0 -92
  298. package/src/pages/Map/index.vue +0 -62
  299. package/src/pages/MonacoEditor/index.vue +0 -63
  300. package/src/pages/Pagination/index.vue +0 -24
  301. package/src/pages/PasswordPrompt/index.vue +0 -12
  302. package/src/pages/Pie/index.vue +0 -36
  303. package/src/pages/Table/index.vue +0 -117
  304. package/src/pages/TreeMap/index.vue +0 -542
  305. package/src/pages/User/index.vue +0 -24
  306. package/src/pages/VarSelectDialog/index.vue +0 -16
  307. package/src/pages/VarietyAiHelper/index.vue +0 -20
  308. package/src/pages/VarietyAutoComplete/index.vue +0 -19
  309. package/src/pages/VarietySearch/api.js +0 -70
  310. package/src/pages/VarietySearch/index.vue +0 -467
  311. package/src/pages/VarietyTextCopy/index.vue +0 -24
  312. package/src/pages/VirtualTable/demo.json +0 -6377
  313. package/src/pages/VirtualTable/index.vue +0 -79
  314. package/src/router/index.ts +0 -9
  315. package/src/router/routes.ts +0 -132
  316. package/src/style.css +0 -79
  317. package/src/vite-env.d.ts +0 -9
  318. package/tsconfig.json +0 -30
  319. package/tsconfig.node.json +0 -10
@@ -1,1158 +0,0 @@
1
- <!-- 因子筛选组件 -->
2
- <script setup name="FactorScreen">
3
- import { nextTick, ref, watch, inject, reactive } from "vue";
4
- import { getToken } from "st-func";
5
- import { Close, Plus, CircleCloseFilled, InfoFilled, Document } from "@element-plus/icons-vue";
6
- import { handleVerifyScore, extractConditionDetails, extractVariables } from "./tools.js";
7
- import { sendToNodeFactorAiTest } from "../../../../public/aiTools";
8
- import FactorDescription from "./FactorDescription.vue";
9
- import MonacoEditor from "../../../MonacoEditor/index.vue";
10
-
11
- const { request, env } = inject("stConfig"); // 组件库全局配置
12
-
13
- const emit = defineEmits(["actionState"]);
14
- const props = defineProps({
15
- config: {
16
- type: Object,
17
- default: {
18
- sqlShow: false, // 是否启用SQL功能
19
- cycleShow: true, // 是否展示周期
20
- cycleDefault: null, // 周期默认值
21
- cycleOptions: [], // 周期下拉框选项
22
- factorOptions: [], // 因子下拉框选项
23
- factorDescriptions: [], // 因子使用说明数据源
24
- },
25
- },
26
- });
27
- const data = defineModel("data", {
28
- default: {
29
- list: [],
30
- sqlEnable: 0,
31
- sqlValue: null,
32
- },
33
- });
34
-
35
- const monacoEditorRef = ref();
36
- const stVarSelectDialogRef = ref();
37
-
38
- // 弹窗开关
39
- const visible = ref(false);
40
- const visibleDescriptions = ref(false);
41
- const factorType = ref("脚本");
42
- const scriptTestLoading = ref(false);
43
- const scriptCopyLoading = ref(false);
44
- const scriptAILoading = ref(false);
45
- const scriptAIButtonLoading = ref(false);
46
- const testVariety = ref("");
47
- const testVarietyVisible = ref(false);
48
- const scriptTestLogVisible = ref(false);
49
- const scriptTestResult = reactive({
50
- result: null,
51
- detail: "",
52
- code: "",
53
- ai: "",
54
- });
55
-
56
- // 弹窗表单
57
- const dialogFormRef = ref(null);
58
- const dialogForm = ref({
59
- // 筛选因子列表
60
- list: [
61
- {
62
- cycle: props.config.cycleDefault ?? null, // 周期
63
- factor: null, // 因子
64
- score: [null, null], // 得分
65
- },
66
- ],
67
- // 是否开启SQL功能 0关闭, 1开启
68
- sqlEnable: 0,
69
- // SQL语句
70
- sqlValue: null,
71
- // 脚本语句
72
- factorSelectExpr: "",
73
- });
74
-
75
- // 打开
76
- const handleOpenDialog = () => {
77
- const { list, sqlEnable, sqlValue, factorSelectExpr } = data.value;
78
- dialogForm.value = {
79
- list: JSON.parse(JSON.stringify(list)),
80
- sqlEnable,
81
- sqlValue,
82
- factorSelectExpr,
83
- };
84
- // 保证因子筛选最少一条
85
- if (!dialogForm.value.list.length) handleAppendFactor();
86
- visible.value = true;
87
- };
88
- // 确定
89
- const handleSubmit = () => {
90
- if (factorType.value === "模版") {
91
- dialogFormRef.value.validate((valid) => {
92
- const { list, sqlEnable, sqlValue } = dialogForm.value;
93
- if (!valid) return;
94
- // 针对开启了SQL功能后的字段校验
95
- if (sqlEnable) {
96
- if (!sqlValue) return ElMessage.error("SQL语句不能为空");
97
- // 提取SQL语句中的条件1, 条件2, ...
98
- const sqlConditions = extractConditionDetails(sqlValue);
99
- // 生成因子表格中的条件1, 条件2, ...
100
- const factorConditions = list.map((item, index) => `条件${index + 1}`);
101
- // 校验SQL中是否全部都能在因子表格中找到
102
- const noSaveConditions = sqlConditions.filter((item) => !factorConditions.includes(item));
103
- if (noSaveConditions.length) return ElMessage.error(`请检查SQL语句, 不存在[${noSaveConditions}]`);
104
- }
105
- data.value = {
106
- list: JSON.parse(JSON.stringify(list)),
107
- sqlEnable,
108
- sqlValue,
109
- factorSelectExpr: "",
110
- };
111
- visible.value = false;
112
- });
113
- } else {
114
- const script = monacoEditorRef.value.getValue();
115
- if (!script) return ElMessage.error("请输入脚本语句");
116
- data.value = {
117
- list: [],
118
- sqlEnable: 0,
119
- sqlValue: null,
120
- factorSelectExpr: script,
121
- };
122
- visible.value = false;
123
- }
124
- };
125
-
126
- // 表单: 删除因子
127
- const handleDeleteFactor = (index) => {
128
- dialogForm.value.list.splice(index, 1);
129
- };
130
- // 表单: 添加因子
131
- const handleAppendFactor = (type) => {
132
- switch (type) {
133
- // 对比
134
- case "compare": {
135
- dialogForm.value.list.push({
136
- key: "compare",
137
- cycle: props.config.cycleDefault ?? null,
138
- factor: null,
139
- compareType: ">",
140
- cycle2: props.config.cycleDefault ?? null,
141
- factor2: null,
142
- });
143
- break;
144
- }
145
- // 常规
146
- default: {
147
- dialogForm.value.list.push({
148
- cycle: props.config.cycleDefault ?? null,
149
- factor: null,
150
- score: [null, null],
151
- });
152
- break;
153
- }
154
- }
155
- };
156
- // 表单: 生成SQL
157
- const handleGenerateSql = () => {
158
- dialogFormRef.value.validate((valid) => {
159
- if (!valid) return;
160
- // 检测是否已经存在SQL语句 => 匹配生成
161
- if (dialogForm.value.sqlValue) {
162
- // 找到sqlValue中存在的所有 条件1, 条件2, ..., 条件n
163
- const sqlConditions = extractConditionDetails(dialogForm.value.sqlValue);
164
- dialogForm.value.sqlValue = dialogForm.value.list.reduce((result, item, index) => {
165
- // 如果已经出现存在过sqlValue中的条件, 则略过, 没存在过的直接加入进去
166
- if (!sqlConditions.includes(`条件${index + 1}`)) {
167
- result += `&& 条件${index + 1} `;
168
- }
169
- return result;
170
- }, dialogForm.value.sqlValue);
171
- }
172
- // 完全重新生成
173
- else {
174
- dialogForm.value.sqlValue = dialogForm.value.list.reduce((result, item, index) => {
175
- if (index === 0) {
176
- result += `条件${index + 1} `;
177
- } else {
178
- result += `&& 条件${index + 1} `;
179
- }
180
- return result;
181
- }, "");
182
- }
183
- });
184
- };
185
-
186
- // Tag: 文案
187
- const handleFormatTag = (tag) => {
188
- switch (tag.key) {
189
- // 对比
190
- case "compare": {
191
- const { cycle, factor, compareType, cycle2, factor2 } = tag;
192
- let str = "";
193
- str += ` ${props.config.cycleOptions.find(({ value }) => value === cycle).label}`;
194
- str += ` ${props.config.factorOptions.find(({ value }) => value === factor).label}`;
195
- str += ` ${compareType}`;
196
- str += ` ${props.config.cycleOptions.find(({ value }) => value === cycle2).label}`;
197
- str += ` ${props.config.factorOptions.find(({ value }) => value === factor2).label}`;
198
- return str;
199
- }
200
- // 常规
201
- default: {
202
- const { cycle, factor, score } = tag;
203
- let str = "";
204
- str += ` ${props.config.cycleOptions.find(({ value }) => value === cycle).label}`;
205
- str += ` ${props.config.factorOptions.find(({ value }) => value === factor).label}`;
206
- str += ` ${score[0] || score[0] === 0 ? `${score[0]}分` : "∞"}`;
207
- str += " ~";
208
- str += ` ${score[1] || score[1] === 0 ? `${score[1]}分` : "∞"}`;
209
- return str;
210
- }
211
- }
212
- };
213
- // Tag: 删除
214
- const handleDeleteTag = (aciton, index) => {
215
- switch (aciton) {
216
- case "sqlTag": {
217
- data.value = {
218
- list: [],
219
- sqlEnable: 0,
220
- sqlValue: null,
221
- };
222
- break;
223
- }
224
- case "factorTag": {
225
- data.value.list.splice(index, 1);
226
- break;
227
- }
228
- case "scriptTag": {
229
- ElMessageBox.confirm("是否确认删除因子筛选: 脚本模式", "删除操作", {
230
- confirmButtonText: "确认",
231
- cancelButtonText: "取消",
232
- type: "warning",
233
- }).then(() => {
234
- data.value = {
235
- list: [],
236
- sqlEnable: 0,
237
- sqlValue: null,
238
- factorSelectExpr: "",
239
- };
240
- });
241
- break;
242
- }
243
- }
244
- };
245
-
246
- // 打开变量选择器
247
- const open = () => {
248
- stVarSelectDialogRef.value.open(monacoEditorRef.value);
249
- };
250
- // 脚本: 插入自定义函数
251
- const handleInsertCustomFunction = (funcName, funcExpression) => {
252
- if (!monacoEditorRef.value) return ElMessage.error("未检测到编辑器实例");
253
- // 生成基础插入内容 (如果内含${}, 需提取出来, 作为变量)
254
- let content = funcName;
255
- const varArray = extractVariables(funcExpression);
256
- if (varArray.length) {
257
- const str = varArray.reduce((result, item, index, arry) => {
258
- result += `${item}=`;
259
- // 如果不是最后一个, 就需要加个逗号
260
- if (index < arry.length - 1) result += ",";
261
- return result;
262
- }, "");
263
- content = `${content}(${str})`;
264
- }
265
-
266
- // 初始化光标和所在行位置
267
- const editorIns = monacoEditorRef.value.getInstance();
268
- const position = editorIns.getPosition();
269
- const currentValue = monacoEditorRef.value.getValue();
270
- const lines = currentValue.split("\n");
271
- // 执行插入操作
272
- if (position.lineNumber <= lines.length) {
273
- const lineIndex = position.lineNumber - 1;
274
- const line = lines[lineIndex];
275
- const columnIndex = position.column - 1;
276
-
277
- // 获取光标前后的字符
278
- const prevChar = columnIndex > 0 ? line[columnIndex - 1] : "";
279
- const nextChar = columnIndex < line.length ? line[columnIndex] : "";
280
-
281
- // 检测是否需要添加空格
282
- let contentToInsert = content;
283
-
284
- // 如果前面有内容且不是空格或行首,在前面添加空格
285
- if (prevChar && prevChar !== " " && !/[\s({[ ]/.test(prevChar)) {
286
- contentToInsert = " " + contentToInsert;
287
- }
288
-
289
- // 如果后面有内容且不是空格或行尾,在后面添加空格
290
- if (nextChar && nextChar !== " " && !/[\s)}\]]/.test(nextChar)) {
291
- contentToInsert = contentToInsert + " ";
292
- }
293
-
294
- // 在光标位置插入内容
295
- const newLine = line.substring(0, columnIndex) + contentToInsert + line.substring(columnIndex);
296
- lines[lineIndex] = newLine;
297
-
298
- // 更新编辑器内容
299
- const newValue = lines.join("\n");
300
- monacoEditorRef.value.setValue(newValue);
301
-
302
- // 将光标移动到插入内容之后
303
- const newColumn = position.column + contentToInsert.length;
304
- editorIns.setPosition({
305
- lineNumber: position.lineNumber,
306
- column: newColumn,
307
- });
308
- editorIns.focus();
309
- }
310
- };
311
- // 脚本: 复制
312
- const handleScriptCopy = async () => {
313
- try {
314
- scriptCopyLoading.value = true;
315
- const script = monacoEditorRef.value.getValue();
316
- if (!script) return ElMessage.error("请输入脚本语句");
317
- const { body } = await request.post("/common/qt/getFuncExpr", { factorSelectExpr: script });
318
- if (!body) return ElMessage.error("脚本解析失败, 请检查脚本内容是否填写完整或者联系管理员");
319
- // 复制内容到粘贴板
320
- let txa = document.createElement("textarea");
321
- txa.value = body;
322
- document.body.appendChild(txa);
323
- txa.select();
324
- document.execCommand("copy");
325
- document.body.removeChild(txa);
326
- ElMessage.success("脚本内容已经成功复制到粘贴板");
327
- } finally {
328
- scriptCopyLoading.value = false;
329
- emit("actionState", "因子筛选", "复制");
330
- }
331
- };
332
-
333
- // 测试: 复制
334
- const handleTestCodeCopy = () => {
335
- let txa = document.createElement("textarea");
336
- txa.value = scriptTestResult.code;
337
- document.body.appendChild(txa);
338
- txa.select();
339
- document.execCommand("copy");
340
- document.body.removeChild(txa);
341
- ElMessage.success("测试代码已经成功复制到粘贴板");
342
- };
343
- // 测试: 打开/确认/日志
344
- const extractCodesFromString = (str) => {
345
- if (!str) return [];
346
- return str.split("\n").reduce((result, next) => {
347
- const code = next.trim().replace(/\s+/gi, " ").split(" ")[0];
348
- code && result.push(code);
349
- return result;
350
- }, []);
351
- };
352
- const handleScriptTest = async (action) => {
353
- switch (action) {
354
- case "open": {
355
- // 基础校验
356
- if (!monacoEditorRef.value.getValue()) return ElMessage.error("脚本语句不可为空");
357
- testVarietyVisible.value = true;
358
- break;
359
- }
360
- case "submit": {
361
- testVarietyVisible.value = false;
362
- try {
363
- scriptTestLoading.value = true;
364
- const { body } = await request.post("/common/qt/getFuncExpr", { factorSelectExpr: monacoEditorRef.value.getValue() });
365
- if (!body) return ElMessage.error("脚本解析失败, 请检查脚本内容是否填写完整或者联系管理员");
366
- const params = {
367
- codes: extractCodesFromString(testVariety.value),
368
- factorSelectExpr: body,
369
- };
370
- const testRes = await request.post("/common/qt/testFactorSelect", params);
371
- const { result, detail } = testRes.body;
372
- Object.assign(scriptTestResult, { result, detail, code: body, ai: "" });
373
- if (result === 1) {
374
- ElMessage.success("测试通过");
375
- } else {
376
- ElMessage.error("测试未能通过");
377
- scriptTestLogVisible.value = true;
378
- }
379
- } finally {
380
- scriptTestLoading.value = false;
381
- emit("actionState", "因子筛选", "测试");
382
- }
383
- break;
384
- }
385
- case "log": {
386
- if (scriptTestResult.result === null) {
387
- return ElMessage.warning("请先进行测试, 等待测试完成后可查看日志");
388
- }
389
- scriptTestLogVisible.value = true;
390
- break;
391
- }
392
- }
393
- };
394
- // 测试: AI分析
395
- const handleTestAi = () => {
396
- emit("actionState", "因子筛选", "AI分析");
397
- scriptAILoading.value = true;
398
- scriptAIButtonLoading.value = true;
399
- scriptTestResult.ai = "";
400
- try {
401
- sendToNodeFactorAiTest({
402
- baseUrl: env.VITE_BASE_URL,
403
- token: getToken(),
404
- value: scriptTestResult.code,
405
- callback: (type, data) => {
406
- if (type === "error") {
407
- scriptAILoading.value = false;
408
- scriptAIButtonLoading.value = false;
409
- ElMessage.error("AI分析失败: " + data);
410
- return;
411
- }
412
- if (type === "message") {
413
- scriptAILoading.value = false;
414
- scriptTestResult.ai += data;
415
- }
416
- if (type === "finish") {
417
- scriptAILoading.value = false;
418
- scriptAIButtonLoading.value = false;
419
- }
420
- },
421
- });
422
- } catch (error) {
423
- ElMessage.error(`AI响应异常: ${error}`);
424
- scriptTestResult.ai = error;
425
- scriptAILoading.value = false;
426
- scriptAIButtonLoading.value = false;
427
- }
428
- };
429
-
430
- // 监控: 窗口开关
431
- watch(
432
- () => visible.value,
433
- (newValue) => {
434
- switch (newValue) {
435
- case true: {
436
- nextTick(() => {
437
- monacoEditorRef.value.resize();
438
- // 如果有脚本内容, 直接切换到脚本模式, 并将值回显
439
- if (data.value.factorSelectExpr) {
440
- factorType.value = "脚本";
441
- monacoEditorRef.value.setValue(data.value.factorSelectExpr);
442
- monacoEditorRef.value.focusToEnd();
443
- }
444
- // 如果有模板内容, 直接切换到模板模式
445
- if ((data.value.sqlEnable && data.value.sqlValue) || (!data.value.sqlEnable && data.value.list.length)) {
446
- factorType.value = "模版";
447
- }
448
- });
449
- // 重置测试结果
450
- Object.assign(scriptTestResult, {
451
- result: null,
452
- detail: "",
453
- code: "",
454
- ai: "",
455
- });
456
- break;
457
- }
458
- case false: {
459
- stVarSelectDialogRef.value.close();
460
- scriptTestLogVisible.value = false;
461
- testVariety.value = "";
462
- break;
463
- }
464
- }
465
- },
466
- );
467
- // 监控: 因子类型
468
- watch(
469
- () => factorType.value,
470
- (newValue) => {
471
- if (newValue === "模版") stVarSelectDialogRef.value.close();
472
- if (newValue === "脚本") {
473
- nextTick(() => {
474
- monacoEditorRef.value.focusToEnd();
475
- });
476
- }
477
- },
478
- { deep: true },
479
- );
480
- </script>
481
-
482
- <template>
483
- <div class="factor-screen">
484
- <!-- 文案 + 添加按钮 -->
485
- <div>
486
- <!-- Tag文案[开启SQL] -->
487
- <template v-if="data.sqlEnable && data.sqlValue">
488
- <el-tag
489
- closable
490
- type="info"
491
- :title="data.sqlValue"
492
- @close="handleDeleteTag('sqlTag')"
493
- >
494
- <el-text
495
- type="info"
496
- truncated
497
- style="max-width: 500px"
498
- >
499
- {{ data.sqlValue }}
500
- </el-text>
501
- </el-tag>
502
- </template>
503
- <!-- Tag文案[关闭SQL] -->
504
- <template v-if="!data.sqlEnable && data.list.length">
505
- <el-tag
506
- v-for="(tag, index) in data.list"
507
- closable
508
- type="info"
509
- @close="handleDeleteTag('factorTag', index)"
510
- >
511
- {{ handleFormatTag(tag) }}
512
- </el-tag>
513
- </template>
514
- <!-- 脚本模式 -->
515
- <el-popover
516
- v-if="data.factorSelectExpr"
517
- width="500"
518
- placement="bottom-start"
519
- >
520
- <div style="white-space: pre-line">
521
- {{ data.factorSelectExpr }}
522
- </div>
523
- <template #reference>
524
- <el-tag
525
- closable
526
- type="info"
527
- @close="handleDeleteTag('scriptTag')"
528
- >
529
- 脚本模式
530
- </el-tag>
531
- </template>
532
- </el-popover>
533
- <!-- 添加按钮 -->
534
- <el-button
535
- class="screen-btn"
536
- type="primary"
537
- plain
538
- size="small"
539
- :icon="Plus"
540
- @click="handleOpenDialog"
541
- >
542
- 添加因子
543
- </el-button>
544
- </div>
545
- <!-- 因子筛选弹窗 -->
546
- <el-dialog
547
- modal-class="factor-dialog"
548
- v-model="visible"
549
- width="1000"
550
- align-center
551
- destroy-on-close
552
- draggable
553
- overflow
554
- :modal="false"
555
- :modal-penetrable="true"
556
- :show-close="false"
557
- >
558
- <template #header="{ titleId, titleClass }">
559
- <div class="custom-header">
560
- <div class="left">
561
- <span
562
- :id="titleId"
563
- :class="titleClass"
564
- >
565
- 因子筛选
566
- </span>
567
- <!-- 因子使用说明 -->
568
- <el-tooltip
569
- effect="dark"
570
- content="点击查看: 因子使用说明"
571
- placement="right"
572
- >
573
- <el-icon @click="visibleDescriptions = true"><InfoFilled /></el-icon>
574
- </el-tooltip>
575
- <!-- 因子模式 -->
576
- <el-radio-group
577
- v-model="factorType"
578
- size="small"
579
- >
580
- <el-radio-button
581
- label="模版"
582
- value="模版"
583
- />
584
- <el-radio-button
585
- label="脚本"
586
- value="脚本"
587
- />
588
- </el-radio-group>
589
- <!-- 脚本模式: 自定义函数插入新建, 脚本测试, 脚本复制 -->
590
- <div
591
- class="editor-tools"
592
- v-show="factorType === '脚本'"
593
- >
594
- <st-customFunction
595
- v-show="factorType === '脚本'"
596
- size="small"
597
- @insert="handleInsertCustomFunction"
598
- @actionState="(...args) => emit('actionState', ...args)"
599
- />
600
- <el-button
601
- type="primary"
602
- size="small"
603
- :loading="scriptCopyLoading"
604
- @click="handleScriptCopy"
605
- >复制</el-button
606
- >
607
- <el-button
608
- type="primary"
609
- size="small"
610
- :loading="scriptTestLoading"
611
- @click="handleScriptTest('open')"
612
- >测试</el-button
613
- >
614
- <el-button
615
- size="small"
616
- :icon="Document"
617
- @click="handleScriptTest('log')"
618
- >日志明细</el-button
619
- >
620
- </div>
621
- </div>
622
- <!-- 变量选择器 + 关闭 -->
623
- <div class="right">
624
- <el-button
625
- v-if="factorType === '脚本'"
626
- size="small"
627
- type="primary"
628
- @click="open"
629
- >变量选择器</el-button
630
- >
631
- <el-icon @click="visible = false"><Close /></el-icon>
632
- </div>
633
- </div>
634
- </template>
635
- <!-- 模版模式 -->
636
- <el-scrollbar
637
- v-if="factorType === '模版'"
638
- height="400px"
639
- >
640
- <el-form
641
- ref="dialogFormRef"
642
- :model="dialogForm"
643
- >
644
- <!-- 因子筛选表格 -->
645
- <div
646
- v-for="(item, index) in dialogForm.list"
647
- class="form-row"
648
- >
649
- <!-- 序列号 -->
650
- <span class="index">{{ `条件${index + 1}` }}</span>
651
- <!-- 对比因子: 分值因子 -->
652
- <template v-if="item.key === 'compare'">
653
- <!-- 周期 -->
654
- <el-form-item
655
- v-if="config.cycleShow"
656
- :prop="'list.' + index + '.cycle'"
657
- :rules="{ required: true, message: '周期不能为空', trigger: 'blur' }"
658
- style="width: 100px; margin-right: 10px"
659
- >
660
- <el-select
661
- v-model="item.cycle"
662
- placeholder="选择周期"
663
- size="small"
664
- >
665
- <el-option
666
- v-for="{ label, value } in config.cycleOptions"
667
- :label="label"
668
- :value="value"
669
- :key="value"
670
- />
671
- </el-select>
672
- </el-form-item>
673
- <!-- 因子 -->
674
- <el-form-item
675
- :prop="'list.' + index + '.factor'"
676
- :rules="{ required: true, message: '因子不能为空', trigger: 'blur' }"
677
- style="width: 132px; margin-right: 10px"
678
- >
679
- <el-select
680
- v-model="item.factor"
681
- placeholder="选择因子"
682
- filterable
683
- size="small"
684
- no-match-text="无匹配数据"
685
- >
686
- <el-option
687
- v-for="{ label, value } in config.factorOptions?.filter((item) => [4].includes(item.type))"
688
- :label="label"
689
- :value="value"
690
- :key="value"
691
- />
692
- </el-select>
693
- </el-form-item>
694
- <!-- 对比符 -->
695
- <el-form-item style="width: 52px; margin-right: 10px">
696
- <el-select
697
- v-model="item.compareType"
698
- size="small"
699
- >
700
- <el-option
701
- v-for="item in ['>', '>=', '<', '<=']"
702
- :label="item"
703
- :value="item"
704
- :key="item"
705
- />
706
- </el-select>
707
- </el-form-item>
708
- <!-- 周期2 -->
709
- <el-form-item
710
- v-if="config.cycleShow"
711
- :prop="'list.' + index + '.cycle2'"
712
- :rules="{ required: true, message: '周期不能为空', trigger: 'blur' }"
713
- style="width: 100px; margin-right: 10px"
714
- >
715
- <el-select
716
- v-model="item.cycle2"
717
- placeholder="选择周期"
718
- size="small"
719
- >
720
- <el-option
721
- v-for="{ label, value } in config.cycleOptions"
722
- :label="label"
723
- :value="value"
724
- :key="value"
725
- />
726
- </el-select>
727
- </el-form-item>
728
- <!-- 因子2 -->
729
- <el-form-item
730
- :prop="'list.' + index + '.factor2'"
731
- :rules="{ required: true, message: '因子不能为空', trigger: 'blur' }"
732
- style="width: 132px; margin-right: 10px"
733
- >
734
- <el-select
735
- v-model="item.factor2"
736
- placeholder="选择因子"
737
- filterable
738
- size="small"
739
- no-match-text="无匹配数据"
740
- >
741
- <el-option
742
- v-for="{ label, value } in config.factorOptions?.filter((item) => [4].includes(item.type))"
743
- :label="label"
744
- :value="value"
745
- :key="value"
746
- />
747
- </el-select>
748
- </el-form-item>
749
- </template>
750
- <!-- 常规因子: 机器打分, 人工打分因子 -->
751
- <template v-else>
752
- <!-- 周期 -->
753
- <el-form-item
754
- v-if="config.cycleShow"
755
- :prop="'list.' + index + '.cycle'"
756
- :rules="{ required: true, message: '周期不能为空', trigger: 'blur' }"
757
- style="width: 100px; margin-right: 10px"
758
- >
759
- <el-select
760
- v-model="item.cycle"
761
- placeholder="选择周期"
762
- size="small"
763
- >
764
- <el-option
765
- v-for="{ label, value } in config.cycleOptions"
766
- :label="label"
767
- :value="value"
768
- :key="value"
769
- />
770
- </el-select>
771
- </el-form-item>
772
- <!-- 因子 -->
773
- <el-form-item
774
- :prop="'list.' + index + '.factor'"
775
- :rules="{ required: true, message: '因子不能为空', trigger: 'blur' }"
776
- style="width: 194px; margin-right: 10px"
777
- >
778
- <el-select
779
- v-model="item.factor"
780
- placeholder="选择因子"
781
- filterable
782
- size="small"
783
- no-match-text="无匹配数据"
784
- >
785
- <el-option
786
- v-for="{ label, value } in config.factorOptions?.filter((item) => [1, 3].includes(item.type))"
787
- :label="label"
788
- :value="value"
789
- :key="value"
790
- />
791
- </el-select>
792
- </el-form-item>
793
- <!-- 分数 -->
794
- <el-form-item
795
- :prop="'list.' + index + '.score'"
796
- :rules="{ validator: handleVerifyScore, trigger: 'blur' }"
797
- style="width: 200px; margin-right: 10px"
798
- >
799
- <div style="display: flex; align-items: center; width: 100%; height: 24px">
800
- <el-input-number
801
- v-model="item.score[0]"
802
- size="small"
803
- controls-position="right"
804
- />
805
- <span>~</span>
806
- <el-input-number
807
- v-model="item.score[1]"
808
- size="small"
809
- controls-position="right"
810
- />
811
- </div>
812
- </el-form-item>
813
- </template>
814
- <!-- 删除 -->
815
- <el-icon @click="handleDeleteFactor(index)"><CircleCloseFilled /></el-icon>
816
- </div>
817
- <el-button
818
- type="primary"
819
- plain
820
- size="small"
821
- :icon="Plus"
822
- @click="handleAppendFactor"
823
- style="margin-bottom: 10px"
824
- >添加因子</el-button
825
- >
826
- <el-button
827
- type="primary"
828
- plain
829
- size="small"
830
- :icon="Plus"
831
- @click="handleAppendFactor('compare')"
832
- style="margin-bottom: 10px"
833
- >添加因子对比</el-button
834
- >
835
- <!-- SQL功能 -->
836
- <template v-if="config.sqlShow">
837
- <el-form-item label="SQL功能: ">
838
- <el-radio-group v-model="dialogForm.sqlEnable">
839
- <el-radio
840
- label="关闭"
841
- :value="0"
842
- />
843
- <el-radio
844
- label="启用"
845
- :value="1"
846
- />
847
- </el-radio-group>
848
- <el-button
849
- v-if="dialogForm.sqlEnable"
850
- type="primary"
851
- size="small"
852
- @click="handleGenerateSql"
853
- style="margin-left: auto"
854
- >生成SQL</el-button
855
- >
856
- </el-form-item>
857
- <template v-if="dialogForm.sqlEnable">
858
- <el-input
859
- v-model="dialogForm.sqlValue"
860
- :autosize="{ minRows: 4 }"
861
- type="textarea"
862
- style="margin-bottom: 10px"
863
- />
864
- <span>&&代表and,||代表or</span>
865
- </template>
866
- </template>
867
- </el-form>
868
- </el-scrollbar>
869
- <!-- 脚本模式 -->
870
- <div
871
- style="width: 968px; height: 400px"
872
- :style="factorType === '脚本' ? null : { position: 'fixed', top: '-400px', zIndex: -1, visibility: 'hidden', pointerEvents: 'none' }"
873
- >
874
- <MonacoEditor
875
- ref="monacoEditorRef"
876
- :language="'lua'"
877
- :suggestionEnable="true"
878
- :variableEnable="true"
879
- />
880
- </div>
881
- <template #footer>
882
- <div class="dialog-footer">
883
- <el-button
884
- type="primary"
885
- @click="handleSubmit"
886
- >确定</el-button
887
- >
888
- </div>
889
- </template>
890
- </el-dialog>
891
- </div>
892
- <!-- 因子说明: 机器打分, 人工打分因子 -->
893
- <FactorDescription
894
- v-model:visible="visibleDescriptions"
895
- :factorType="factorType"
896
- :data="config.factorDescriptions?.filter((item) => [1, 3].includes(item.type))"
897
- />
898
- <!-- 窗口: 选择测试所用的品种 -->
899
- <el-dialog
900
- modal-class="test-variety-dialog"
901
- v-model="testVarietyVisible"
902
- width="500"
903
- align-center
904
- append-to-body
905
- overflow
906
- :modal="false"
907
- :modal-penetrable="true"
908
- :show-close="false"
909
- >
910
- <template #header="{ titleId, titleClass }">
911
- <div class="custom-header">
912
- <div class="left">
913
- <span
914
- :id="titleId"
915
- :class="titleClass"
916
- >
917
- 测试品种
918
- </span>
919
- </div>
920
- <div class="right">
921
- <st-varietyAutoComplete
922
- label=""
923
- @select="({ name, code }) => (testVariety += `${code} ${name} \n`)"
924
- />
925
- <el-icon @click="testVarietyVisible = false"><Close /></el-icon>
926
- </div>
927
- </div>
928
- </template>
929
- <el-input
930
- class="full-height-textarea"
931
- v-model="testVariety"
932
- resize="none"
933
- type="textarea"
934
- :placeholder="`不填写时, 默认为000001 平安银行\n格式示例:\nhc8888\xa0\xa0\xa0\xa0热轧卷板期货指数\nsp8888\xa0\xa0\xa0\xa0纸浆期货指数\nbu8888\xa0\xa0\xa0\xa0石油沥青期货指数`"
935
- />
936
- <template #footer>
937
- <div class="dialog-footer">
938
- <el-button
939
- type="primary"
940
- @click="handleScriptTest('submit')"
941
- >
942
- 确认
943
- </el-button>
944
- </div>
945
- </template>
946
- </el-dialog>
947
- <!-- 窗口: 日志明细 -->
948
- <el-dialog
949
- modal-class="log-dialog"
950
- v-model="scriptTestLogVisible"
951
- width="80vw"
952
- align-center
953
- append-to-body
954
- draggable
955
- overflow
956
- :modal="false"
957
- :modal-penetrable="true"
958
- :show-close="false"
959
- >
960
- <template #header="{ titleId, titleClass }">
961
- <div class="custom-header">
962
- <div class="left">
963
- <span
964
- :id="titleId"
965
- :class="titleClass"
966
- >
967
- 日志明细
968
- </span>
969
- </div>
970
- <!-- 关闭 -->
971
- <div class="right">
972
- <el-icon @click="scriptTestLogVisible = false"><Close /></el-icon>
973
- </div>
974
- </div>
975
- </template>
976
- <div class="content">
977
- <!-- 代码 -->
978
- <el-scrollbar
979
- class="code"
980
- height="600px"
981
- >
982
- <pre>{{ scriptTestResult.code }}</pre>
983
- </el-scrollbar>
984
- <!-- 日志 -->
985
- <el-scrollbar
986
- class="log"
987
- height="600px"
988
- >
989
- <pre :class="scriptTestResult.result === 1 ? 'success-log' : 'error-log'">{{ scriptTestResult.result === 1 ? `✅️ 测试通过\n${scriptTestResult.detail}` : scriptTestResult.detail }}</pre>
990
- </el-scrollbar>
991
- <!-- AI分析结果 -->
992
- <el-scrollbar
993
- class="ai"
994
- height="600px"
995
- >
996
- <v-md-editor
997
- v-if="scriptTestResult.ai"
998
- mode="preview"
999
- :model-value="scriptTestResult.ai"
1000
- />
1001
- <!-- 正在进行AI分析, 并且没有返回结果时, 展示骨架屏 -->
1002
- <el-skeleton
1003
- v-else-if="scriptAILoading"
1004
- :rows="5"
1005
- animated
1006
- />
1007
- <!-- 未进行AI分析, 并且没有返回结果时, 展示文案 -->
1008
- <el-empty
1009
- v-else-if="!scriptAILoading"
1010
- description="点击下方按钮: AI分析, 分析结果将会展示在此处"
1011
- />
1012
- </el-scrollbar>
1013
- </div>
1014
- <!-- 底部 -->
1015
- <template #footer>
1016
- <div class="dialog-footer">
1017
- <el-button
1018
- type="primary"
1019
- :loading="scriptAIButtonLoading"
1020
- @click="handleTestAi"
1021
- >
1022
- AI分析
1023
- </el-button>
1024
- <el-button
1025
- type="primary"
1026
- @click="handleTestCodeCopy"
1027
- >
1028
- 复制
1029
- </el-button>
1030
- <el-button @click="scriptTestLogVisible = false">关闭</el-button>
1031
- </div>
1032
- </template>
1033
- </el-dialog>
1034
- <!-- 变量选择器 -->
1035
- <st-varSelectDialog ref="stVarSelectDialogRef" />
1036
- </template>
1037
-
1038
- <style lang="scss" scoped>
1039
- .factor-screen {
1040
- .el-tag {
1041
- margin-right: 10px;
1042
- }
1043
- .custom-header {
1044
- display: flex;
1045
- align-items: center;
1046
- justify-content: space-between;
1047
- .left,
1048
- .right {
1049
- display: flex;
1050
- align-items: center;
1051
- gap: 10px;
1052
- }
1053
- .editor-tools {
1054
- display: flex;
1055
- align-items: center;
1056
- gap: 10px;
1057
- .el-button {
1058
- margin: 0;
1059
- }
1060
- }
1061
- .el-icon {
1062
- cursor: pointer;
1063
- }
1064
- }
1065
- .form-row {
1066
- display: flex;
1067
- align-items: center;
1068
- justify-content: start;
1069
- margin-bottom: 18px;
1070
- .index {
1071
- display: inline-block;
1072
- width: 50px;
1073
- height: 22px;
1074
- }
1075
- .el-form-item {
1076
- margin: 0;
1077
- }
1078
- .el-icon {
1079
- cursor: pointer;
1080
- }
1081
- }
1082
- }
1083
- .test-variety-dialog {
1084
- .custom-header {
1085
- display: flex;
1086
- align-items: center;
1087
- justify-content: space-between;
1088
- .left,
1089
- .right {
1090
- display: flex;
1091
- align-items: center;
1092
- gap: 10px;
1093
- }
1094
- .el-icon {
1095
- cursor: pointer;
1096
- }
1097
- }
1098
- .full-height-textarea {
1099
- width: 100%;
1100
- height: 200px;
1101
- margin-top: 10px;
1102
- :deep(.el-textarea__inner) {
1103
- box-sizing: border-box;
1104
- height: 100%;
1105
- }
1106
- }
1107
- }
1108
- .log-dialog {
1109
- .custom-header {
1110
- display: flex;
1111
- align-items: center;
1112
- justify-content: space-between;
1113
- .left,
1114
- .right {
1115
- display: flex;
1116
- align-items: center;
1117
- gap: 10px;
1118
- }
1119
- .el-icon {
1120
- cursor: pointer;
1121
- }
1122
- }
1123
- .content {
1124
- display: flex;
1125
- gap: 1px;
1126
- .el-scrollbar {
1127
- background-color: var(--el-color-black);
1128
- flex: 1;
1129
- box-sizing: border-box;
1130
- padding: 8px;
1131
- border: var(--el-border);
1132
- }
1133
- .code {
1134
- color: var(--el-color-info);
1135
- }
1136
- .success-log {
1137
- color: var(--el-color-success);
1138
- }
1139
- .error-log {
1140
- color: var(--el-color-danger);
1141
- }
1142
- pre {
1143
- margin: 0;
1144
- line-height: 1.5;
1145
- white-space: pre-wrap;
1146
- word-break: break-all;
1147
- word-wrap: break-word;
1148
- }
1149
- .ai {
1150
- flex: 1;
1151
- background-color: white;
1152
- :deep(.vuepress-markdown-body) {
1153
- padding: 0;
1154
- }
1155
- }
1156
- }
1157
- }
1158
- </style>