st-comp 0.0.244 → 0.0.246
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/ConfigProvider.cjs +1 -1
- package/es/ConfigProvider.js +1 -1
- package/es/CustomFunction.cjs +2 -2
- package/es/CustomFunction.js +262 -263
- package/es/FactorWarning.cjs +1 -1
- package/es/FactorWarning.js +1 -1
- package/es/Kline.cjs +1 -1
- package/es/Kline.js +1 -1
- package/es/KlineBasic.cjs +1 -1
- package/es/KlineBasic.js +574 -606
- package/es/KlineNew.cjs +1 -1
- package/es/KlineNew.js +1 -1
- package/es/KlinePlus.cjs +1 -1
- package/es/KlinePlus.js +1 -1
- package/es/MonacoEditor.cjs +1 -1
- package/es/MonacoEditor.js +3 -3
- package/es/Pie.cjs +1 -1
- package/es/Pie.js +1 -1
- package/es/User.cjs +1 -1
- package/es/User.js +1 -1
- package/es/VarSelectDialog.cjs +1 -1
- package/es/VarSelectDialog.js +2 -2
- package/es/VarietyAutoComplete.cjs +1 -1
- package/es/VarietyAutoComplete.js +1 -1
- package/es/VarietySearch.cjs +20 -20
- package/es/VarietySearch.js +2995 -3000
- package/es/{VarietySelect-031bf077.cjs → VarietySelect-2fd501da.cjs} +1 -1
- package/es/{VarietySelect-ae0c48b2.js → VarietySelect-5a9dd50b.js} +1 -1
- package/es/{index-1f939868.cjs → index-2375023e.cjs} +2 -2
- package/es/{index-edabe380.js → index-7ed0999e.js} +5487 -5574
- package/es/{index-2c456130.cjs → index-8901a38c.cjs} +40 -40
- package/es/{index-4b01552e.js → index-ac98a4d8.js} +3 -3
- package/es/{python-7ce6f0b1.js → python-a914569a.js} +3 -3
- package/es/{python-c8abd4f5.cjs → python-c67c8901.cjs} +1 -1
- package/es/style.css +1 -1
- package/lib/bundle.js +1 -1
- package/lib/bundle.umd.cjs +223 -223
- package/lib/{index-200db55b.js → index-2a325d42.js} +34655 -34779
- package/lib/{python-9540022d.js → python-eb65d93b.js} +1 -1
- package/lib/style.css +1 -1
- package/package.json +1 -1
- package/packages/CustomFunction/index.vue +2 -4
- package/packages/KlineBasic/index.vue +518 -497
- package/packages/VarietySearch/components/CompositeOrder/index.vue +2 -4
- package/packages/VarietySearch/components/FactorScreen/index.vue +5 -7
- package/packages/VarietySearch/index.vue +4 -6
- package/src/pages/KlineBasic/api.js +7 -4
- package/src/pages/KlineBasic/index.vue +346 -56
- package/src/pages/VarietySearch/index.vue +7 -2
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { actionStat } from "st-func";
|
|
3
2
|
import { Close, Plus } from "@element-plus/icons-vue";
|
|
4
3
|
import { ref, watch, computed, inject } from "vue";
|
|
5
4
|
|
|
6
5
|
const clearRow = inject("clearRow");
|
|
7
6
|
|
|
8
7
|
const data = defineModel("data", { default: [] });
|
|
8
|
+
const emit = defineEmits(["actionState"]);
|
|
9
9
|
const props = defineProps({
|
|
10
10
|
config: { type: Object, default: () => {} },
|
|
11
11
|
varietyMarket: { type: null || Number, default: () => null }, // 已选品种市场
|
|
12
12
|
commonOption: { type: Array, default: () => [] }, // 已选常用选项
|
|
13
|
-
pageName: { type: String, default: "" },
|
|
14
13
|
});
|
|
15
14
|
const visible = ref(false);
|
|
16
15
|
const compositeOrderForm = ref({
|
|
@@ -60,8 +59,7 @@ const handleAction = (action, index) => {
|
|
|
60
59
|
}
|
|
61
60
|
// 窗口确认
|
|
62
61
|
case "submit": {
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
emit("actionState", "组合排序");
|
|
65
63
|
const { id, name, value } = compositeOrderForm.value;
|
|
66
64
|
if (!name) return ElMessage.warning("请选择需要排序的条件");
|
|
67
65
|
const { label } = compositeOrderOptions.value.find((item) => item.key === name);
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
<!-- 因子筛选组件 -->
|
|
2
2
|
<script setup name="FactorScreen">
|
|
3
|
-
import { actionStat } from "st-func";
|
|
4
3
|
import { nextTick, ref, watch, inject, reactive } from "vue";
|
|
5
4
|
import { Close, Plus, CircleCloseFilled, InfoFilled, Document } from "@element-plus/icons-vue";
|
|
6
5
|
import { handleVerifyScore, extractConditionDetails, extractVariables, sendToAi } from "./tools.js";
|
|
@@ -9,6 +8,7 @@ import MonacoEditor from "../../../MonacoEditor/index.vue";
|
|
|
9
8
|
|
|
10
9
|
const { request } = inject("stConfig"); // 组件库全局配置
|
|
11
10
|
|
|
11
|
+
const emit = defineEmits(["actionState"]);
|
|
12
12
|
const props = defineProps({
|
|
13
13
|
config: {
|
|
14
14
|
type: Object,
|
|
@@ -21,7 +21,6 @@ const props = defineProps({
|
|
|
21
21
|
factorDescriptions: [], // 因子使用说明数据源
|
|
22
22
|
},
|
|
23
23
|
},
|
|
24
|
-
pageName: { type: String, default: "" },
|
|
25
24
|
});
|
|
26
25
|
const data = defineModel("data", {
|
|
27
26
|
default: {
|
|
@@ -324,7 +323,7 @@ const handleScriptCopy = async () => {
|
|
|
324
323
|
ElMessage.success("脚本内容已经成功复制到粘贴板");
|
|
325
324
|
} finally {
|
|
326
325
|
scriptCopyLoading.value = false;
|
|
327
|
-
|
|
326
|
+
emit("actionState", "因子筛选", "复制");
|
|
328
327
|
}
|
|
329
328
|
};
|
|
330
329
|
|
|
@@ -376,7 +375,7 @@ const handleScriptTest = async (action) => {
|
|
|
376
375
|
}
|
|
377
376
|
} finally {
|
|
378
377
|
scriptTestLoading.value = false;
|
|
379
|
-
|
|
378
|
+
emit("actionState", "因子筛选", "测试");
|
|
380
379
|
}
|
|
381
380
|
break;
|
|
382
381
|
}
|
|
@@ -391,7 +390,7 @@ const handleScriptTest = async (action) => {
|
|
|
391
390
|
};
|
|
392
391
|
// 测试: AI分析
|
|
393
392
|
const handleTestAi = () => {
|
|
394
|
-
|
|
393
|
+
emit("actionState", "因子筛选", "AI分析");
|
|
395
394
|
const appId = "87be17ecc84d4d2ea3108d7155bec2ac";
|
|
396
395
|
const apiKey = "sk-d995eb26a4334bdeb2ccb4cbfaf51de8";
|
|
397
396
|
scriptAILoading.value = true;
|
|
@@ -402,7 +401,6 @@ const handleTestAi = () => {
|
|
|
402
401
|
return;
|
|
403
402
|
}
|
|
404
403
|
scriptTestResult.ai = scriptTestResult.ai + res;
|
|
405
|
-
console.log(scriptTestResult.ai);
|
|
406
404
|
});
|
|
407
405
|
};
|
|
408
406
|
|
|
@@ -574,7 +572,7 @@ watch(
|
|
|
574
572
|
v-show="factorType === '脚本'"
|
|
575
573
|
size="small"
|
|
576
574
|
@insert="handleInsertCustomFunction"
|
|
577
|
-
|
|
575
|
+
@actionState="(...args) => emit('actionState', ...args)"
|
|
578
576
|
/>
|
|
579
577
|
<el-button
|
|
580
578
|
type="primary"
|
|
@@ -6,10 +6,8 @@ import CommonIndicator from "./components/CommonIndicator/index.vue";
|
|
|
6
6
|
import CompositeOrder from "./components/CompositeOrder/index.vue";
|
|
7
7
|
import AddTag from "./components/AddTag/index.vue";
|
|
8
8
|
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
pageName: { type: String, default: "" },
|
|
12
|
-
});
|
|
9
|
+
const emit = defineEmits(["actionState"]);
|
|
10
|
+
const props = defineProps({ config: { type: Object, default: {} } });
|
|
13
11
|
const searchData = defineModel("searchData");
|
|
14
12
|
searchData.value = Object.assign(searchData.value, {
|
|
15
13
|
// 品种市场
|
|
@@ -600,7 +598,7 @@ defineExpose({
|
|
|
600
598
|
<FactorScreen
|
|
601
599
|
v-model:data="searchData.factorScreen"
|
|
602
600
|
:config="config.factorScreen"
|
|
603
|
-
|
|
601
|
+
@actionState="(...args) => emit('actionState', ...args)"
|
|
604
602
|
/>
|
|
605
603
|
</div>
|
|
606
604
|
</template>
|
|
@@ -617,7 +615,7 @@ defineExpose({
|
|
|
617
615
|
:varietyMarket="searchData.varietyMarket"
|
|
618
616
|
:commonOption="searchData.commonOption"
|
|
619
617
|
:config="config.compositeOrder"
|
|
620
|
-
|
|
618
|
+
@actionState="(...args) => emit('actionState', ...args)"
|
|
621
619
|
/>
|
|
622
620
|
</div>
|
|
623
621
|
</template>
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import axios from "axios";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
const
|
|
3
|
+
// 测试环境
|
|
4
|
+
// const token = "dc4eb64816effa53ccee0de7a02e777b";
|
|
5
|
+
// export const host = "http://192.168.12.38:5173";
|
|
6
|
+
|
|
7
|
+
// 线上环境
|
|
8
|
+
const token = "10831ed6ce9ff2652a732f63c5d79c5c";
|
|
9
|
+
export const host = "//investapi.hzyotoy.com";
|
|
5
10
|
|
|
6
11
|
// 获取指标线配置
|
|
7
12
|
export const getIndicator = async () => {
|
|
@@ -21,7 +26,6 @@ export const getConfig = async () => {
|
|
|
21
26
|
});
|
|
22
27
|
return res.data;
|
|
23
28
|
}
|
|
24
|
-
|
|
25
29
|
// 设置配置
|
|
26
30
|
export const setConfig = async (data) => {
|
|
27
31
|
const res = await axios({
|
|
@@ -32,7 +36,6 @@ export const setConfig = async (data) => {
|
|
|
32
36
|
});
|
|
33
37
|
return res.data;
|
|
34
38
|
}
|
|
35
|
-
|
|
36
39
|
// 获取周期列表
|
|
37
40
|
export const getCycleList = async () => {
|
|
38
41
|
const res = await axios({
|
|
@@ -1,76 +1,366 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div style="width: 100%;height: 100%;">
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
<el-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
2
|
+
<div style="width: 100%;height: 100%; display: flex; flex-direction: column;">
|
|
3
|
+
<!-- 工具栏 -->
|
|
4
|
+
<div style="height: 42px; display: flex; align-items: center; gap: 12px; flex-wrap: wrap; padding: 0 12px; flex-shrink: 0;">
|
|
5
|
+
<el-radio-group v-model="displayMode" size="small" @change="handleModeChange">
|
|
6
|
+
<el-radio-button value="single">单周期</el-radio-button>
|
|
7
|
+
<el-radio-button value="multi">多周期</el-radio-button>
|
|
8
|
+
</el-radio-group>
|
|
9
|
+
|
|
10
|
+
<el-divider direction="vertical" />
|
|
11
|
+
|
|
12
|
+
<!-- 单周期模式下的配置 -->
|
|
13
|
+
<template v-if="displayMode === 'single'">
|
|
14
|
+
<el-input
|
|
15
|
+
v-model="singleConfig.variety"
|
|
16
|
+
placeholder="品种代码"
|
|
17
|
+
size="small"
|
|
18
|
+
style="width: 120px;"
|
|
14
19
|
/>
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
:label="item.label"
|
|
21
|
-
:value="item.value"
|
|
20
|
+
<el-input
|
|
21
|
+
v-model="singleConfig.varietyName"
|
|
22
|
+
placeholder="品种名称"
|
|
23
|
+
size="small"
|
|
24
|
+
style="width: 120px;"
|
|
22
25
|
/>
|
|
23
|
-
|
|
26
|
+
<el-input
|
|
27
|
+
v-model="singleConfig.featureId"
|
|
28
|
+
placeholder="合约ID"
|
|
29
|
+
size="small"
|
|
30
|
+
style="width: 120px;"
|
|
31
|
+
/>
|
|
32
|
+
<el-input
|
|
33
|
+
v-model="singleConfig.featureType"
|
|
34
|
+
placeholder="合约类型"
|
|
35
|
+
size="small"
|
|
36
|
+
style="width: 120px;"
|
|
37
|
+
/>
|
|
38
|
+
<el-select
|
|
39
|
+
v-model="singleConfig.cycle"
|
|
40
|
+
placeholder="周期"
|
|
41
|
+
size="small"
|
|
42
|
+
style="width: 120px;"
|
|
43
|
+
>
|
|
44
|
+
<el-option
|
|
45
|
+
v-for="item in cycleOptions"
|
|
46
|
+
:key="item.value"
|
|
47
|
+
:label="item.label"
|
|
48
|
+
:value="item.value"
|
|
49
|
+
/>
|
|
50
|
+
</el-select>
|
|
51
|
+
<el-select
|
|
52
|
+
v-model="singleConfig.mainIndicator"
|
|
53
|
+
placeholder="主图指标"
|
|
54
|
+
size="small"
|
|
55
|
+
style="width: 120px;"
|
|
56
|
+
>
|
|
57
|
+
<el-option
|
|
58
|
+
v-for="(item, index) in indicatorStore.mainIndicatorList"
|
|
59
|
+
:key="index"
|
|
60
|
+
:label="item.label"
|
|
61
|
+
:value="item.value"
|
|
62
|
+
/>
|
|
63
|
+
</el-select>
|
|
64
|
+
</template>
|
|
65
|
+
|
|
66
|
+
<!-- 多周期模式下的配置(共用基础信息) -->
|
|
67
|
+
<template v-if="displayMode === 'multi'">
|
|
68
|
+
<el-input
|
|
69
|
+
v-model="multiBaseConfig.variety"
|
|
70
|
+
placeholder="品种代码"
|
|
71
|
+
size="small"
|
|
72
|
+
style="width: 120px;"
|
|
73
|
+
@change="refreshMultiCharts"
|
|
74
|
+
/>
|
|
75
|
+
<el-input
|
|
76
|
+
v-model="multiBaseConfig.varietyName"
|
|
77
|
+
placeholder="品种名称"
|
|
78
|
+
size="small"
|
|
79
|
+
style="width: 120px;"
|
|
80
|
+
@change="refreshMultiCharts"
|
|
81
|
+
/>
|
|
82
|
+
<el-input
|
|
83
|
+
v-model="multiBaseConfig.featureId"
|
|
84
|
+
placeholder="合约ID"
|
|
85
|
+
size="small"
|
|
86
|
+
style="width: 120px;"
|
|
87
|
+
@change="refreshMultiCharts"
|
|
88
|
+
/>
|
|
89
|
+
<el-input
|
|
90
|
+
v-model="multiBaseConfig.featureType"
|
|
91
|
+
placeholder="合约类型"
|
|
92
|
+
size="small"
|
|
93
|
+
style="width: 120px;"
|
|
94
|
+
@change="refreshMultiCharts"
|
|
95
|
+
/>
|
|
96
|
+
<el-select
|
|
97
|
+
v-model="multiBaseConfig.mainIndicator"
|
|
98
|
+
placeholder="主图指标"
|
|
99
|
+
size="small"
|
|
100
|
+
style="width: 120px;"
|
|
101
|
+
@change="refreshMultiCharts"
|
|
102
|
+
>
|
|
103
|
+
<el-option
|
|
104
|
+
v-for="(item, index) in indicatorStore.mainIndicatorList"
|
|
105
|
+
:key="index"
|
|
106
|
+
:label="item.label"
|
|
107
|
+
:value="item.value"
|
|
108
|
+
/>
|
|
109
|
+
</el-select>
|
|
110
|
+
</template>
|
|
24
111
|
</div>
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
:
|
|
31
|
-
:
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
112
|
+
|
|
113
|
+
<!-- 图表展示区域 -->
|
|
114
|
+
<div
|
|
115
|
+
class="charts-container"
|
|
116
|
+
:style="{
|
|
117
|
+
height: 'calc(100% - 42px)',
|
|
118
|
+
overflow: 'auto'
|
|
119
|
+
}"
|
|
120
|
+
>
|
|
121
|
+
<!-- 单周期模式:单个图表 -->
|
|
122
|
+
<div
|
|
123
|
+
v-if="displayMode === 'single' && show"
|
|
124
|
+
class="single-chart"
|
|
125
|
+
>
|
|
126
|
+
<st-klineBasic
|
|
127
|
+
:key="singleChartKey"
|
|
128
|
+
:variety="singleConfig.variety"
|
|
129
|
+
:varietyName="singleConfig.varietyName"
|
|
130
|
+
:featureId="singleConfig.featureId"
|
|
131
|
+
:featureType="singleConfig.featureType"
|
|
132
|
+
:cycle="singleConfig.cycle"
|
|
133
|
+
:mainIndicator="singleConfig.mainIndicator"
|
|
134
|
+
:indicatorStore="indicatorStore"
|
|
135
|
+
:env="{ VITE_BASE_URL: host }"
|
|
136
|
+
:brushRange="['2025-06-03 00:00:00', '2025-06-05 23:59:59']"
|
|
137
|
+
/>
|
|
138
|
+
</div>
|
|
139
|
+
|
|
140
|
+
<!-- 多周期模式:6个图表网格布局 -->
|
|
141
|
+
<div
|
|
142
|
+
v-if="displayMode === 'multi' && show"
|
|
143
|
+
class="multi-charts-grid"
|
|
144
|
+
>
|
|
145
|
+
<div
|
|
146
|
+
v-for="(chart, index) in multiCharts"
|
|
147
|
+
:key="`${chart.cycle}-${multiBaseConfig.variety}`"
|
|
148
|
+
class="multi-chart-item"
|
|
149
|
+
>
|
|
150
|
+
<div class="multi-chart-header">
|
|
151
|
+
<span class="multi-chart-title">{{ chart.cycleLabel }}</span>
|
|
152
|
+
</div>
|
|
153
|
+
<div class="multi-chart-content">
|
|
154
|
+
<st-klineBasic
|
|
155
|
+
:ref="(el) => setChartRef(el, chart.cycle)"
|
|
156
|
+
:variety="multiBaseConfig.variety"
|
|
157
|
+
:varietyName="multiBaseConfig.varietyName"
|
|
158
|
+
:featureId="multiBaseConfig.featureId"
|
|
159
|
+
:featureType="multiBaseConfig.featureType"
|
|
160
|
+
:cycle="chart.cycle"
|
|
161
|
+
:mainIndicator="multiBaseConfig.mainIndicator"
|
|
162
|
+
:indicatorStore="indicatorStore"
|
|
163
|
+
:env="{ VITE_BASE_URL: host }"
|
|
164
|
+
:brushRange="['2025-06-03 00:00:00', '2025-06-05 23:59:59']"
|
|
165
|
+
/>
|
|
166
|
+
</div>
|
|
167
|
+
</div>
|
|
168
|
+
</div>
|
|
38
169
|
</div>
|
|
39
170
|
</div>
|
|
40
171
|
</template>
|
|
41
172
|
|
|
42
173
|
<script setup>
|
|
43
|
-
import { ref, onMounted } from 'vue';
|
|
174
|
+
import { ref, reactive, computed, onMounted, watch } from 'vue';
|
|
44
175
|
import useIndicatorStore from './indicator';
|
|
45
|
-
import { getCycleList } from './api';
|
|
46
|
-
|
|
47
|
-
const freqOptions = ['1m', '5m', '15m', '30m', '60m', '1d', '1w', '1mon']
|
|
176
|
+
import { getCycleList, host } from './api';
|
|
48
177
|
|
|
49
178
|
const indicatorStore = useIndicatorStore();
|
|
50
179
|
|
|
51
|
-
|
|
52
|
-
const
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
180
|
+
// 显示模式
|
|
181
|
+
const displayMode = ref('single'); // single: 单周期, multi: 多周期
|
|
182
|
+
const show = ref(false);
|
|
183
|
+
|
|
184
|
+
// 周期映射
|
|
185
|
+
const cycleMap = {
|
|
186
|
+
'15m': { value: '1', label: '15分钟' },
|
|
187
|
+
'30m': { value: '2', label: '30分钟' },
|
|
188
|
+
'60m': { value: '3', label: '60分钟' },
|
|
189
|
+
'1d': { value: '6', label: '日线' },
|
|
190
|
+
'1w': { value: '7', label: '周线' },
|
|
191
|
+
'1mon': { value: '8', label: '月线' }
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
// 多周期展示的周期列表
|
|
195
|
+
const multiCycleList = [
|
|
196
|
+
{ cycle: '1', cycleLabel: '15分钟' }, // 15m
|
|
197
|
+
{ cycle: '2', cycleLabel: '30分钟' }, // 30m
|
|
198
|
+
{ cycle: '3', cycleLabel: '60分钟' }, // 60m
|
|
199
|
+
{ cycle: '6', cycleLabel: '日线' }, // 1d
|
|
200
|
+
{ cycle: '7', cycleLabel: '周线' }, // 1w
|
|
201
|
+
{ cycle: '8', cycleLabel: '月线' } // 1mon
|
|
202
|
+
];
|
|
203
|
+
|
|
204
|
+
// 周期选项
|
|
56
205
|
const cycleOptions = ref([]);
|
|
57
|
-
const cycle = ref('');
|
|
58
|
-
const mainIndicator = ref('DKX_EMA')
|
|
59
|
-
const config = ref({
|
|
60
|
-
defaultShowCounts: 500, // 默认展示条数
|
|
61
|
-
maxShowCounts: 5000, // 单页最大展示条数
|
|
62
|
-
showSubChart: true, // 是否展示副图
|
|
63
|
-
})
|
|
64
206
|
|
|
207
|
+
// 单周期配置
|
|
208
|
+
const singleConfig = reactive({
|
|
209
|
+
variety: '000001',
|
|
210
|
+
varietyName: '平安银行',
|
|
211
|
+
featureId: 88,
|
|
212
|
+
featureType: '3',
|
|
213
|
+
cycle: '',
|
|
214
|
+
mainIndicator: 'DKX_EMA'
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
// 多周期基础配置(共用)
|
|
218
|
+
const multiBaseConfig = reactive({
|
|
219
|
+
variety: '000001',
|
|
220
|
+
varietyName: '平安银行',
|
|
221
|
+
featureId: 88,
|
|
222
|
+
featureType: '3',
|
|
223
|
+
mainIndicator: 'DKX_EMA'
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
// 多周期图表数据
|
|
227
|
+
const multiCharts = ref(multiCycleList);
|
|
228
|
+
|
|
229
|
+
// 存储图表实例引用(用于需要时手动刷新)
|
|
230
|
+
const chartRefs = ref({});
|
|
231
|
+
|
|
232
|
+
// 单图表刷新key
|
|
233
|
+
const singleChartKey = ref(0);
|
|
234
|
+
|
|
235
|
+
// 设置图表引用
|
|
236
|
+
const setChartRef = (el, cycle) => {
|
|
237
|
+
if (el) {
|
|
238
|
+
chartRefs.value[cycle] = el;
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
// 刷新多周期图表
|
|
243
|
+
const refreshMultiCharts = () => {
|
|
244
|
+
// 通过重新生成key来强制刷新
|
|
245
|
+
multiCharts.value = [...multiCycleList];
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
// 模式切换处理
|
|
249
|
+
const handleModeChange = () => {
|
|
250
|
+
// 切换模式时不需要额外操作,Vue会自动重新渲染
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
// 监听单周期配置变化,刷新图表
|
|
254
|
+
watch(
|
|
255
|
+
() => [singleConfig.variety, singleConfig.cycle, singleConfig.mainIndicator],
|
|
256
|
+
() => {
|
|
257
|
+
if (displayMode.value === 'single') {
|
|
258
|
+
singleChartKey.value++;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
// 监听多周期基础配置变化,刷新所有图表
|
|
264
|
+
watch(
|
|
265
|
+
() => [multiBaseConfig.variety, multiBaseConfig.mainIndicator],
|
|
266
|
+
() => {
|
|
267
|
+
if (displayMode.value === 'multi') {
|
|
268
|
+
refreshMultiCharts();
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
);
|
|
272
|
+
|
|
273
|
+
// 初始化
|
|
65
274
|
onMounted(async () => {
|
|
66
|
-
await indicatorStore.init()
|
|
67
|
-
const res = await getCycleList()
|
|
68
|
-
cycleOptions.value = res?.body?.[1002].map(item => ({
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
})
|
|
275
|
+
await indicatorStore.init();
|
|
276
|
+
const res = await getCycleList();
|
|
277
|
+
cycleOptions.value = res?.body?.[1002].map(item => ({
|
|
278
|
+
label: item.dictName,
|
|
279
|
+
value: item.dictCode
|
|
280
|
+
}));
|
|
281
|
+
|
|
282
|
+
// 设置默认周期(取第二个选项,通常是日线)
|
|
283
|
+
if (cycleOptions.value.length > 1) {
|
|
284
|
+
singleConfig.cycle = cycleOptions.value[1].value;
|
|
285
|
+
} else if (cycleOptions.value.length > 0) {
|
|
286
|
+
singleConfig.cycle = cycleOptions.value[0].value;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
show.value = true;
|
|
290
|
+
});
|
|
72
291
|
</script>
|
|
73
292
|
|
|
74
293
|
<style lang="scss" scoped>
|
|
294
|
+
.charts-container {
|
|
295
|
+
flex: 1;
|
|
296
|
+
overflow: auto;
|
|
297
|
+
padding: 12px;
|
|
298
|
+
background: #f5f5f5;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// 单周期模式
|
|
302
|
+
.single-chart {
|
|
303
|
+
width: 100%;
|
|
304
|
+
height: 100%;
|
|
305
|
+
min-height: 600px;
|
|
306
|
+
background: #000;
|
|
307
|
+
border-radius: 4px;
|
|
308
|
+
overflow: hidden;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// 多周期模式 - 网格布局
|
|
312
|
+
.multi-charts-grid {
|
|
313
|
+
display: grid;
|
|
314
|
+
grid-template-columns: repeat(3, 1fr);
|
|
315
|
+
gap: 12px;
|
|
316
|
+
width: 100%;
|
|
317
|
+
}
|
|
75
318
|
|
|
76
|
-
|
|
319
|
+
// 多周期模式 - 6宫格布局
|
|
320
|
+
.multi-charts-grid {
|
|
321
|
+
display: grid;
|
|
322
|
+
grid-template-columns: repeat(3, 1fr); // 3列
|
|
323
|
+
grid-template-rows: repeat(2, 1fr); // 2行,每行占满剩余空间
|
|
324
|
+
gap: 12px;
|
|
325
|
+
width: 100%;
|
|
326
|
+
height: 100%; // 占满父容器高度
|
|
327
|
+
min-height: 0; // 确保grid可以正确收缩
|
|
328
|
+
|
|
329
|
+
.multi-chart-item {
|
|
330
|
+
background: #000;
|
|
331
|
+
border-radius: 4px;
|
|
332
|
+
overflow: hidden;
|
|
333
|
+
display: flex;
|
|
334
|
+
flex-direction: column;
|
|
335
|
+
min-height: 0; // 确保flex子项可以正确收缩
|
|
336
|
+
height: 100%; // 占满grid单元格高度
|
|
337
|
+
|
|
338
|
+
.multi-chart-header {
|
|
339
|
+
height: 32px;
|
|
340
|
+
padding: 0 12px;
|
|
341
|
+
background: #1a1a1a;
|
|
342
|
+
display: flex;
|
|
343
|
+
align-items: center;
|
|
344
|
+
border-bottom: 1px solid #333;
|
|
345
|
+
flex-shrink: 0; // 头部固定高度,不收缩
|
|
346
|
+
|
|
347
|
+
.multi-chart-title {
|
|
348
|
+
font-size: 14px;
|
|
349
|
+
font-weight: 500;
|
|
350
|
+
color: #fff;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
.multi-chart-content {
|
|
355
|
+
flex: 1; // 占满剩余空间
|
|
356
|
+
min-height: 0; // 确保内容区域可以正确收缩
|
|
357
|
+
position: relative;
|
|
358
|
+
|
|
359
|
+
// 确保K线组件占满容器
|
|
360
|
+
:deep(.klineBasic) {
|
|
361
|
+
height: 100%;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
</style>
|
|
@@ -48,7 +48,7 @@ const getTableData = async () => {
|
|
|
48
48
|
* @description: 根据用户最后一次操作交互的时机, 决定排序使用哪个维度
|
|
49
49
|
* 常规排序字段: orderByInfo
|
|
50
50
|
* 表头的orderByInfo和预警组的orderByInfo为顺序互斥, 谁最后操作就用谁
|
|
51
|
-
*
|
|
51
|
+
*
|
|
52
52
|
* 组合排序字段: compositeOrder
|
|
53
53
|
* 表头的orderByInfo与compositeOrder为顺序互斥, 谁最后操作就用谁
|
|
54
54
|
* 预警组的orderByInfo与compositeOrder为强制互斥, compositeOrder有值就一定优先使用compositeOrder
|
|
@@ -105,6 +105,10 @@ const sortChange = ({ column, prop, order }) => {
|
|
|
105
105
|
getTableData();
|
|
106
106
|
};
|
|
107
107
|
|
|
108
|
+
const actionState = (...args) => {
|
|
109
|
+
console.log(...args);
|
|
110
|
+
};
|
|
111
|
+
|
|
108
112
|
onMounted(async () => {
|
|
109
113
|
const dicAlar = await getAlarDict();
|
|
110
114
|
const dicCycle = await getAlarFreq();
|
|
@@ -181,7 +185,7 @@ watch(
|
|
|
181
185
|
},
|
|
182
186
|
{
|
|
183
187
|
deep: true,
|
|
184
|
-
}
|
|
188
|
+
},
|
|
185
189
|
);
|
|
186
190
|
</script>
|
|
187
191
|
|
|
@@ -191,6 +195,7 @@ watch(
|
|
|
191
195
|
ref="varietySearchRef"
|
|
192
196
|
v-model:searchData="varietySearchData"
|
|
193
197
|
:config="varietySearchConfig"
|
|
198
|
+
@actionState="actionState"
|
|
194
199
|
/>
|
|
195
200
|
<div>品种池组件接口参数: {{ apiParams }}</div>
|
|
196
201
|
<el-button
|