st-comp 0.0.47 → 0.0.49

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "st-comp",
3
3
  "public": true,
4
- "version": "0.0.47",
4
+ "version": "0.0.49",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "dev": "vite",
@@ -23,6 +23,7 @@
23
23
  },
24
24
  "devDependencies": {
25
25
  "@vitejs/plugin-vue": "^4.2.3",
26
+ "@vitejs/plugin-vue-jsx": "^3.1.0",
26
27
  "sass": "^1.69.3",
27
28
  "ssh2": "^1.14.0",
28
29
  "ssh2-sftp-client": "^9.1.0",
@@ -6,56 +6,59 @@
6
6
  </template>
7
7
 
8
8
  <script setup lang="ts">
9
- import { computed } from 'vue'
10
- import Tips from '../Tips/index.vue'
11
- import { stMath } from 'st-func'
12
- const { round, multiply, divide, subtract } = stMath
9
+ import { computed } from "vue";
10
+ import Tips from "../Tips/index.vue";
11
+ import { stMath } from "st-func";
12
+ const { round, multiply, divide, subtract } = stMath;
13
13
 
14
- const props = defineProps({
15
- // 提示数据
16
- drawData: {
17
- type: Object,
18
- require: true,
19
- },
20
- activeIndex: {
21
- type: Number,
22
- require: true,
23
- },
24
- })
14
+ const props = defineProps({
15
+ // 提示数据
16
+ drawData: {
17
+ type: Object,
18
+ require: true,
19
+ },
20
+ activeIndex: {
21
+ type: Number,
22
+ require: true,
23
+ },
24
+ });
25
25
 
26
- const mainTips = computed(() => {
27
- const { drawData, activeIndex } = (props as any)
28
- if (drawData.candlestickData && drawData.candlestickData[activeIndex]) {
29
- const itemData = drawData.candlestickData[activeIndex]
30
- const diff = round(multiply(divide(subtract(itemData[1], itemData[4]), itemData[4]), 100))
31
- let diffColor
32
- if (diff > 0) {
33
- diffColor = 'red'
34
- } else if (diff < 0) {
35
- diffColor = 'green'
36
- }
37
- return [
38
- { label: '开', value: round(itemData[0]) },
39
- { label: '高', value: round(itemData[3]) },
40
- { label: '低', value: round(itemData[2]) },
41
- { label: '收', value: round(itemData[1]) },
42
- { label: '涨跌', value: `${diff}%`, color: diffColor },
43
- ]
26
+ const mainTips = computed(() => {
27
+ const { drawData, activeIndex } = props as any;
28
+ if (drawData.candlestickData && drawData.candlestickData[activeIndex]) {
29
+ const itemData = drawData.candlestickData[activeIndex];
30
+ // 收盘价 - 昨收 / (昨收绝对值)
31
+ const diff = round(multiply(divide(subtract(itemData[1], itemData[4]), Math.abs(itemData[4])), 100));
32
+ let diffColor;
33
+ if (diff > 0) {
34
+ diffColor = "red";
35
+ } else if (diff < 0) {
36
+ diffColor = "green";
44
37
  }
45
- return []
46
- })
38
+ return [
39
+ { label: "开", value: round(itemData[0]) },
40
+ { label: "高", value: round(itemData[3]) },
41
+ { label: "低", value: round(itemData[2]) },
42
+ { label: "收", value: round(itemData[1]) },
43
+ { label: "涨跌", value: `${diff}%`, color: diffColor },
44
+ ];
45
+ }
46
+ return [];
47
+ });
47
48
 
48
- const mainIndicatorTips = computed(() => {
49
- const { drawData, activeIndex } = props
50
- return drawData?.mainIndicatorData?.map(item => {
51
- return { label: item.key, value: round(item.data[activeIndex]), color: item.color }
49
+ const mainIndicatorTips = computed(() => {
50
+ const { drawData, activeIndex } = props;
51
+ return (
52
+ drawData?.mainIndicatorData?.map((item) => {
53
+ return { label: item.key, value: round(item.data[activeIndex]), color: item.color };
52
54
  }) || []
53
- })
55
+ );
56
+ });
54
57
  </script>
55
58
 
56
59
  <style lang="scss" scoped>
57
- .kline-tips {
58
- padding-left: 3px;
59
- width: 100%;
60
- }
60
+ .kline-tips {
61
+ padding-left: 3px;
62
+ width: 100%;
63
+ }
61
64
  </style>
@@ -1,14 +1,14 @@
1
- import { App } from "vue";
2
- import KlineUtils from "./components/KlineUtils/index.vue"
3
- import KlineTips from "./components/KlineTips/index.vue"
4
- import KlineSub from "./components/KlineSub/index.vue"
5
- import KlineSlide from "./components/KlineSlide/index.vue"
6
-
7
- export default {
8
- install(app: App) {
9
- app.component("st-klineUtils", KlineUtils);
10
- app.component("st-klineSub", KlineSub);
11
- app.component("st-klineTips", KlineTips);
12
- app.component("st-klineSlide", KlineSlide);
13
- },
14
- }
1
+ import { App } from "vue";
2
+ import KlineUtils from "./components/KlineUtils/index.vue"
3
+ import KlineTips from "./components/KlineTips/index.vue"
4
+ import KlineSub from "./components/KlineSub/index.vue"
5
+ import KlineSlide from "./components/KlineSlide/index.vue"
6
+
7
+ export default {
8
+ install(app: App) {
9
+ app.component("st-klineUtils", KlineUtils);
10
+ app.component("st-klineSub", KlineSub);
11
+ app.component("st-klineTips", KlineTips);
12
+ app.component("st-klineSlide", KlineSlide);
13
+ },
14
+ }
@@ -0,0 +1,77 @@
1
+ <template>
2
+ <div class="st-VarietySearch-checkBox">
3
+ <div class="st-VarietySearch-checkBox-label">
4
+ {{ config.label }}:
5
+ <el-button
6
+ text
7
+ size="small"
8
+ type="primary"
9
+ @click="checkList = []"
10
+ >
11
+ 不限
12
+ </el-button>
13
+ </div>
14
+ <div class="st-VarietySearch-checkBox-content">
15
+ <el-checkbox-group
16
+ size="small"
17
+ v-model="checkList"
18
+ >
19
+ <el-checkbox
20
+ v-for="item in config.options"
21
+ :key="item.value"
22
+ :label="item.value"
23
+ >
24
+ {{ item.label }}
25
+ </el-checkbox>
26
+ </el-checkbox-group>
27
+ </div>
28
+ </div>
29
+ </template>
30
+
31
+ <script setup>
32
+ import { ref, watch } from 'vue'
33
+
34
+ const emit = defineEmits(['change']);
35
+ const props = defineProps({
36
+ config: {
37
+ type: Object,
38
+ require: true,
39
+ default: () => ({}),
40
+ },
41
+ formData: {
42
+ type: Object,
43
+ require: true,
44
+ },
45
+ })
46
+
47
+ const checkList = ref([])
48
+
49
+ watch(() => props.formData, () => {
50
+ checkList.value = props.formData[props.config.key] || []
51
+ }, { deep: true })
52
+
53
+ watch(checkList, () => {
54
+ emit('change', props.config.key, checkList.value)
55
+ })
56
+ </script>
57
+
58
+ <style lang="scss" scoped>
59
+ .st-VarietySearch-checkBox {
60
+ &-label {
61
+ display: inline-block;
62
+ vertical-align: top;
63
+ width: 120px;
64
+ height: 24px;
65
+ line-height: 22px;
66
+ font-size: 12px;
67
+ &-clear {
68
+ color: #409eff;
69
+ }
70
+ }
71
+ &-content {
72
+ vertical-align: top;
73
+ width: calc(100% - 120px);
74
+ display: inline-block;
75
+ }
76
+ }
77
+ </style>
@@ -0,0 +1,256 @@
1
+ <template>
2
+ <div class="st-VarietySearch-factorFilter">
3
+ <div class="st-VarietySearch-factorFilter-label">
4
+ {{ config.label }}:
5
+ <el-button
6
+ text
7
+ size="small"
8
+ type="primary"
9
+ @click="clear"
10
+ >
11
+ 不限
12
+ </el-button>
13
+ </div>
14
+ <div class="st-VarietySearch-factorFilter-content">
15
+ <el-tag
16
+ v-for="item in tagList"
17
+ style="margin-right: 5px"
18
+ :key="item.key"
19
+ closable
20
+ type="info"
21
+ :disable-transitions="false"
22
+ @close="deleteFactor(item, true)"
23
+ >
24
+ {{ item.freqName || "" }}
25
+ {{ item.factorName || "" }}
26
+ {{ item.startScore === null ? " / " : item.startScore + "分" }}
27
+ <span>~</span>
28
+ {{ item.endScore === null ? " / " : item.endScore + "分" }}
29
+ </el-tag>
30
+ <el-button type="primary" plain size="small" @click="open">
31
+ + 添加因子
32
+ </el-button>
33
+ </div>
34
+ <el-dialog
35
+ v-model="visible"
36
+ class="st-VarietySearch-factorFilter-dialog"
37
+ title="因子筛选"
38
+ align-center
39
+ :draggable="true"
40
+ width="510"
41
+ >
42
+ <el-row
43
+ v-for="item in factorList"
44
+ style="margin-bottom: 10px;"
45
+ :key="item.key"
46
+ >
47
+ <el-col :span="6">
48
+ <el-select
49
+ v-model="item.freqId"
50
+ :style="{ width: '100px' }"
51
+ :class="!item.freqId && check ? 'st-VarietySearch-factorFilter-border-red' : ''"
52
+ size="small"
53
+ placeholder="选择周期"
54
+ >
55
+ <el-option
56
+ v-for="optionItem in config.freqList"
57
+ :key="optionItem.value"
58
+ :label="optionItem.label"
59
+ :value="optionItem.value"
60
+ />
61
+ </el-select>
62
+ </el-col>
63
+ <el-col :span="7">
64
+ <el-select
65
+ v-model="item.factorId"
66
+ :class="!item.factorId && check ? 'st-VarietySearch-factorFilter-border-red' : ''"
67
+ :style="{ width: '120px' }"
68
+ size="small"
69
+ placeholder="选择因子"
70
+ >
71
+ <el-option
72
+ v-for="optionItem in config.factorList"
73
+ :key="optionItem.value"
74
+ :label="optionItem.label"
75
+ :value="optionItem.value"
76
+ />
77
+ </el-select>
78
+ </el-col>
79
+ <el-col :span="10">
80
+ <el-input-number
81
+ v-model="item.startScore"
82
+ :class="!((item.startScore || item.startScore === 0) || (item.endScore || item.endScore === 0)) && check ? 'st-VarietySearch-factorFilter-border-red' : ''"
83
+ style="width: 85px"
84
+ :step="0.5"
85
+ :min="-999"
86
+ :max="999"
87
+ placeholder="分数"
88
+ controls-position="right"
89
+ size="small"
90
+ />
91
+ <span> ~ </span>
92
+ <el-input-number
93
+ v-model="item.endScore"
94
+ :class="!((item.startScore || item.startScore === 0) || (item.endScore || item.endScore === 0)) && check ? 'st-VarietySearch-factorFilter-border-red' : ''"
95
+ style="width: 85px"
96
+ :step="0.5"
97
+ :min="-999"
98
+ :max="999"
99
+ controls-position="right"
100
+ placeholder="分数"
101
+ size="small"
102
+ />
103
+ </el-col>
104
+ <el-col :span="1">
105
+ <el-text
106
+ type="info"
107
+ style="cursor: pointer; vertical-align: -3px;"
108
+ @click="deleteFactor(item)"
109
+ >
110
+ <el-icon><CircleCloseFilled /></el-icon>
111
+ </el-text>
112
+ </el-col>
113
+ </el-row>
114
+ <el-button type="primary" plain size="small" @click="addFactor">
115
+ + 添加因子
116
+ </el-button>
117
+ <template #footer>
118
+ <div class="dialog-footer">
119
+ <el-button size="small" @click="visible = false">取消</el-button>
120
+ <el-button size="small" type="primary" @click="submit">
121
+ 确认
122
+ </el-button>
123
+ </div>
124
+ </template>
125
+ </el-dialog>
126
+ </div>
127
+ </template>
128
+
129
+ <script setup>
130
+ import { ref, computed } from 'vue'
131
+ import { CircleCloseFilled } from "@element-plus/icons-vue";
132
+ import { ElMessage } from 'element-plus';
133
+
134
+ const emit = defineEmits(['change']);
135
+ const props = defineProps({
136
+ config: {
137
+ type: Object,
138
+ require: true,
139
+ default: () => ({ key: new Date() }),
140
+ },
141
+ formData: {
142
+ type: Object,
143
+ require: true,
144
+ },
145
+ })
146
+
147
+ const defauleItem = {
148
+ factorId: null, // 因子id
149
+ freqId: null, // 周期id
150
+ startScore: null, // 开始分值
151
+ endScore: null, // 结束分值
152
+ }
153
+
154
+ const visible = ref(false)
155
+ const factorList = ref([])
156
+ const check = ref(false)
157
+
158
+ // 标签列表
159
+ const tagList = computed(() => {
160
+ return props.formData[props.config.key].filter(item => item.factorId && item.freqId).map(item => {
161
+ return {
162
+ ...item,
163
+ freqName: props.config.freqList.find(i => i.value === item.freqId)?.label,
164
+ factorName: props.config.factorList.find(i => i.id === item.factorId)?.factorName,
165
+ }
166
+ })
167
+ })
168
+
169
+ // 打开弹窗
170
+ const open = () => {
171
+ if (factorList.value.length === 0) {
172
+ addFactor()
173
+ }
174
+ visible.value = true
175
+ }
176
+
177
+ // 添加因子
178
+ const addFactor = () => {
179
+ factorList.value.push({ ...defauleItem, key: new Date().getTime() })
180
+ }
181
+
182
+ // 删除因子
183
+ const deleteFactor = (item, isUpdate = false) => {
184
+ factorList.value = factorList.value.filter(i => i.key !== item.key)
185
+ if (isUpdate) {
186
+ emit('change', props.config.key, [...factorList.value])
187
+ }
188
+ }
189
+
190
+ // 不限
191
+ const clear = () => {
192
+ factorList.value = []
193
+ emit('change', props.config.key, [])
194
+ }
195
+
196
+ // 提交
197
+ const submit = () => {
198
+ for(let i = 0; i < factorList.value.length; i++) {
199
+ const item = factorList.value[i]
200
+ if (!(
201
+ item.factorId &&
202
+ item.freqId &&
203
+ ((item.startScore || item.startScore === 0) || (item.endScore || item.endScore === 0))
204
+ )) {
205
+ check.value = true
206
+ ElMessage.error('请检查列表参数后重试!')
207
+ return
208
+ }
209
+ }
210
+ emit('change', props.config.key, [...factorList.value])
211
+ check.value = false
212
+ visible.value = false
213
+ }
214
+ </script>
215
+
216
+ <style lang="scss">
217
+ .st-VarietySearch-factorFilter-border-red .el-input__wrapper,
218
+ .st-VarietySearch-factorFilter-border-red .el-select__wrapper {
219
+ box-shadow: 0 0 0 1px var(--el-color-danger) inset;
220
+ }
221
+ .st-VarietySearch-factorFilter-dialog {
222
+ .el-dialog__header {
223
+ padding-top: 10px;
224
+ .el-dialog__headerbtn {
225
+ width: 40px;
226
+ height: 40px;
227
+ }
228
+ }
229
+ .el-dialog__body {
230
+ border-top: 1px solid var(--el-border-color);
231
+ border-bottom: 1px solid var(--el-border-color);
232
+ padding: 15px 20px;
233
+ }
234
+ }
235
+ </style>
236
+
237
+ <style lang="scss" scoped>
238
+ .st-VarietySearch-factorFilter {
239
+ &-label {
240
+ display: inline-block;
241
+ vertical-align: top;
242
+ width: 120px;
243
+ height: 24px;
244
+ line-height: 22px;
245
+ font-size: 12px;
246
+ &-clear {
247
+ color: #409eff;
248
+ }
249
+ }
250
+ &-content {
251
+ vertical-align: top;
252
+ width: calc(100% - 120px);
253
+ display: inline-block;
254
+ }
255
+ }
256
+ </style>