st-comp 0.0.103 → 0.0.104

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.103",
4
+ "version": "0.0.104",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "dev": "vite",
@@ -63,12 +63,14 @@ const handleSubmit = () => {
63
63
  dialogFormRef.value.validate((valid) => {
64
64
  const { list, sqlEnable, sqlValue } = dialogForm.value;
65
65
  if (!valid) return;
66
- // 针对于开启了SQL功能后的字段校验
66
+ // 针对开启了SQL功能后的字段校验
67
67
  if (sqlEnable) {
68
68
  if (!sqlValue) return ElMessage.error("SQL语句不能为空");
69
- // 校验语句里是否存在因子中不存在的条件
69
+ // 提取SQL语句中的条件1, 条件2, ...
70
70
  const sqlConditions = extractConditionDetails(sqlValue);
71
+ // 生成因子表格中的条件1, 条件2, ...
71
72
  const factorConditions = list.map((item, index) => `条件${index + 1}`);
73
+ // 校验SQL中是否全部都能在因子表格中找到
72
74
  const noSaveConditions = sqlConditions.filter((item) => !factorConditions.includes(item));
73
75
  if (noSaveConditions.length) return ElMessage.error(`请检查SQL语句, 不存在[${noSaveConditions}]`);
74
76
  }
@@ -86,12 +88,30 @@ const handleDeleteFactor = (index) => {
86
88
  dialogForm.value.list.splice(index, 1);
87
89
  };
88
90
  // 表单: 添加因子
89
- const handleAppendFactor = () => {
90
- dialogForm.value.list.push({
91
- cycle: props.config.cycleDefault ?? null,
92
- factor: null,
93
- score: [null, null],
94
- });
91
+ const handleAppendFactor = (type) => {
92
+ switch (type) {
93
+ // 对比
94
+ case "compare": {
95
+ dialogForm.value.list.push({
96
+ key: "compare",
97
+ cycle: props.config.cycleDefault ?? null,
98
+ factor: null,
99
+ compareType: ">",
100
+ cycle2: props.config.cycleDefault ?? null,
101
+ factor2: null,
102
+ });
103
+ break;
104
+ }
105
+ // 常规
106
+ default: {
107
+ dialogForm.value.list.push({
108
+ cycle: props.config.cycleDefault ?? null,
109
+ factor: null,
110
+ score: [null, null],
111
+ });
112
+ break;
113
+ }
114
+ }
95
115
  };
96
116
  // 表单: 生成SQL
97
117
  const handleGenerateSql = () => {
@@ -125,14 +145,30 @@ const handleGenerateSql = () => {
125
145
 
126
146
  // Tag: 文案
127
147
  const handleFormatTag = (tag) => {
128
- const { cycle, factor, score } = tag;
129
- let str = "";
130
- str += ` ${props.config.cycleOptions.find(({ value }) => value === cycle).label}`;
131
- str += ` ${props.config.factorOptions.find(({ value }) => value === factor).label}`;
132
- str += ` ${score[0] || score[0] === 0 ? `${score[0]}分` : ""}`;
133
- str += " ~";
134
- str += ` ${score[1] || score[1] === 0 ? `${score[1]}分` : "∞"}`;
135
- return str;
148
+ switch (tag.key) {
149
+ // 对比
150
+ case "compare": {
151
+ const { cycle, factor, compareType, cycle2, factor2 } = tag;
152
+ let str = "";
153
+ str += ` ${props.config.cycleOptions.find(({ value }) => value === cycle).label}`;
154
+ str += ` ${props.config.factorOptions.find(({ value }) => value === factor).label}`;
155
+ str += ` ${compareType}`;
156
+ str += ` ${props.config.cycleOptions.find(({ value }) => value === cycle2).label}`;
157
+ str += ` ${props.config.factorOptions.find(({ value }) => value === factor2).label}`;
158
+ return str;
159
+ }
160
+ // 常规
161
+ default: {
162
+ const { cycle, factor, score } = tag;
163
+ let str = "";
164
+ str += ` ${props.config.cycleOptions.find(({ value }) => value === cycle).label}`;
165
+ str += ` ${props.config.factorOptions.find(({ value }) => value === factor).label}`;
166
+ str += ` ${score[0] || score[0] === 0 ? `${score[0]}分` : "∞"}`;
167
+ str += " ~";
168
+ str += ` ${score[1] || score[1] === 0 ? `${score[1]}分` : "∞"}`;
169
+ return str;
170
+ }
171
+ }
136
172
  };
137
173
  // Tag: 删除
138
174
  const handleDeleteTag = (aciton, index) => {
@@ -200,7 +236,7 @@ const handleDeleteTag = (aciton, index) => {
200
236
  <!-- 因子筛选弹窗 -->
201
237
  <el-dialog
202
238
  v-model="visible"
203
- width="530"
239
+ width="602"
204
240
  align-center
205
241
  destroy-on-close
206
242
  >
@@ -230,69 +266,171 @@ const handleDeleteTag = (aciton, index) => {
230
266
  v-for="(item, index) in dialogForm.list"
231
267
  class="form-row"
232
268
  >
233
- <!-- 序列标记 -->
269
+ <!-- 序列号 -->
234
270
  <span class="index">{{ `条件${index + 1}` }}</span>
235
- <!-- 周期 -->
236
- <el-form-item
237
- v-if="config.cycleShow"
238
- :prop="'list.' + index + '.cycle'"
239
- :rules="{ required: true, message: '周期不能为空', trigger: 'blur' }"
240
- style="width: 100px; margin-right: 10px"
241
- >
242
- <el-select
243
- v-model="item.cycle"
244
- placeholder="选择周期"
245
- size="small"
271
+ <!-- 对比因子 -->
272
+ <template v-if="item.key === 'compare'">
273
+ <!-- 周期 -->
274
+ <el-form-item
275
+ v-if="config.cycleShow"
276
+ :prop="'list.' + index + '.cycle'"
277
+ :rules="{ required: true, message: '周期不能为空', trigger: 'blur' }"
278
+ style="width: 100px; margin-right: 10px"
246
279
  >
247
- <el-option
248
- v-for="{ label, value } in config.cycleOptions"
249
- :label="label"
250
- :value="value"
251
- :key="value"
252
- />
253
- </el-select>
254
- </el-form-item>
255
- <!-- 因子 -->
256
- <el-form-item
257
- :prop="'list.' + index + '.factor'"
258
- :rules="{ required: true, message: '因子不能为空', trigger: 'blur' }"
259
- style="width: 100px; margin-right: 10px"
260
- >
261
- <el-select
262
- v-model="item.factor"
263
- placeholder="选择因子"
264
- filterable
265
- size="small"
266
- no-match-text="无匹配数据"
280
+ <el-select
281
+ v-model="item.cycle"
282
+ placeholder="选择周期"
283
+ size="small"
284
+ >
285
+ <el-option
286
+ v-for="{ label, value } in config.cycleOptions"
287
+ :label="label"
288
+ :value="value"
289
+ :key="value"
290
+ />
291
+ </el-select>
292
+ </el-form-item>
293
+ <!-- 因子 -->
294
+ <el-form-item
295
+ :prop="'list.' + index + '.factor'"
296
+ :rules="{ required: true, message: '因子不能为空', trigger: 'blur' }"
297
+ style="width: 100px; margin-right: 10px"
267
298
  >
268
- <el-option
269
- v-for="{ label, value } in config.factorOptions"
270
- :label="label"
271
- :value="value"
272
- :key="value"
273
- />
274
- </el-select>
275
- </el-form-item>
276
- <!-- 分数 -->
277
- <el-form-item
278
- :prop="'list.' + index + '.score'"
279
- :rules="{ validator: handleVerifyScore, trigger: 'blur' }"
280
- style="width: 200px; margin-right: 10px"
281
- >
282
- <div style="display: flex; align-items: center; width: 100%; height: 24px">
283
- <el-input-number
284
- v-model="item.score[0]"
299
+ <el-select
300
+ v-model="item.factor"
301
+ placeholder="选择因子"
302
+ filterable
285
303
  size="small"
286
- controls-position="right"
287
- />
288
- <span>~</span>
289
- <el-input-number
290
- v-model="item.score[1]"
304
+ no-match-text="无匹配数据"
305
+ >
306
+ <el-option
307
+ v-for="{ label, value } in config.factorOptions"
308
+ :label="label"
309
+ :value="value"
310
+ :key="value"
311
+ />
312
+ </el-select>
313
+ </el-form-item>
314
+ <!-- 对比符 -->
315
+ <el-form-item style="width: 52px; margin-right: 10px">
316
+ <el-select
317
+ v-model="item.compareType"
291
318
  size="small"
292
- controls-position="right"
293
- />
294
- </div>
295
- </el-form-item>
319
+ >
320
+ <el-option
321
+ v-for="item in ['>', '>=', '<', '<=']"
322
+ :label="item"
323
+ :value="item"
324
+ :key="item"
325
+ />
326
+ </el-select>
327
+ </el-form-item>
328
+ <!-- 周期2 -->
329
+ <el-form-item
330
+ v-if="config.cycleShow"
331
+ :prop="'list.' + index + '.cycle2'"
332
+ :rules="{ required: true, message: '周期不能为空', trigger: 'blur' }"
333
+ style="width: 100px; margin-right: 10px"
334
+ >
335
+ <el-select
336
+ v-model="item.cycle2"
337
+ placeholder="选择周期"
338
+ size="small"
339
+ >
340
+ <el-option
341
+ v-for="{ label, value } in config.cycleOptions"
342
+ :label="label"
343
+ :value="value"
344
+ :key="value"
345
+ />
346
+ </el-select>
347
+ </el-form-item>
348
+ <!-- 因子2 -->
349
+ <el-form-item
350
+ :prop="'list.' + index + '.factor2'"
351
+ :rules="{ required: true, message: '因子不能为空', trigger: 'blur' }"
352
+ style="width: 100px; margin-right: 10px"
353
+ >
354
+ <el-select
355
+ v-model="item.factor2"
356
+ placeholder="选择因子"
357
+ filterable
358
+ size="small"
359
+ no-match-text="无匹配数据"
360
+ >
361
+ <el-option
362
+ v-for="{ label, value } in config.factorOptions"
363
+ :label="label"
364
+ :value="value"
365
+ :key="value"
366
+ />
367
+ </el-select>
368
+ </el-form-item>
369
+ </template>
370
+ <!-- 常规因子 -->
371
+ <template v-else>
372
+ <!-- 周期 -->
373
+ <el-form-item
374
+ v-if="config.cycleShow"
375
+ :prop="'list.' + index + '.cycle'"
376
+ :rules="{ required: true, message: '周期不能为空', trigger: 'blur' }"
377
+ style="width: 100px; margin-right: 10px"
378
+ >
379
+ <el-select
380
+ v-model="item.cycle"
381
+ placeholder="选择周期"
382
+ size="small"
383
+ >
384
+ <el-option
385
+ v-for="{ label, value } in config.cycleOptions"
386
+ :label="label"
387
+ :value="value"
388
+ :key="value"
389
+ />
390
+ </el-select>
391
+ </el-form-item>
392
+ <!-- 因子 -->
393
+ <el-form-item
394
+ :prop="'list.' + index + '.factor'"
395
+ :rules="{ required: true, message: '因子不能为空', trigger: 'blur' }"
396
+ style="width: 100px; margin-right: 10px"
397
+ >
398
+ <el-select
399
+ v-model="item.factor"
400
+ placeholder="选择因子"
401
+ filterable
402
+ size="small"
403
+ no-match-text="无匹配数据"
404
+ >
405
+ <el-option
406
+ v-for="{ label, value } in config.factorOptions"
407
+ :label="label"
408
+ :value="value"
409
+ :key="value"
410
+ />
411
+ </el-select>
412
+ </el-form-item>
413
+ <!-- 分数 -->
414
+ <el-form-item
415
+ :prop="'list.' + index + '.score'"
416
+ :rules="{ validator: handleVerifyScore, trigger: 'blur' }"
417
+ style="width: 200px; margin-right: 10px"
418
+ >
419
+ <div style="display: flex; align-items: center; width: 100%; height: 24px">
420
+ <el-input-number
421
+ v-model="item.score[0]"
422
+ size="small"
423
+ controls-position="right"
424
+ />
425
+ <span>~</span>
426
+ <el-input-number
427
+ v-model="item.score[1]"
428
+ size="small"
429
+ controls-position="right"
430
+ />
431
+ </div>
432
+ </el-form-item>
433
+ </template>
296
434
  <!-- 删除 -->
297
435
  <el-icon @click="handleDeleteFactor(index)"><CircleCloseFilled /></el-icon>
298
436
  </div>
@@ -305,6 +443,15 @@ const handleDeleteTag = (aciton, index) => {
305
443
  style="margin-bottom: 10px"
306
444
  >添加因子</el-button
307
445
  >
446
+ <el-button
447
+ type="primary"
448
+ plain
449
+ size="small"
450
+ :icon="Plus"
451
+ @click="handleAppendFactor('compare')"
452
+ style="margin-bottom: 10px"
453
+ >添加因子对比</el-button
454
+ >
308
455
  <!-- SQL功能 -->
309
456
  <template v-if="config.sqlShow">
310
457
  <el-form-item label="SQL功能: ">
@@ -128,37 +128,64 @@ defineExpose({
128
128
  // 5.因子筛选
129
129
  if (config.value.factorScreen?.show) {
130
130
  const { factorScreen } = data;
131
- // 因子列表参数
131
+ // tbFeatureFactorScores参数整理
132
132
  if (factorScreen?.list?.length) {
133
133
  params.tbFeatureFactorScores = factorScreen.list.map((item) => {
134
- return {
135
- freqId: item.cycle,
136
- factorId: item.factor,
137
- startScore: item.score[0],
138
- endScore: item.score[1],
139
- };
134
+ switch (item.key) {
135
+ // 对比
136
+ case "compare": {
137
+ return {
138
+ freqId: item.cycle,
139
+ factorId: item.factor,
140
+ compareType: item.compareType,
141
+ freqId2: item.cycle2,
142
+ factorId2: item.factor2,
143
+ };
144
+ }
145
+ // 常规
146
+ default: {
147
+ return {
148
+ freqId: item.cycle,
149
+ factorId: item.factor,
150
+ startScore: item.score[0],
151
+ endScore: item.score[1],
152
+ };
153
+ }
154
+ }
140
155
  });
141
156
  }
142
- // SQL语句参数
143
- params.enableSql = factorScreen.sqlEnable === 1 ? 2 : 1;
157
+ // sql参数整理
144
158
  if (factorScreen.sqlEnable) {
145
159
  const conditions = factorScreen.list.reduce((result, item, index) => {
146
160
  const key = `条件${index + 1}`;
147
- let sql = `factor_id = ${item.factor} and `;
148
- if (config.value.factorScreen?.cycleShow) sql = `freq_id = ${item.cycle} and factor_id = ${item.factor} and `;
149
- // 分数语句的判断
150
- if ((item.score[0] || item.score[0] === 0) && (item.score[1] || item.score[1] === 0)) {
151
- sql += `score >= ${item.score[0]} and score <= ${item.score[1]}`;
152
- } else if (item.score[0] || item.score[0] === 0) {
153
- sql += `score >= ${item.score[0]}`;
154
- } else if (item.score[1] || item.score[1] === 0) {
155
- sql += `score <= ${item.score[1]}`;
161
+ switch (item.key) {
162
+ case "compare": {
163
+ let sql = "";
164
+ if (config.value.factorScreen?.cycleShow) {
165
+ sql = `freq_id = ${item.cycle} and factor_id = ${item.factor} ${item.compareType} freq_id = ${item.cycle2} and factor_id = ${item.factor2}`;
166
+ } else {
167
+ sql = `factor_id = ${item.factor} ${item.compareType} factor_id = ${item.factor2}`;
168
+ }
169
+ result.set(key, `(${sql})`);
170
+ break;
171
+ }
172
+ default: {
173
+ let sql = `factor_id = ${item.factor} and `;
174
+ if (config.value.factorScreen?.cycleShow) sql = `freq_id = ${item.cycle} and factor_id = ${item.factor} and `;
175
+ // 分数语句
176
+ if ((item.score[0] || item.score[0] === 0) && (item.score[1] || item.score[1] === 0)) {
177
+ sql += `score >= ${item.score[0]} and score <= ${item.score[1]}`;
178
+ } else if (item.score[0] || item.score[0] === 0) {
179
+ sql += `score >= ${item.score[0]}`;
180
+ } else if (item.score[1] || item.score[1] === 0) {
181
+ sql += `score <= ${item.score[1]}`;
182
+ }
183
+ result.set(key, `(${sql})`);
184
+ }
156
185
  }
157
- // 格式化因子sql语句
158
- sql = `(${sql})`;
159
- result.set(key, sql);
160
186
  return result;
161
187
  }, new Map([]));
188
+ // 将(SQL语句)与(字符串条件N)进行替换
162
189
  let sqlStr = factorScreen.sqlValue;
163
190
  for (const [key, value] of conditions) {
164
191
  const regex = new RegExp(key, "g");
@@ -166,6 +193,8 @@ defineExpose({
166
193
  }
167
194
  params.sql = sqlStr;
168
195
  }
196
+ // enableSql参数整理
197
+ params.enableSql = factorScreen.sqlEnable === 1 ? 2 : 1;
169
198
  }
170
199
  // 6.常用指标
171
200
  {
@@ -57,13 +57,13 @@ const varietySearchConfig = ref({
57
57
  sqlShow: true,
58
58
  // 周期下拉框数据源
59
59
  cycleOptions: [
60
- { label: "Mock周期一", value: 1 },
61
- { label: "Mock周期二", value: 2 },
60
+ { label: "周期一", value: 1 },
61
+ { label: "周期二", value: 2 },
62
62
  ],
63
63
  // 因子下拉框数据源
64
64
  factorOptions: [
65
- { label: "Mock因子一", value: 1 },
66
- { label: "Mock因子二", value: 2 },
65
+ { label: "因子一", value: 1 },
66
+ { label: "因子二", value: 2 },
67
67
  ],
68
68
  // 因子使用说明数据源
69
69
  factorDescriptions: [],