st-comp 0.0.159 → 0.0.161
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/components.d.ts +1 -0
- package/es/ChartLayout.js +3 -3
- package/es/Dialog.js +12 -12
- package/es/FactorWarning.cjs +1 -1
- package/es/FactorWarning.js +27 -27
- package/es/Kline.js +16 -16
- package/es/KlineBasic.cjs +1 -1
- package/es/KlineBasic.js +248 -251
- package/es/KlineNew.js +14 -14
- package/es/MonacoEditor.cjs +1 -1
- package/es/MonacoEditor.js +7 -2
- package/es/Pagination.cjs +1 -1
- package/es/Pagination.js +18 -18
- package/es/PasswordPrompt.js +3 -3
- package/es/Table.cjs +1 -1
- package/es/Table.js +196 -347
- package/es/User.cjs +1 -1
- package/es/User.js +21 -21
- package/es/VarietySearch.cjs +3 -1
- package/es/VarietySearch.js +4265 -1071
- package/es/VirtualTable.js +12 -12
- package/es/_commonjsHelpers-10dfc225.js +8 -0
- package/es/_commonjsHelpers-87b0abe8.cjs +1 -0
- package/es/{_initCloneObject-e3d8a9ab.js → _initCloneObject-7f4a9bd7.js} +3 -3
- package/es/{base-19787dfb.js → base-113d028b.js} +7 -7
- package/es/{castArray-8405000b.js → castArray-2b3f27ef.js} +1 -1
- package/es/{config-provider-0f6672af.js → config-provider-3ffe8f8f.js} +3 -3
- package/es/{debounce-6cb0781f.js → debounce-3517a4c7.js} +1 -1
- package/es/{dropdown-17b3ef6a.js → dropdown-ee1240ff.js} +4 -4
- package/es/{el-button-0bf1d532.js → el-button-de89fb60.js} +4 -4
- package/es/{el-checkbox-group-d53bc316.js → el-checkbox-group-17e4156a.js} +2 -2
- package/es/{el-empty-bd5343a7.js → el-empty-546e4106.js} +2 -2
- package/es/{el-form-item-05c0e335.js → el-form-item-73ecd9af.js} +8 -8
- package/es/{el-input-1e309239.js → el-input-c715d419.js} +9 -8
- package/es/{el-input-6a3805c5.cjs → el-input-cb340042.cjs} +1 -1
- package/es/{el-input-number-60ebc58f.js → el-input-number-02db11f6.js} +13 -13
- package/es/{el-input-number-96ff2e47.cjs → el-input-number-0f194f3f.cjs} +1 -1
- package/es/{el-menu-item-6c6236a1.js → el-menu-item-67fac653.js} +8 -8
- package/es/{el-message-7d927756.js → el-message-2eae949c.js} +7 -7
- package/es/{el-overlay-26bf0945.js → el-overlay-f94c4f3b.js} +8 -8
- package/es/{el-popover-17e2e66c.js → el-popconfirm-029f2c00.js} +12 -12
- package/es/{el-popover-7bd8a7c3.cjs → el-popconfirm-86503f8a.cjs} +1 -1
- package/es/{el-popper-b6527ae2.js → el-popper-b34ec18f.js} +9 -9
- package/es/{el-scrollbar-29bcab5f.js → el-scrollbar-c463eaff.js} +7 -7
- package/es/{el-select-7395562b.js → el-select-b77506ca.js} +13 -13
- package/es/{el-table-column-47d80736.js → el-table-column-4aea6b31.js} +12 -12
- package/es/{el-tag-7414e0c7.js → el-tag-1cf8487e.js} +3 -3
- package/es/index-2da94fd7.js +159 -0
- package/es/{index-273822d1.js → index-440d64f2.js} +7 -7
- package/es/{index-75cce588.js → index-496e80be.js} +2 -2
- package/es/index-58521b9e.cjs +1 -0
- package/es/{index-621b092b.js → index-7125c109.js} +1 -1
- package/es/{index-dc22ffe4.js → index-a777a57a.js} +2 -2
- package/es/{index-72151b24.js → index-dd5d4ae9.js} +6 -6
- package/es/{index-c066fe0d.js → index-f393f2d4.js} +3 -3
- package/es/{index-70372cdb.js → index-f905d74d.js} +1 -1
- package/es/{index-ad9f40cd.cjs → index.vue_vue_type_script_setup_true_lang-4024853c.cjs} +3 -3
- package/es/{index-015c420d.js → index.vue_vue_type_script_setup_true_lang-745718ff.js} +5 -9
- package/es/{python-81655341.cjs → python-6a3f6816.cjs} +2 -2
- package/es/{python-be1bd6d2.js → python-7fcad568.js} +1 -1
- package/es/{raf-a532c514.js → raf-5d53429d.js} +1 -1
- package/es/{scroll-d787d648.js → scroll-9ec370f4.js} +1 -1
- package/es/style.css +1 -1
- package/es/{use-form-common-props-5ff2f51b.js → use-form-common-props-d20ca09c.js} +8 -8
- package/es/{vnode-6a0c7411.js → vnode-2d8e2f0e.js} +1 -1
- package/es/{zh-cn-f37255ae.js → zh-cn-4d2bbda7.js} +2 -2
- package/lib/bundle.js +1 -1
- package/lib/bundle.umd.cjs +222 -220
- package/lib/{index-819ef426.js → index-c0cfb828.js} +45519 -42330
- package/lib/{python-4c5a7f20.js → python-4a34bda1.js} +1 -1
- package/lib/style.css +1 -1
- package/package.json +2 -1
- package/packages/VarietySearch/components/CommonIndicator/index.vue +98 -54
- package/packages/VarietySearch/components/FactorScreen/ScriptSelect.vue +300 -0
- package/packages/VarietySearch/components/FactorScreen/VarietySelect.vue +78 -0
- package/packages/VarietySearch/components/FactorScreen/index.vue +123 -21
- package/packages/VarietySearch/config.js +49 -0
- package/packages/VarietySearch/index.vue +24 -13
- package/src/pages/VarietySearch/api.js +70 -0
- package/src/pages/VarietySearch/index.vue +83 -109
- package/vitePlugins/createExportFile.ts +0 -101
- package/vitePlugins/testRelese.ts +0 -67
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "st-comp",
|
|
3
3
|
"public": true,
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.161",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"dev": "vite",
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"dayjs": "^1.11.10",
|
|
19
19
|
"echarts": "^5.4.3",
|
|
20
20
|
"element-plus": "^2.9.4",
|
|
21
|
+
"interactjs": "^1.10.27",
|
|
21
22
|
"monaco-editor": "0.47.0",
|
|
22
23
|
"pinia": "^2.1.6",
|
|
23
24
|
"st-func": "^0.0.59",
|
|
@@ -3,12 +3,18 @@
|
|
|
3
3
|
import { ref, watch, computed } from "vue";
|
|
4
4
|
|
|
5
5
|
const perVolumnRadioOptions = [
|
|
6
|
-
{ label:
|
|
7
|
-
{ label:
|
|
8
|
-
{ label:
|
|
9
|
-
{ label:
|
|
10
|
-
{ label:
|
|
11
|
-
]
|
|
6
|
+
{ label: "近2周", value: "1" },
|
|
7
|
+
{ label: "近1个月", value: "2" },
|
|
8
|
+
{ label: "近3个月", value: "3" },
|
|
9
|
+
{ label: "近6个月", value: "4" },
|
|
10
|
+
{ label: "近1年", value: "5" },
|
|
11
|
+
];
|
|
12
|
+
const auditOpinionTypeRadioOptions = [
|
|
13
|
+
{ label: "无保留意见", value: 1 },
|
|
14
|
+
{ label: "保留意见", value: 2 },
|
|
15
|
+
{ label: "否定意见", value: 3 },
|
|
16
|
+
{ label: "无法表示意见", value: 4 },
|
|
17
|
+
];
|
|
12
18
|
|
|
13
19
|
const data = defineModel("data", { default: [] });
|
|
14
20
|
const props = defineProps({
|
|
@@ -18,8 +24,8 @@ const props = defineProps({
|
|
|
18
24
|
});
|
|
19
25
|
const visible = ref(false);
|
|
20
26
|
const rankKey = computed(() => {
|
|
21
|
-
return props.data.find(i => i.radioType ===
|
|
22
|
-
})
|
|
27
|
+
return props.data.find((i) => i.radioType === "1")?.key;
|
|
28
|
+
});
|
|
23
29
|
|
|
24
30
|
// 常用指标项数据源 [受到: 品种市场, 常用选项影响]
|
|
25
31
|
const commonIndicatorOptions = computed(() => {
|
|
@@ -106,19 +112,24 @@ const clickIndicator = (item) => {
|
|
|
106
112
|
case "mainFlow": {
|
|
107
113
|
indicatorValue.value = {
|
|
108
114
|
...baseParams,
|
|
109
|
-
radioType:
|
|
115
|
+
radioType: "0",
|
|
110
116
|
rankRange: [null, null],
|
|
111
117
|
};
|
|
112
118
|
break;
|
|
113
119
|
}
|
|
120
|
+
// 年报审计意见
|
|
121
|
+
case "auditOpinionType": {
|
|
122
|
+
indicatorValue.value = { ...baseParams, enumType: null };
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
114
125
|
// 其它的通用处理
|
|
115
126
|
default: {
|
|
116
127
|
indicatorValue.value = {
|
|
117
128
|
...baseParams,
|
|
118
129
|
range: [null, null],
|
|
119
130
|
unit: item.defaultUnit.length ? [...item.defaultUnit] : [null, null],
|
|
120
|
-
radioType: rankKey.value && rankKey.value !== item.key ?
|
|
121
|
-
rankRange: item.defaultRankRange || [null, null]
|
|
131
|
+
radioType: rankKey.value && rankKey.value !== item.key ? "0" : item.defaultRadioType, // 0数值 1排名
|
|
132
|
+
rankRange: item.defaultRankRange || [null, null], // 默认排名
|
|
122
133
|
};
|
|
123
134
|
}
|
|
124
135
|
}
|
|
@@ -182,68 +193,69 @@ const submitDialog = () => {
|
|
|
182
193
|
if (!radio) return ElMessage.warning("格式错误: 请选择时间");
|
|
183
194
|
if (!levels?.length) return ElMessage.warning("格式错误: 请选择分位");
|
|
184
195
|
// 格式化文案
|
|
185
|
-
indicatorValue.value.tagText = `${label}: ${
|
|
186
|
-
perVolumnRadioOptions.find(item => item.value === radio)?.label
|
|
187
|
-
}${
|
|
188
|
-
levels.map(i => `${i}分位`).join('、')
|
|
189
|
-
}`;
|
|
196
|
+
indicatorValue.value.tagText = `${label}: ${perVolumnRadioOptions.find((item) => item.value === radio)?.label}${levels.map((i) => `${i}分位`).join("、")}`;
|
|
190
197
|
break;
|
|
191
198
|
}
|
|
192
199
|
// 主力净流入资金
|
|
193
200
|
case "mainFlow": {
|
|
194
201
|
const { label, radioType, radio, rankRange } = indicatorValue.value;
|
|
195
202
|
const checkNumber = (val) => {
|
|
196
|
-
if (val ===
|
|
197
|
-
const num = Number(val)
|
|
203
|
+
if (val === "" || val === null || val === undefined) return false;
|
|
204
|
+
const num = Number(val);
|
|
198
205
|
if (isNaN(num)) return false;
|
|
199
|
-
return true
|
|
200
|
-
}
|
|
206
|
+
return true;
|
|
207
|
+
};
|
|
201
208
|
// 校验
|
|
202
209
|
if (!radio) return ElMessage.warning("格式错误: 请选择时间");
|
|
203
210
|
if (!checkNumber(rankRange[0]) && !checkNumber(rankRange[1])) {
|
|
204
|
-
return ElMessage.warning(`格式错误: 请填写${radioType ===
|
|
211
|
+
return ElMessage.warning(`格式错误: 请填写${radioType === "0" ? "涨幅范围" : "排名范围"}`);
|
|
205
212
|
}
|
|
206
213
|
// 格式化文案
|
|
207
214
|
if (!["", null].includes(rankRange[0]) && !["", null].includes(rankRange[1])) {
|
|
208
|
-
indicatorValue.value.tagText = `${label}: ${radio}日${
|
|
209
|
-
radioType ===
|
|
210
|
-
}
|
|
215
|
+
indicatorValue.value.tagText = `${label}: ${radio}日${radioType === "0" ? "涨幅范围" : "排名范围"}: ${rankRange[0]}${radioType === "0" ? "%" : ""} ~ ${rankRange[1]}${
|
|
216
|
+
radioType === "0" ? "%" : ""
|
|
217
|
+
}`;
|
|
211
218
|
} else if (!["", null].includes(rankRange[0])) {
|
|
212
|
-
indicatorValue.value.tagText = `${label}: ${radio}日${
|
|
213
|
-
radioType === '0' ? '涨幅范围' : '排名范围'
|
|
214
|
-
}: ≥${rankRange[0]}${radioType === '0' ? '%' : ''}`;
|
|
219
|
+
indicatorValue.value.tagText = `${label}: ${radio}日${radioType === "0" ? "涨幅范围" : "排名范围"}: ≥${rankRange[0]}${radioType === "0" ? "%" : ""}`;
|
|
215
220
|
} else {
|
|
216
|
-
indicatorValue.value.tagText = `${label}: ${radio}日${
|
|
217
|
-
radioType === '0' ? '涨幅范围' : '排名范围'
|
|
218
|
-
}: ≤${rankRange[1]}${radioType === '0' ? '%' : ''}`;
|
|
221
|
+
indicatorValue.value.tagText = `${label}: ${radio}日${radioType === "0" ? "涨幅范围" : "排名范围"}: ≤${rankRange[1]}${radioType === "0" ? "%" : ""}`;
|
|
219
222
|
}
|
|
220
223
|
break;
|
|
221
224
|
}
|
|
225
|
+
// 年报审计意见
|
|
226
|
+
case "auditOpinionType": {
|
|
227
|
+
const { label, enumType } = indicatorValue.value;
|
|
228
|
+
// 校验
|
|
229
|
+
if (enumType === null) return ElMessage.warning("格式错误: 请至少选择一个值");
|
|
230
|
+
// 格式化文案
|
|
231
|
+
indicatorValue.value.tagText = `${label}: ${auditOpinionTypeRadioOptions.find((item) => item.value === enumType)?.label}`;
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
222
234
|
// 其它的通用处理
|
|
223
235
|
default: {
|
|
224
236
|
const { label, unit, radioType } = indicatorValue.value;
|
|
225
|
-
const range = radioType ===
|
|
237
|
+
const range = radioType === "1" ? indicatorValue.value.rankRange : indicatorValue.value.range;
|
|
226
238
|
// 校验
|
|
227
239
|
if (["", null].includes(range[0]) && ["", null].includes(range[1])) {
|
|
228
240
|
return ElMessage.warning("格式错误: 请至少填写一个值");
|
|
229
241
|
}
|
|
230
242
|
// 排名校验
|
|
231
|
-
if (radioType ===
|
|
232
|
-
const rangeLeft = Number(range[0])
|
|
233
|
-
const rangeRight = Number(range[1])
|
|
243
|
+
if (radioType === "1") {
|
|
244
|
+
const rangeLeft = Number(range[0]);
|
|
245
|
+
const rangeRight = Number(range[1]);
|
|
234
246
|
if (isNaN(rangeLeft) || isNaN(rangeRight)) return ElMessage.warning("格式错误: 请填写数字");
|
|
235
247
|
if (rangeLeft < 0 || rangeRight < 0) return ElMessage.warning("格式错误: 请填写大于0的数字");
|
|
236
248
|
if (rangeLeft > rangeRight) return ElMessage.warning("格式错误: 请填写正确的排名范围");
|
|
237
249
|
}
|
|
238
|
-
const unitLeft = radioType ===
|
|
239
|
-
const unitRight = radioType ===
|
|
250
|
+
const unitLeft = radioType === "1" ? "" : unit[0] ?? "";
|
|
251
|
+
const unitRight = radioType === "1" ? "" : unit[1] ?? "";
|
|
240
252
|
// 格式化文案
|
|
241
253
|
if (!["", null].includes(range[0]) && !["", null].includes(range[1])) {
|
|
242
|
-
indicatorValue.value.tagText = `${label}${radioType ===
|
|
254
|
+
indicatorValue.value.tagText = `${label}${radioType === "1" ? "排名" : ""}: ${range[0]}${unitLeft} ~ ${range[1]}${unitRight}`;
|
|
243
255
|
} else if (!["", null].includes(range[0])) {
|
|
244
|
-
indicatorValue.value.tagText = `${label}${radioType ===
|
|
256
|
+
indicatorValue.value.tagText = `${label}${radioType === "1" ? "排名" : ""}: ≥${range[0]}${unitLeft}`;
|
|
245
257
|
} else {
|
|
246
|
-
indicatorValue.value.tagText = `${label}${radioType ===
|
|
258
|
+
indicatorValue.value.tagText = `${label}${radioType === "1" ? "排名" : ""}: ≤${range[1]}${unitRight}`;
|
|
247
259
|
}
|
|
248
260
|
}
|
|
249
261
|
}
|
|
@@ -331,7 +343,7 @@ watch(
|
|
|
331
343
|
const changeMainFlowRadioType = () => {
|
|
332
344
|
indicatorValue.value.radio = null;
|
|
333
345
|
indicatorValue.value.rankRange = [null, null];
|
|
334
|
-
}
|
|
346
|
+
};
|
|
335
347
|
</script>
|
|
336
348
|
|
|
337
349
|
<template>
|
|
@@ -380,28 +392,48 @@ const changeMainFlowRadioType = () => {
|
|
|
380
392
|
align-center
|
|
381
393
|
destroy-on-close
|
|
382
394
|
>
|
|
383
|
-
<template
|
|
384
|
-
|
|
395
|
+
<template
|
|
396
|
+
#header
|
|
397
|
+
v-if="nowIndicator.showRankType"
|
|
398
|
+
>
|
|
399
|
+
<span style="font-size: 18px">{{ nowIndicator.label }}</span>
|
|
385
400
|
<el-radio-group
|
|
386
401
|
v-model="indicatorValue.radioType"
|
|
387
|
-
style="vertical-align: 4px; margin-left: 12px
|
|
402
|
+
style="vertical-align: 4px; margin-left: 12px"
|
|
388
403
|
>
|
|
389
|
-
<el-radio-button
|
|
390
|
-
|
|
404
|
+
<el-radio-button
|
|
405
|
+
label="数值"
|
|
406
|
+
value="0"
|
|
407
|
+
/>
|
|
408
|
+
<el-radio-button
|
|
409
|
+
:disabled="rankKey && rankKey !== nowIndicator.key"
|
|
410
|
+
label="排名"
|
|
411
|
+
value="1"
|
|
412
|
+
/>
|
|
391
413
|
</el-radio-group>
|
|
392
414
|
</template>
|
|
393
|
-
<template
|
|
394
|
-
|
|
415
|
+
<template
|
|
416
|
+
#header
|
|
417
|
+
v-else-if="nowIndicator.key === 'mainFlow'"
|
|
418
|
+
>
|
|
419
|
+
<span style="font-size: 18px">{{ nowIndicator.label }}</span>
|
|
395
420
|
<el-radio-group
|
|
396
421
|
v-model="indicatorValue.radioType"
|
|
397
|
-
style="vertical-align: 4px; margin-left: 12px
|
|
422
|
+
style="vertical-align: 4px; margin-left: 12px"
|
|
398
423
|
@change="changeMainFlowRadioType"
|
|
399
424
|
>
|
|
400
|
-
<el-radio-button
|
|
401
|
-
|
|
425
|
+
<el-radio-button
|
|
426
|
+
label="涨幅范围"
|
|
427
|
+
value="0"
|
|
428
|
+
/>
|
|
429
|
+
<el-radio-button
|
|
430
|
+
:disabled="rankKey && rankKey !== nowIndicator.key"
|
|
431
|
+
label="排名范围"
|
|
432
|
+
value="1"
|
|
433
|
+
/>
|
|
402
434
|
</el-radio-group>
|
|
403
435
|
</template>
|
|
404
|
-
|
|
436
|
+
|
|
405
437
|
<template v-if="nowIndicator.type === undefined && indicatorValue.radioType === '1'">
|
|
406
438
|
<!-- 输入框区域 -->
|
|
407
439
|
<div class="out-box">
|
|
@@ -584,7 +616,8 @@ const changeMainFlowRadioType = () => {
|
|
|
584
616
|
v-for="item in perVolumnRadioOptions"
|
|
585
617
|
:key="item.value"
|
|
586
618
|
:value="item.value"
|
|
587
|
-
|
|
619
|
+
>{{ item.label }}</el-radio
|
|
620
|
+
>
|
|
588
621
|
</el-radio-group>
|
|
589
622
|
<el-select
|
|
590
623
|
v-model="indicatorValue.levels"
|
|
@@ -609,8 +642,8 @@ const changeMainFlowRadioType = () => {
|
|
|
609
642
|
<el-radio value="10">10日</el-radio>
|
|
610
643
|
<el-radio value="20">20日</el-radio>
|
|
611
644
|
</el-radio-group>
|
|
612
|
-
<div style="display: flex; align-items: center
|
|
613
|
-
<span>{{ indicatorValue.radioType ===
|
|
645
|
+
<div style="display: flex; align-items: center">
|
|
646
|
+
<span>{{ indicatorValue.radioType === "0" ? "涨幅范围" : "排名范围" }}: </span>
|
|
614
647
|
<el-input
|
|
615
648
|
v-model="indicatorValue.rankRange[0]"
|
|
616
649
|
style="flex: 1"
|
|
@@ -622,6 +655,17 @@ const changeMainFlowRadioType = () => {
|
|
|
622
655
|
/>
|
|
623
656
|
</div>
|
|
624
657
|
</div>
|
|
658
|
+
<!-- 年报审计意见 -->
|
|
659
|
+
<div v-if="nowIndicator.key === 'auditOpinionType'">
|
|
660
|
+
<el-radio-group v-model="indicatorValue.enumType">
|
|
661
|
+
<el-radio
|
|
662
|
+
v-for="(item, index) in auditOpinionTypeRadioOptions"
|
|
663
|
+
:key="index"
|
|
664
|
+
:label="item.label"
|
|
665
|
+
:value="item.value"
|
|
666
|
+
/>
|
|
667
|
+
</el-radio-group>
|
|
668
|
+
</div>
|
|
625
669
|
</template>
|
|
626
670
|
<!-- 确定 -->
|
|
627
671
|
<template #footer>
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import interact from "interactjs";
|
|
3
|
+
import { computed, onMounted, ref, inject } from "vue";
|
|
4
|
+
import { Close, InfoFilled } from "@element-plus/icons-vue";
|
|
5
|
+
import VarietySelect from './VarietySelect.vue'
|
|
6
|
+
|
|
7
|
+
const stConfig = inject("stConfig");
|
|
8
|
+
|
|
9
|
+
const dialogRef = ref(null); // 弹窗主体Ref
|
|
10
|
+
const dialogTop = ref((window.innerHeight - 542) / 2 - 220 > 0 ? (window.innerHeight - 542) / 2 - 220 : 0);
|
|
11
|
+
const dialogRight = ref((window.innerWidth - 1000) / 2 > 0 ? (window.innerWidth - 1000) / 2 : 0);
|
|
12
|
+
|
|
13
|
+
const editorRef = ref(null); // 编辑器Ref
|
|
14
|
+
const visible = ref(false);
|
|
15
|
+
|
|
16
|
+
const varName = ref(null);
|
|
17
|
+
const varList = ref([]);
|
|
18
|
+
const formatList = computed(() => {
|
|
19
|
+
return varList.value.find((item) => item.varName === varName.value)?.formatList ?? [];
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
// 格式化配置项的下拉框数据源
|
|
23
|
+
const handleOptionsStrToArray = (str) => {
|
|
24
|
+
const trimmedStr = str.replace(/^\[|\]$/g, "");
|
|
25
|
+
// 分割字符串为多个数组项
|
|
26
|
+
const items = trimmedStr.split("],[");
|
|
27
|
+
|
|
28
|
+
return items.map((item) => {
|
|
29
|
+
// 移除每个项两端的方括号(如果有)
|
|
30
|
+
const cleanItem = item.replace(/\[|\]/g, "");
|
|
31
|
+
// 分割标签和值
|
|
32
|
+
const [label, value] = cleanItem.split(",");
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
label: label.trim(),
|
|
36
|
+
value: value.trim(),
|
|
37
|
+
};
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
// 插入变量值
|
|
42
|
+
const handleInsetVarContent = (configList) => {
|
|
43
|
+
// 1.校验是否填写完整 + 生成输出值
|
|
44
|
+
const result = [];
|
|
45
|
+
for (let index = 0; index < configList.length; index++) {
|
|
46
|
+
const item = configList[index];
|
|
47
|
+
console.log(item)
|
|
48
|
+
switch (item.vtype) {
|
|
49
|
+
case "text": {
|
|
50
|
+
result.push(item.param);
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
default: {
|
|
54
|
+
if (!item.modelValue) return ElMessage.error("请检查插入格式内是否填写完整");
|
|
55
|
+
result.push(item.suffix ? `${item.modelValue}${item.suffix}` : `${item.modelValue}`);
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// 2.插入内容
|
|
61
|
+
const content = result.join("_");
|
|
62
|
+
|
|
63
|
+
const editorIns = editorRef.value.getInstance();
|
|
64
|
+
const position = editorIns.getPosition();
|
|
65
|
+
|
|
66
|
+
const currentValue = editorRef.value.getValue();
|
|
67
|
+
const lines = currentValue.split("\n");
|
|
68
|
+
// 如果光标位置有效
|
|
69
|
+
if (position.lineNumber <= lines.length) {
|
|
70
|
+
const lineIndex = position.lineNumber - 1;
|
|
71
|
+
const line = lines[lineIndex];
|
|
72
|
+
|
|
73
|
+
// 在光标位置插入内容
|
|
74
|
+
const newLine = line.substring(0, position.column - 1) + content + line.substring(position.column - 1);
|
|
75
|
+
lines[lineIndex] = newLine;
|
|
76
|
+
|
|
77
|
+
// 更新编辑器内容
|
|
78
|
+
const newValue = lines.join("\n");
|
|
79
|
+
editorRef.value.setValue(newValue);
|
|
80
|
+
|
|
81
|
+
// 将光标移动到插入内容之后
|
|
82
|
+
const newColumn = position.column + content.length;
|
|
83
|
+
editorIns.setPosition({
|
|
84
|
+
lineNumber: position.lineNumber,
|
|
85
|
+
column: newColumn,
|
|
86
|
+
});
|
|
87
|
+
editorIns.focus();
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
onMounted(async () => {
|
|
92
|
+
const { body } = await stConfig.request.post('/common/conf/queryAllBackVariables', { useCase: "2" });
|
|
93
|
+
varList.value = body;
|
|
94
|
+
});
|
|
95
|
+
defineExpose({
|
|
96
|
+
open: (editor) => {
|
|
97
|
+
editorRef.value = editor;
|
|
98
|
+
visible.value = true;
|
|
99
|
+
// 支持拖拽
|
|
100
|
+
const dragArea = document.querySelector("body");
|
|
101
|
+
interact(dialogRef.value).draggable({
|
|
102
|
+
allowFrom: ".custom-header", // 只有 .custom-header 元素可以触发拖拽
|
|
103
|
+
// 限制拖拽范围
|
|
104
|
+
modifiers: [
|
|
105
|
+
interact.modifiers.restrictRect({
|
|
106
|
+
restriction: dragArea, // 限制在拖拽区域内
|
|
107
|
+
endOnly: false, // 实时限制
|
|
108
|
+
}),
|
|
109
|
+
],
|
|
110
|
+
listeners: {
|
|
111
|
+
move(event) {
|
|
112
|
+
dialogRight.value -= event.dx;
|
|
113
|
+
dialogTop.value += event.dy;
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
},
|
|
118
|
+
close: () => {
|
|
119
|
+
visible.value = false;
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
</script>
|
|
123
|
+
|
|
124
|
+
<template>
|
|
125
|
+
<div
|
|
126
|
+
v-show="visible"
|
|
127
|
+
class="var-select-dialog"
|
|
128
|
+
ref="dialogRef"
|
|
129
|
+
:style="{ right: `${dialogRight}px`, top: `${dialogTop}px` }"
|
|
130
|
+
>
|
|
131
|
+
<div class="custom-header">
|
|
132
|
+
<div class="left">
|
|
133
|
+
<span> 选择变量 </span>
|
|
134
|
+
<el-select
|
|
135
|
+
v-model="varName"
|
|
136
|
+
placeholder="选择变量"
|
|
137
|
+
filterable
|
|
138
|
+
clearable
|
|
139
|
+
>
|
|
140
|
+
<el-option
|
|
141
|
+
v-for="(item, index) in varList"
|
|
142
|
+
:key="index"
|
|
143
|
+
:label="item.varName"
|
|
144
|
+
:value="item.varName"
|
|
145
|
+
/>
|
|
146
|
+
</el-select>
|
|
147
|
+
</div>
|
|
148
|
+
<div class="right">
|
|
149
|
+
<el-icon
|
|
150
|
+
class="el-icon--left"
|
|
151
|
+
@click="visible = false"
|
|
152
|
+
>
|
|
153
|
+
<Close />
|
|
154
|
+
</el-icon>
|
|
155
|
+
</div>
|
|
156
|
+
</div>
|
|
157
|
+
<div class="custom-body">
|
|
158
|
+
<template v-if="formatList.length">
|
|
159
|
+
<div
|
|
160
|
+
class="format-item"
|
|
161
|
+
v-for="(formatItem, formatIndex) in formatList"
|
|
162
|
+
:key="formatIndex"
|
|
163
|
+
>
|
|
164
|
+
<span>格式{{ formatIndex + 1 }}:</span>
|
|
165
|
+
|
|
166
|
+
<!-- 配置项 -->
|
|
167
|
+
<div class="config-list">
|
|
168
|
+
<template v-for="(config, configIndex) in formatItem.configList">
|
|
169
|
+
<div class="config-item">
|
|
170
|
+
<!-- 类型: 固定值 -->
|
|
171
|
+
<template v-if="config.vtype === 'text'">
|
|
172
|
+
<span>{{ config.param }}</span>
|
|
173
|
+
</template>
|
|
174
|
+
<template v-if="config.vtype === 'inputVariety'">
|
|
175
|
+
<VarietySelect
|
|
176
|
+
size="small"
|
|
177
|
+
:placeholder="config.param"
|
|
178
|
+
:selectClearEnable="false"
|
|
179
|
+
:labelShowEnable="false"
|
|
180
|
+
@select="({ name, code }) => (config.modelValue = code)"
|
|
181
|
+
@change="(value) => (config.modelValue = value)"
|
|
182
|
+
style="width: 100px"
|
|
183
|
+
/>
|
|
184
|
+
</template>
|
|
185
|
+
<template v-if="config.vtype === 'input'">
|
|
186
|
+
<el-input
|
|
187
|
+
v-model="config.modelValue"
|
|
188
|
+
:placeholder="config.param"
|
|
189
|
+
size="small"
|
|
190
|
+
/>
|
|
191
|
+
<span v-if="config.suffix">{{ config.suffix }}</span>
|
|
192
|
+
</template>
|
|
193
|
+
<template v-if="config.vtype === 'select'">
|
|
194
|
+
<el-select
|
|
195
|
+
v-model="config.modelValue"
|
|
196
|
+
:placeholder="config.param"
|
|
197
|
+
clearable
|
|
198
|
+
size="small"
|
|
199
|
+
>
|
|
200
|
+
<el-option
|
|
201
|
+
v-for="item in handleOptionsStrToArray(config.optionsStr)"
|
|
202
|
+
:key="item.value"
|
|
203
|
+
:label="item.label"
|
|
204
|
+
:value="item.value"
|
|
205
|
+
/>
|
|
206
|
+
</el-select>
|
|
207
|
+
</template>
|
|
208
|
+
</div>
|
|
209
|
+
<span v-if="configIndex !== formatItem.configList.length - 1">_</span>
|
|
210
|
+
</template>
|
|
211
|
+
</div>
|
|
212
|
+
<!-- 插入变量 -->
|
|
213
|
+
<el-button
|
|
214
|
+
type="primary"
|
|
215
|
+
plain
|
|
216
|
+
size="small"
|
|
217
|
+
@click="handleInsetVarContent(formatItem.configList)"
|
|
218
|
+
>
|
|
219
|
+
插入变量
|
|
220
|
+
</el-button>
|
|
221
|
+
<!-- Tip示例 -->
|
|
222
|
+
<el-tooltip
|
|
223
|
+
effect="dark"
|
|
224
|
+
:content="formatItem.tip"
|
|
225
|
+
placement="top-start"
|
|
226
|
+
>
|
|
227
|
+
<el-icon><InfoFilled /></el-icon>
|
|
228
|
+
</el-tooltip>
|
|
229
|
+
</div>
|
|
230
|
+
</template>
|
|
231
|
+
</div>
|
|
232
|
+
</div>
|
|
233
|
+
</template>
|
|
234
|
+
|
|
235
|
+
<style lang="scss" scoped>
|
|
236
|
+
.var-select-dialog {
|
|
237
|
+
min-width: 660px;
|
|
238
|
+
max-width: 1000px;
|
|
239
|
+
border-radius: 4px;
|
|
240
|
+
box-sizing: border-box;
|
|
241
|
+
box-shadow: var(--el-box-shadow-light);
|
|
242
|
+
background-color: var(--el-bg-color);
|
|
243
|
+
z-index: 2006;
|
|
244
|
+
position: fixed;
|
|
245
|
+
.custom-header {
|
|
246
|
+
display: flex;
|
|
247
|
+
align-items: center;
|
|
248
|
+
justify-content: space-between;
|
|
249
|
+
padding: 10px;
|
|
250
|
+
.left {
|
|
251
|
+
display: flex;
|
|
252
|
+
align-items: center;
|
|
253
|
+
flex: 1;
|
|
254
|
+
span {
|
|
255
|
+
margin-right: 10px;
|
|
256
|
+
}
|
|
257
|
+
.el-select {
|
|
258
|
+
width: 140px;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
.right {
|
|
262
|
+
display: flex;
|
|
263
|
+
align-items: center;
|
|
264
|
+
.el-button {
|
|
265
|
+
margin-right: 10px;
|
|
266
|
+
}
|
|
267
|
+
.el-icon {
|
|
268
|
+
cursor: pointer;
|
|
269
|
+
&:hover {
|
|
270
|
+
color: var(--el-color-primary);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
.custom-body {
|
|
276
|
+
min-height: 160px;
|
|
277
|
+
box-sizing: border-box;
|
|
278
|
+
border-top: var(--el-border);
|
|
279
|
+
padding: 20px 10px;
|
|
280
|
+
.format-item {
|
|
281
|
+
font-size: 12px;
|
|
282
|
+
display: flex;
|
|
283
|
+
align-items: center;
|
|
284
|
+
flex-wrap: wrap;
|
|
285
|
+
gap: 10px;
|
|
286
|
+
margin-bottom: 10px;
|
|
287
|
+
.config-list {
|
|
288
|
+
display: flex;
|
|
289
|
+
align-items: center;
|
|
290
|
+
.el-input {
|
|
291
|
+
width: 100px;
|
|
292
|
+
}
|
|
293
|
+
.el-select {
|
|
294
|
+
width: 100px;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
</style>
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
<!-- 组件: 品种自动补全搜索 -->
|
|
2
|
+
<script setup>
|
|
3
|
+
import { ref, inject } from "vue";
|
|
4
|
+
import { getUserData } from "st-func";
|
|
5
|
+
|
|
6
|
+
const stConfig = inject("stConfig");
|
|
7
|
+
|
|
8
|
+
const emit = defineEmits(["select", "change"]);
|
|
9
|
+
const props = defineProps({
|
|
10
|
+
size: { type: String, default: "default" },
|
|
11
|
+
placeholder: { type: String, default: "请输入品种名称或代码" },
|
|
12
|
+
labelShowEnable: { type: Boolean, default: true }, // 是否开启展示label
|
|
13
|
+
selectClearEnable: { type: Boolean, default: true }, // 是否开启选择回调后清除输入框值
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
const inputValue = ref("");
|
|
17
|
+
const fetchSuggestions = async (value, callback) => {
|
|
18
|
+
if (value === "" || value === "null") {
|
|
19
|
+
callback([]);
|
|
20
|
+
} else {
|
|
21
|
+
const params = {
|
|
22
|
+
keyWord: value,
|
|
23
|
+
pageNum: 1,
|
|
24
|
+
pageSize: 999,
|
|
25
|
+
userId: getUserData("id"),
|
|
26
|
+
hotSearchFlag: 1,
|
|
27
|
+
};
|
|
28
|
+
const { body } = await stConfig.request.post("/common/qt/getFeatureInfosByPage", params);
|
|
29
|
+
const result = body.list.map(({ code, featureName }) => ({
|
|
30
|
+
label: `${code}\xa0\xa0\xa0${featureName}`,
|
|
31
|
+
value: code,
|
|
32
|
+
}));
|
|
33
|
+
callback(result);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
const handleSelect = ({ label, value }) => {
|
|
37
|
+
const name = label.split("\xa0").at(-1);
|
|
38
|
+
const code = value;
|
|
39
|
+
emit("select", { name, code });
|
|
40
|
+
if (props.selectClearEnable) inputValue.value = "";
|
|
41
|
+
};
|
|
42
|
+
const handleChange = (value) => {
|
|
43
|
+
emit("change", value);
|
|
44
|
+
}
|
|
45
|
+
</script>
|
|
46
|
+
|
|
47
|
+
<template>
|
|
48
|
+
<div class="variety-auto-complete">
|
|
49
|
+
<span v-if="labelShowEnable">品种搜索:</span>
|
|
50
|
+
<el-autocomplete
|
|
51
|
+
v-model="inputValue"
|
|
52
|
+
clearable
|
|
53
|
+
:size="props.size"
|
|
54
|
+
:placeholder="props.placeholder"
|
|
55
|
+
:fetch-suggestions="fetchSuggestions"
|
|
56
|
+
@select="handleSelect"
|
|
57
|
+
@change="handleChange"
|
|
58
|
+
>
|
|
59
|
+
<template #default="{ item }">
|
|
60
|
+
<div class="label">{{ item.label }}</div>
|
|
61
|
+
</template>
|
|
62
|
+
</el-autocomplete>
|
|
63
|
+
</div>
|
|
64
|
+
</template>
|
|
65
|
+
|
|
66
|
+
<style lang="scss" scoped>
|
|
67
|
+
.variety-auto-complete {
|
|
68
|
+
width: 100%;
|
|
69
|
+
display: flex;
|
|
70
|
+
align-items: center;
|
|
71
|
+
span {
|
|
72
|
+
width: 80px;
|
|
73
|
+
}
|
|
74
|
+
.el-autocomplete {
|
|
75
|
+
flex: 1;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
</style>
|