st-comp 0.0.210 → 0.0.212
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.
- package/es/CustomFunction.cjs +1 -1
- package/es/CustomFunction.js +7 -7
- package/es/VarietySearch.cjs +13 -13
- package/es/VarietySearch.js +2008 -1849
- package/es/VarietyTextCopy.cjs +3 -3
- package/es/VarietyTextCopy.js +4 -4
- package/es/style.css +1 -1
- package/lib/bundle.js +1 -1
- package/lib/bundle.umd.cjs +175 -175
- package/lib/{index-a5dba4c8.js → index-7624f550.js} +17407 -17249
- package/lib/{python-198536af.js → python-b043127b.js} +1 -1
- package/lib/style.css +1 -1
- package/package.json +1 -1
- package/packages/VarietySearch/components/CompositeOrder/index.vue +31 -12
- package/packages/VarietySearch/components/FactorScreen/index.vue +207 -10
package/package.json
CHANGED
|
@@ -11,7 +11,11 @@ const props = defineProps({
|
|
|
11
11
|
commonOption: { type: Array, default: () => [] }, // 已选常用选项
|
|
12
12
|
});
|
|
13
13
|
const visible = ref(false);
|
|
14
|
-
const compositeOrderForm = ref({
|
|
14
|
+
const compositeOrderForm = ref({
|
|
15
|
+
id: null,
|
|
16
|
+
name: null, // 字段名
|
|
17
|
+
value: "desc", // 排序
|
|
18
|
+
});
|
|
15
19
|
|
|
16
20
|
// 组合排序数据源 [受到: 品种市场, 常用选项影响]
|
|
17
21
|
const compositeOrderOptions = computed(() => {
|
|
@@ -41,7 +45,7 @@ const handleAction = (action, index) => {
|
|
|
41
45
|
switch (action) {
|
|
42
46
|
// 新增
|
|
43
47
|
case "add": {
|
|
44
|
-
compositeOrderForm.value = { name: null, value: "desc" };
|
|
48
|
+
compositeOrderForm.value = { id: null, name: null, value: "desc" };
|
|
45
49
|
visible.value = true;
|
|
46
50
|
break;
|
|
47
51
|
}
|
|
@@ -54,22 +58,37 @@ const handleAction = (action, index) => {
|
|
|
54
58
|
}
|
|
55
59
|
// 窗口确认
|
|
56
60
|
case "submit": {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
data.value.
|
|
61
|
+
const { id, name, value } = compositeOrderForm.value;
|
|
62
|
+
if (!name) return ElMessage.warning("请选择需要排序的条件");
|
|
63
|
+
const { label } = compositeOrderOptions.value.find((item) => item.key === name);
|
|
64
|
+
const tagText = `${label}-${value === "asc" ? "正序↑" : "降序↓"}`;
|
|
65
|
+
|
|
66
|
+
// 新增确认逻辑
|
|
67
|
+
if (id === null) {
|
|
68
|
+
// 判断data中是否已存在同字段条件, 是则替换, 否则push
|
|
69
|
+
const index = data.value.findIndex((item) => item.name === name);
|
|
70
|
+
if (index === -1) {
|
|
71
|
+
data.value.push({ ...compositeOrderForm.value, id: name, tagText });
|
|
72
|
+
} else {
|
|
73
|
+
data.value.splice(index, 1, { ...compositeOrderForm.value, id: name, tagText });
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// 编辑确认逻辑
|
|
77
|
+
else if (compositeOrderForm.value.id) {
|
|
78
|
+
// 修改当前位置的内容, 并将其他相同name的删除掉
|
|
79
|
+
const index = data.value.findIndex((item) => item.name === id);
|
|
80
|
+
const index2 = data.value.findIndex((item) => item.name === name);
|
|
81
|
+
data.value[index] = { ...compositeOrderForm.value, id: name, tagText };
|
|
82
|
+
if (index2 !== -1 && index !== index2) data.value.splice(index2, 1);
|
|
66
83
|
}
|
|
84
|
+
|
|
67
85
|
visible.value = false;
|
|
68
86
|
break;
|
|
69
87
|
}
|
|
70
88
|
// 删除
|
|
71
89
|
case "delete": {
|
|
72
90
|
data.value.splice(index, 1);
|
|
91
|
+
visible.value = false;
|
|
73
92
|
break;
|
|
74
93
|
}
|
|
75
94
|
}
|
|
@@ -84,7 +103,7 @@ watch(
|
|
|
84
103
|
return compositeOrderOptions.value.find((item) => item.key === name);
|
|
85
104
|
});
|
|
86
105
|
}
|
|
87
|
-
}
|
|
106
|
+
},
|
|
88
107
|
);
|
|
89
108
|
</script>
|
|
90
109
|
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
<!-- 因子筛选组件 -->
|
|
2
2
|
<script setup name="FactorScreen">
|
|
3
|
-
import { nextTick, ref, watch } from "vue";
|
|
4
|
-
import { Close, Plus, CircleCloseFilled, InfoFilled } from "@element-plus/icons-vue";
|
|
3
|
+
import { nextTick, ref, watch, inject, reactive } from "vue";
|
|
4
|
+
import { Close, Plus, CircleCloseFilled, InfoFilled, Document } from "@element-plus/icons-vue";
|
|
5
5
|
import { handleVerifyScore, extractConditionDetails, extractVariables } from "./tools.js";
|
|
6
6
|
import FactorDescription from "./FactorDescription.vue";
|
|
7
7
|
import MonacoEditor from "../../../MonacoEditor/index.vue";
|
|
8
8
|
|
|
9
|
+
const { request } = inject("stConfig"); // 组件库全局配置
|
|
10
|
+
|
|
9
11
|
const props = defineProps({
|
|
10
12
|
config: {
|
|
11
13
|
type: Object,
|
|
@@ -29,10 +31,20 @@ const data = defineModel("data", {
|
|
|
29
31
|
|
|
30
32
|
const monacoEditorRef = ref();
|
|
31
33
|
const stVarSelectDialogRef = ref();
|
|
34
|
+
|
|
32
35
|
// 弹窗开关
|
|
33
36
|
const visible = ref(false);
|
|
34
37
|
const visibleDescriptions = ref(false);
|
|
35
38
|
const factorType = ref("脚本");
|
|
39
|
+
const scriptTestLoading = ref(false);
|
|
40
|
+
const scriptCopyLoading = ref(false);
|
|
41
|
+
const scriptTestLogVisible = ref(false);
|
|
42
|
+
const scriptTestResult = reactive({
|
|
43
|
+
result: null,
|
|
44
|
+
detail: "",
|
|
45
|
+
code: "",
|
|
46
|
+
});
|
|
47
|
+
|
|
36
48
|
// 弹窗表单
|
|
37
49
|
const dialogFormRef = ref(null);
|
|
38
50
|
const dialogForm = ref({
|
|
@@ -227,7 +239,7 @@ const handleDeleteTag = (aciton, index) => {
|
|
|
227
239
|
const open = () => {
|
|
228
240
|
stVarSelectDialogRef.value.open(monacoEditorRef.value);
|
|
229
241
|
};
|
|
230
|
-
// 插入自定义函数
|
|
242
|
+
// 脚本: 插入自定义函数
|
|
231
243
|
const handleInsertCustomFunction = (funcName, funcExpression) => {
|
|
232
244
|
if (!monacoEditorRef.value) return ElMessage.error("未检测到编辑器实例");
|
|
233
245
|
// 生成基础插入内容 (如果内含${}, 需提取出来, 作为变量)
|
|
@@ -288,6 +300,54 @@ const handleInsertCustomFunction = (funcName, funcExpression) => {
|
|
|
288
300
|
editorIns.focus();
|
|
289
301
|
}
|
|
290
302
|
};
|
|
303
|
+
// 脚本: 复制
|
|
304
|
+
const handleScriptCopy = async () => {
|
|
305
|
+
try {
|
|
306
|
+
scriptCopyLoading.value = true;
|
|
307
|
+
const script = monacoEditorRef.value.getValue();
|
|
308
|
+
if (!script) return ElMessage.error("请输入脚本语句");
|
|
309
|
+
const { body } = await request.post("/common/qt/getFuncExpr", { factorSelectExpr: script });
|
|
310
|
+
if (!body) return ElMessage.error("脚本解析失败, 请检查脚本内容是否填写完整或者联系管理员");
|
|
311
|
+
// 复制内容到粘贴板
|
|
312
|
+
let txa = document.createElement("textarea");
|
|
313
|
+
txa.value = body;
|
|
314
|
+
document.body.appendChild(txa);
|
|
315
|
+
txa.select();
|
|
316
|
+
document.execCommand("copy");
|
|
317
|
+
document.body.removeChild(txa);
|
|
318
|
+
ElMessage.success("脚本内容已经成功复制到粘贴板");
|
|
319
|
+
} finally {
|
|
320
|
+
scriptCopyLoading.value = false;
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
// 脚本: 测试
|
|
324
|
+
const handleScriptTest = async () => {
|
|
325
|
+
try {
|
|
326
|
+
scriptTestLoading.value = true;
|
|
327
|
+
const script = monacoEditorRef.value.getValue();
|
|
328
|
+
if (!script) return ElMessage.error("请输入脚本语句");
|
|
329
|
+
const { body } = await request.post("/common/qt/getFuncExpr", { factorSelectExpr: script });
|
|
330
|
+
if (!body) return ElMessage.error("脚本解析失败, 请检查脚本内容是否填写完整或者联系管理员");
|
|
331
|
+
const testRes = await request.post("/common/qt/testFactorSelect", { factorSelectExpr: body });
|
|
332
|
+
const { result, detail } = testRes.body;
|
|
333
|
+
Object.assign(scriptTestResult, { result, detail, code: body });
|
|
334
|
+
if (result === 1) {
|
|
335
|
+
ElMessage.success("测试通过");
|
|
336
|
+
} else {
|
|
337
|
+
ElMessage.error("测试未能通过");
|
|
338
|
+
scriptTestLogVisible.value = true;
|
|
339
|
+
}
|
|
340
|
+
} finally {
|
|
341
|
+
scriptTestLoading.value = false;
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
// 脚本: 日志明细
|
|
345
|
+
const handleScriptLog = () => {
|
|
346
|
+
if (scriptTestResult.result === null) {
|
|
347
|
+
return ElMessage.warning("请先进行测试, 等待测试完成后可查看日志");
|
|
348
|
+
}
|
|
349
|
+
scriptTestLogVisible.value = true;
|
|
350
|
+
};
|
|
291
351
|
|
|
292
352
|
// 监控: 窗口开关
|
|
293
353
|
watch(
|
|
@@ -308,16 +368,21 @@ watch(
|
|
|
308
368
|
factorType.value = "模版";
|
|
309
369
|
}
|
|
310
370
|
});
|
|
371
|
+
// 重置测试结果
|
|
372
|
+
Object.assign(scriptTestResult, {
|
|
373
|
+
result: null,
|
|
374
|
+
detail: "",
|
|
375
|
+
});
|
|
311
376
|
break;
|
|
312
377
|
}
|
|
313
378
|
case false: {
|
|
314
379
|
stVarSelectDialogRef.value.close();
|
|
380
|
+
scriptTestLogVisible.value = false;
|
|
315
381
|
break;
|
|
316
382
|
}
|
|
317
383
|
}
|
|
318
|
-
}
|
|
384
|
+
},
|
|
319
385
|
);
|
|
320
|
-
|
|
321
386
|
// 监控: 因子类型
|
|
322
387
|
watch(
|
|
323
388
|
() => factorType.value,
|
|
@@ -329,7 +394,7 @@ watch(
|
|
|
329
394
|
});
|
|
330
395
|
}
|
|
331
396
|
},
|
|
332
|
-
{ deep: true }
|
|
397
|
+
{ deep: true },
|
|
333
398
|
);
|
|
334
399
|
</script>
|
|
335
400
|
|
|
@@ -418,6 +483,7 @@ watch(
|
|
|
418
483
|
>
|
|
419
484
|
因子筛选
|
|
420
485
|
</span>
|
|
486
|
+
<!-- 因子使用说明 -->
|
|
421
487
|
<el-tooltip
|
|
422
488
|
effect="dark"
|
|
423
489
|
content="点击查看: 因子使用说明"
|
|
@@ -425,6 +491,7 @@ watch(
|
|
|
425
491
|
>
|
|
426
492
|
<el-icon @click="visibleDescriptions = true"><InfoFilled /></el-icon>
|
|
427
493
|
</el-tooltip>
|
|
494
|
+
<!-- 因子模式 -->
|
|
428
495
|
<el-radio-group
|
|
429
496
|
v-model="factorType"
|
|
430
497
|
size="small"
|
|
@@ -438,11 +505,37 @@ watch(
|
|
|
438
505
|
value="脚本"
|
|
439
506
|
/>
|
|
440
507
|
</el-radio-group>
|
|
441
|
-
|
|
508
|
+
<!-- 脚本模式: 自定义函数插入新建, 脚本测试, 脚本复制 -->
|
|
509
|
+
<div
|
|
510
|
+
class="editor-tools"
|
|
442
511
|
v-show="factorType === '脚本'"
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
512
|
+
>
|
|
513
|
+
<st-customFunction
|
|
514
|
+
v-show="factorType === '脚本'"
|
|
515
|
+
size="small"
|
|
516
|
+
@insert="handleInsertCustomFunction"
|
|
517
|
+
/>
|
|
518
|
+
<el-button
|
|
519
|
+
type="primary"
|
|
520
|
+
size="small"
|
|
521
|
+
:loading="scriptCopyLoading"
|
|
522
|
+
@click="handleScriptCopy"
|
|
523
|
+
>复制</el-button
|
|
524
|
+
>
|
|
525
|
+
<el-button
|
|
526
|
+
type="primary"
|
|
527
|
+
size="small"
|
|
528
|
+
:loading="scriptTestLoading"
|
|
529
|
+
@click="handleScriptTest"
|
|
530
|
+
>测试</el-button
|
|
531
|
+
>
|
|
532
|
+
<el-button
|
|
533
|
+
size="small"
|
|
534
|
+
:icon="Document"
|
|
535
|
+
@click="handleScriptLog"
|
|
536
|
+
>日志明细</el-button
|
|
537
|
+
>
|
|
538
|
+
</div>
|
|
446
539
|
</div>
|
|
447
540
|
<!-- 变量选择器 + 关闭 -->
|
|
448
541
|
<div class="right">
|
|
@@ -719,6 +812,57 @@ watch(
|
|
|
719
812
|
:factorType="factorType"
|
|
720
813
|
:data="config.factorDescriptions?.filter((item) => [1, 3].includes(item.type))"
|
|
721
814
|
/>
|
|
815
|
+
<!-- 窗口: 日志明细 -->
|
|
816
|
+
<el-dialog
|
|
817
|
+
modal-class="log-dialog"
|
|
818
|
+
v-model="scriptTestLogVisible"
|
|
819
|
+
width="830"
|
|
820
|
+
align-center
|
|
821
|
+
append-to-body
|
|
822
|
+
draggable
|
|
823
|
+
overflow
|
|
824
|
+
:modal="false"
|
|
825
|
+
:modal-penetrable="true"
|
|
826
|
+
:show-close="false"
|
|
827
|
+
>
|
|
828
|
+
<template #header="{ titleId, titleClass }">
|
|
829
|
+
<div class="custom-header">
|
|
830
|
+
<div class="left">
|
|
831
|
+
<span
|
|
832
|
+
:id="titleId"
|
|
833
|
+
:class="titleClass"
|
|
834
|
+
>
|
|
835
|
+
日志明细
|
|
836
|
+
</span>
|
|
837
|
+
</div>
|
|
838
|
+
<!-- 关闭 -->
|
|
839
|
+
<div class="right">
|
|
840
|
+
<el-icon @click="scriptTestLogVisible = false"><Close /></el-icon>
|
|
841
|
+
</div>
|
|
842
|
+
</div>
|
|
843
|
+
</template>
|
|
844
|
+
<div class="content">
|
|
845
|
+
<!-- 代码 -->
|
|
846
|
+
<el-scrollbar
|
|
847
|
+
class="code"
|
|
848
|
+
height="600px"
|
|
849
|
+
>
|
|
850
|
+
<pre>{{ scriptTestResult.code }}</pre>
|
|
851
|
+
</el-scrollbar>
|
|
852
|
+
<!-- 分割线 -->
|
|
853
|
+
<el-divider direction="vertical" />
|
|
854
|
+
<!-- 日志 -->
|
|
855
|
+
<el-scrollbar height="600px">
|
|
856
|
+
<pre :class="scriptTestResult.result === 1 ? 'success-log' : 'error-log'">{{ scriptTestResult.result === 1 ? "测试通过 √" : scriptTestResult.detail }}</pre>
|
|
857
|
+
</el-scrollbar>
|
|
858
|
+
</div>
|
|
859
|
+
<!-- 底部 -->
|
|
860
|
+
<template #footer>
|
|
861
|
+
<div class="dialog-footer">
|
|
862
|
+
<el-button @click="scriptTestLogVisible = false"> 关闭 </el-button>
|
|
863
|
+
</div>
|
|
864
|
+
</template>
|
|
865
|
+
</el-dialog>
|
|
722
866
|
<!-- 变量选择器 -->
|
|
723
867
|
<st-varSelectDialog ref="stVarSelectDialogRef" />
|
|
724
868
|
</template>
|
|
@@ -738,6 +882,14 @@ watch(
|
|
|
738
882
|
align-items: center;
|
|
739
883
|
gap: 10px;
|
|
740
884
|
}
|
|
885
|
+
.editor-tools {
|
|
886
|
+
display: flex;
|
|
887
|
+
align-items: center;
|
|
888
|
+
gap: 10px;
|
|
889
|
+
.el-button {
|
|
890
|
+
margin: 0;
|
|
891
|
+
}
|
|
892
|
+
}
|
|
741
893
|
.el-icon {
|
|
742
894
|
cursor: pointer;
|
|
743
895
|
}
|
|
@@ -760,4 +912,49 @@ watch(
|
|
|
760
912
|
}
|
|
761
913
|
}
|
|
762
914
|
}
|
|
915
|
+
.log-dialog {
|
|
916
|
+
.custom-header {
|
|
917
|
+
display: flex;
|
|
918
|
+
align-items: center;
|
|
919
|
+
justify-content: space-between;
|
|
920
|
+
.left,
|
|
921
|
+
.right {
|
|
922
|
+
display: flex;
|
|
923
|
+
align-items: center;
|
|
924
|
+
gap: 10px;
|
|
925
|
+
}
|
|
926
|
+
.el-icon {
|
|
927
|
+
cursor: pointer;
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
.content {
|
|
931
|
+
display: flex;
|
|
932
|
+
background-color: var(--el-color-black);
|
|
933
|
+
.el-scrollbar {
|
|
934
|
+
flex: 1;
|
|
935
|
+
box-sizing: border-box;
|
|
936
|
+
padding: 8px;
|
|
937
|
+
}
|
|
938
|
+
.el-divider {
|
|
939
|
+
margin: 0;
|
|
940
|
+
height: 616px;
|
|
941
|
+
}
|
|
942
|
+
.code {
|
|
943
|
+
color: var(--el-color-info);
|
|
944
|
+
}
|
|
945
|
+
.success-log {
|
|
946
|
+
color: var(--el-color-success);
|
|
947
|
+
}
|
|
948
|
+
.error-log {
|
|
949
|
+
color: var(--el-color-danger);
|
|
950
|
+
}
|
|
951
|
+
pre {
|
|
952
|
+
margin: 0;
|
|
953
|
+
line-height: 1.5;
|
|
954
|
+
white-space: pre-wrap;
|
|
955
|
+
word-break: break-all;
|
|
956
|
+
word-wrap: break-word;
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
}
|
|
763
960
|
</style>
|