st-comp 0.0.150 → 0.0.152

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.150",
4
+ "version": "0.0.152",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "dev": "vite",
@@ -133,6 +133,7 @@ const levelText = computed(() => {
133
133
 
134
134
  defineExpose({
135
135
  pwdValidators,
136
+ levelValue,
136
137
  // 提供给表单校验使用
137
138
  ruleFormPassword: [
138
139
  { required: true, trigger: "blur", message: "密码不能为空" },
@@ -37,6 +37,7 @@
37
37
  ref="changePasswordFormRef"
38
38
  :model="changePasswordForm"
39
39
  :rules="changePasswordRules"
40
+ :validate-on-rule-change="false"
40
41
  @submit.native.prevent="changePasswordFn"
41
42
  @keyup.enter.native="changePasswordFn"
42
43
  label-width="auto"
@@ -125,10 +126,7 @@ const changePasswordForm = ref({
125
126
  confirmPassword: "",
126
127
  });
127
128
  const changePasswordRules = ref({
128
- oldPassword: [
129
- { required: true, message: "请输入原密码", trigger: "blur" },
130
- { min: 6, max: 18, trigger: "blur", message: "密码长度为6到18位" },
131
- ],
129
+ oldPassword: [{ required: true, message: "请输入原密码", trigger: "blur" }],
132
130
  newPassword: [],
133
131
  confirmPassword: [
134
132
  { required: true, message: "请输入确认密码", trigger: "blur" },
@@ -144,7 +142,6 @@ const changePasswordRules = ref({
144
142
  },
145
143
  trigger: "blur",
146
144
  },
147
- { min: 6, max: 18, trigger: "blur", message: "密码长度为6到18位" },
148
145
  ],
149
146
  });
150
147
  const isFocusNewPassword = ref(false); // 是否聚焦新密码
@@ -176,11 +173,6 @@ const changePasswordDialogOpen = () => {
176
173
  if (changePasswordRules.value.newPassword.length === 0) {
177
174
  nextTick(() => {
178
175
  changePasswordRules.value.newPassword = PasswordPromptRef.value?.ruleFormPassword;
179
- // 宏任务清除element-plus表单规则调整后的自动校验
180
- let timer = setTimeout(() => {
181
- changePasswordFormRef.value.resetFields();
182
- clearTimeout(timer);
183
- }, 0);
184
176
  });
185
177
  }
186
178
  };
@@ -2,6 +2,14 @@
2
2
  <script setup name="CommonIndicator">
3
3
  import { ref, watch, computed } from "vue";
4
4
 
5
+ const perVolumnRadioOptions = [
6
+ { label: '近2周', value: 'last2WeekVolumn' },
7
+ { label: '近1个月', value: 'last1MonthVolumn' },
8
+ { label: '近3个月', value: 'last3MonthVolumn' },
9
+ { label: '近6个月', value: 'last6MonthVolumn' },
10
+ { label: '近1年', value: 'last12MonthVolumn' },
11
+ ]
12
+
5
13
  const data = defineModel("data", { default: [] });
6
14
  const props = defineProps({
7
15
  config: { type: Object, default: () => {} },
@@ -85,6 +93,24 @@ const clickIndicator = (item) => {
85
93
  };
86
94
  break;
87
95
  }
96
+ // 成交量
97
+ case "perVolumn": {
98
+ indicatorValue.value = {
99
+ ...baseParams,
100
+ radio: 'last12MonthVolumn',
101
+ levels: [],
102
+ };
103
+ break;
104
+ }
105
+ // 主力净流入资金
106
+ case "mainFlow": {
107
+ indicatorValue.value = {
108
+ ...baseParams,
109
+ mainFlowRadioType: '0',
110
+ rankRange: [null, null],
111
+ };
112
+ break;
113
+ }
88
114
  // 其它的通用处理
89
115
  default: {
90
116
  indicatorValue.value = {
@@ -149,6 +175,39 @@ const submitDialog = () => {
149
175
  indicatorValue.value.tagText = `${label}: ${optionsCpType === 1 ? "看涨" : "看跌"}`;
150
176
  break;
151
177
  }
178
+ // 成交量
179
+ case "perVolumn": {
180
+ const { label, radio, levels } = indicatorValue.value;
181
+ // 校验
182
+ if (!levels?.length) return ElMessage.warning("格式错误: 请选择分位");
183
+ // 格式化文案
184
+ indicatorValue.value.tagText = `${label}: ${
185
+ perVolumnRadioOptions.find(item => item.value === radio)?.label
186
+ }${
187
+ levels.map(i => `${i}分位`).join('、')
188
+ }`;
189
+ break;
190
+ }
191
+ // 主力净流入资金
192
+ case "mainFlow": {
193
+ const { label, mainFlowRadioType, radio, rankRange } = indicatorValue.value;
194
+ const checkNumber = (val) => {
195
+ if (val === '' || val === null || val === undefined) return false;
196
+ const num = Number(val)
197
+ if (isNaN(num)) return false;
198
+ return true
199
+ }
200
+ // 校验
201
+ if (!radio) return ElMessage.warning("格式错误: 请选择时间");
202
+ if (!checkNumber(rankRange[0]) || !checkNumber(rankRange[1])) {
203
+ return ElMessage.warning(`格式错误: 请填写${mainFlowRadioType === '0' ? '涨幅范围' : '排名范围'}`);
204
+ }
205
+ // 格式化文案
206
+ indicatorValue.value.tagText = `${label}: ${radio}日${
207
+ mainFlowRadioType === '0' ? '涨幅范围' : '排名范围'
208
+ }: ${rankRange[0]}${mainFlowRadioType === '0' ? '%' : ''} ~ ${rankRange[1]}${mainFlowRadioType === '0' ? '%' : ''}`;
209
+ break;
210
+ }
152
211
  // 其它的通用处理
153
212
  default: {
154
213
  const { label, unit, radioType } = indicatorValue.value;
@@ -257,6 +316,11 @@ watch(
257
316
  }
258
317
  }
259
318
  );
319
+
320
+ const changeMainFlowRadioType = () => {
321
+ indicatorValue.value.radio = null;
322
+ indicatorValue.value.rankRange = [null, null];
323
+ }
260
324
  </script>
261
325
 
262
326
  <template>
@@ -315,6 +379,17 @@ watch(
315
379
  <el-radio-button :disabled="rankKey && rankKey !== nowIndicator.key" label="排名" value="1" />
316
380
  </el-radio-group>
317
381
  </template>
382
+ <template #header v-else-if="nowIndicator.key === 'mainFlow'">
383
+ <span style="font-size: 18px;">{{ nowIndicator.label }}</span>
384
+ <el-radio-group
385
+ v-model="indicatorValue.mainFlowRadioType"
386
+ style="vertical-align: 4px; margin-left: 12px;"
387
+ @change="changeMainFlowRadioType"
388
+ >
389
+ <el-radio-button label="涨幅范围" value="0" />
390
+ <el-radio-button label="排名范围" value="1" />
391
+ </el-radio-group>
392
+ </template>
318
393
 
319
394
  <template v-if="nowIndicator.type === undefined && indicatorValue.radioType === '1'">
320
395
  <!-- 输入框区域 -->
@@ -336,7 +411,7 @@ watch(
336
411
  <!-- 便捷配置项区域 -->
337
412
  <div
338
413
  class="convenient-option-box"
339
- v-if="nowIndicator.convenientOptions.length"
414
+ v-if="nowIndicator.convenientOptions?.length"
340
415
  >
341
416
  <el-button
342
417
  v-for="item in nowIndicator.convenientOptions"
@@ -491,6 +566,51 @@ watch(
491
566
  />
492
567
  </el-radio-group>
493
568
  </div>
569
+ <!-- 成交量 -->
570
+ <div v-if="nowIndicator.key === 'perVolumn'">
571
+ <el-radio-group v-model="indicatorValue.radio">
572
+ <el-radio
573
+ v-for="item in perVolumnRadioOptions"
574
+ :key="item.value"
575
+ :value="item.value"
576
+ >{{ item.label }}</el-radio>
577
+ </el-radio-group>
578
+ <el-select
579
+ v-model="indicatorValue.levels"
580
+ multiple
581
+ clearable
582
+ placeholder="请选择"
583
+ style="width: 420px"
584
+ >
585
+ <el-option
586
+ v-for="item in [1, 2, 3, 4, 5]"
587
+ :key="item"
588
+ :label="`${item}分位`"
589
+ :value="item"
590
+ />
591
+ </el-select>
592
+ </div>
593
+ <!-- 主力净流入资金 -->
594
+ <div v-if="nowIndicator.key === 'mainFlow'">
595
+ <el-radio-group v-model="indicatorValue.radio">
596
+ <el-radio value="3">3日</el-radio>
597
+ <el-radio value="5">5日</el-radio>
598
+ <el-radio value="10">10日</el-radio>
599
+ <el-radio value="20">20日</el-radio>
600
+ </el-radio-group>
601
+ <div style="display: flex; align-items: center;">
602
+ <span>{{ indicatorValue.mainFlowRadioType === '0' ? '涨幅范围' : '排名范围' }}:&nbsp;</span>
603
+ <el-input
604
+ v-model="indicatorValue.rankRange[0]"
605
+ style="flex: 1"
606
+ />
607
+ ~
608
+ <el-input
609
+ v-model="indicatorValue.rankRange[1]"
610
+ style="flex: 1"
611
+ />
612
+ </div>
613
+ </div>
494
614
  </template>
495
615
  <!-- 确定 -->
496
616
  <template #footer>
@@ -295,6 +295,16 @@ export default {
295
295
  // 默认数值
296
296
  defaultRankRange: [0, 25],
297
297
  },
298
+ // 成交量
299
+ {
300
+ key: "perVolumn",
301
+ label: "成交量",
302
+ type: "custom",
303
+ parent: {
304
+ varietyMarketIds: [3, 5, 7],
305
+ commonOptionIds: [4, 6, 12, 14, 15, 16],
306
+ },
307
+ },
298
308
  // 净资产收益率roe
299
309
  {
300
310
  key: "roe",
@@ -367,6 +377,16 @@ export default {
367
377
  },
368
378
  type: "custom",
369
379
  },
380
+ // 主力净流入资金
381
+ {
382
+ key: "mainFlow",
383
+ label: "主力净流入资金",
384
+ type: "custom",
385
+ parent: {
386
+ varietyMarketIds: [3, 5, 7],
387
+ commonOptionIds: [4, 6, 12, 14, 15, 16],
388
+ },
389
+ },
370
390
 
371
391
  // ----------期权-----------
372
392
 
@@ -469,7 +489,7 @@ export default {
469
489
  // 成交量
470
490
  {
471
491
  key: "volume",
472
- label: "成交量",
492
+ label: "成交量(期权)",
473
493
  parent: {
474
494
  varietyMarketIds: [8],
475
495
  commonOptionIds: [11],
@@ -266,7 +266,7 @@ defineExpose({
266
266
  const QIQUANKYES = ["expireDays", "virtualRealDegree", "yearProfitRate", "impliedVolatility", "levelMultiplier", "turnover", "volume", "openInterest", "optionsCpType", "optionGear"];
267
267
  // 1.常用指标-基本面(type:undefined的指标, 且[期权]的常用指标不计入基本面)
268
268
  const query = data.commonIndicator.reduce((result, item) => {
269
- const { key, type, range, unit, radioType, rankRange } = item;
269
+ const { key, type, range, unit, radioType, mainFlowRadioType, radio, rankRange } = item;
270
270
  // 排名模式
271
271
  if (radioType === "1") {
272
272
  params.sortBy = {
@@ -286,6 +286,12 @@ defineExpose({
286
286
  end,
287
287
  });
288
288
  }
289
+ // 主力净流入资金
290
+ else if (key === 'mainFlow') {
291
+ let [start, end] = rankRange;
292
+ let column = mainFlowRadioType === '0' ? `netInfow${radio}d` : `last${radio}DayMianFlowRank`
293
+ result.push({ column, start, end });
294
+ }
289
295
  // 其它基本面指标
290
296
  else if (type === undefined && !QIQUANKYES.includes(key)) {
291
297
  let [start, end] = range;
@@ -402,6 +408,14 @@ defineExpose({
402
408
  break;
403
409
  }
404
410
  });
411
+ // 7.常用指标-成交量
412
+ const perVolumnIndicator = data.commonIndicator.find(({ key }) => key === "perVolumn");
413
+ if (perVolumnIndicator) {
414
+ params.perVolumn = {
415
+ type: perVolumnIndicator.radio,
416
+ value: perVolumnIndicator.levels,
417
+ };
418
+ }
405
419
  if (Object.keys(searchOptionDto).length) {
406
420
  params.searchOptionDto = {
407
421
  ...params.searchOptionDto,
@@ -1,12 +1,12 @@
1
- <template>
2
- <div>
3
- PasswordPrompt
4
- </div>
5
- </template>
6
-
7
- <script setup lang="ts">
8
- </script>
9
-
10
- <style lang="scss" scoped>
11
-
12
- </style>
1
+ <template>
2
+ <div>
3
+ PasswordPrompt
4
+ </div>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+ </script>
9
+
10
+ <style lang="scss" scoped>
11
+
12
+ </style>
@@ -1 +0,0 @@
1
- "use strict";require("./base-0ca7c43a.cjs");const e=require("vue"),f=require("./index-afc88a4b.cjs"),h=require("./_plugin-vue_export-helper-f246444f.cjs");const g={key:0,class:"rule-box"},x={key:0,class:"level-box"},V={class:"level-color"},C={class:"level-text"},w={__name:"index",props:{value:{type:String,default:""},isFocus:{type:Boolean,default:!1},textColor:{type:[String,null],default:null}},setup(n,{expose:m}){const v=n,u=[{text:"不能包含空格",validator:t=>!/\s/.test(t)},{text:"长度为8-18个字符",validator:t=>t.length>=8&&t.length<=18},{text:"必须包含字母、数字、符号中至少2种",validator:t=>{const l=/[a-zA-Z]/.test(t),o=/\d/.test(t),r=/[^a-zA-Z0-9]/.test(t);return[l,o,r].filter(Boolean).length>=2}},{text:"请勿输入连续、重复6位以上字母或数字, 0123456, 1111111",validator:t=>{if(/([a-zA-Z0-9])\1{6,}/.test(t)||/(?:0123456|1234567|2345678|3456789|9876543|8765432|7654321|6543210)/.test(t))return!1;const r=t.toLowerCase(),d=s=>{if(!/^[a-z]+$/.test(s))return!1;for(let a=1;a<s.length;a++)if(s.charCodeAt(a)!==s.charCodeAt(a-1)+1)return!1;return!0};for(let s=0;s<=r.length-7;s++){const a=r.substr(s,7);if(d(a))return!1}return!0}}],p=e.computed(()=>!u.map(l=>l.validator(v.value)).includes(!1)),c=e.computed(()=>{const t=v.value;if(!t)return 0;let l=0;return t.length>=8&&l++,t.length>=12&&l++,/\d/.test(t)&&l++,/[a-z]/.test(t)&&l++,/[A-Z]/.test(t)&&l++,/[^a-zA-Z0-9]/.test(t)&&l++,l<=2?1:l<=4?2:3}),i=e.computed(()=>{switch(c.value){case 1:return"lv1";case 2:return"lv2";case 3:return"lv3";default:return""}}),_=e.computed(()=>{switch(c.value){case 1:return"弱";case 2:return"中";case 3:return"强";default:return""}});return m({pwdValidators:u,ruleFormPassword:[{required:!0,trigger:"blur",message:"密码不能为空"},...u.map(t=>({trigger:"blur",validator:(l,o,r)=>{t.validator(o)?r():r(t.text)}}))]}),(t,l)=>{const o=f.ElIcon;return e.openBlock(),e.createElementBlock("div",{class:"password-prompt",style:e.normalizeStyle({color:n.textColor??"var(--el-color-info)"})},[e.createVNode(e.Transition,{name:"slide-down"},{default:e.withCtx(()=>[n.isFocus?(e.openBlock(),e.createElementBlock("div",g,[(e.openBlock(),e.createElementBlock(e.Fragment,null,e.renderList(u,(r,d)=>e.createElementVNode("div",{class:"rule-item",key:d},[e.withDirectives(e.createVNode(o,null,{default:e.withCtx(()=>[e.createVNode(e.unref(f.circle_check_default))]),_:2},1536),[[e.vShow,r.validator(n.value)]]),e.createElementVNode("span",null,e.toDisplayString(r.text),1)])),64))])):e.createCommentVNode("",!0)]),_:1}),!n.isFocus&&p.value?(e.openBlock(),e.createElementBlock("div",x,[e.createElementVNode("div",V,[e.createElementVNode("div",{class:e.normalizeClass(["levelValue-block",[c.value>=1?i.value:""]])},null,2),e.createElementVNode("div",{class:e.normalizeClass(["levelValue-block",[c.value>=2?i.value:""]])},null,2),e.createElementVNode("div",{class:e.normalizeClass(["levelValue-block",[c.value>=3?i.value:""]])},null,2)]),e.createElementVNode("div",C,"密码强度: "+e.toDisplayString(_.value),1)])):e.createCommentVNode("",!0)],4)}}},N=h._export_sfc(w,[["__scopeId","data-v-b9fee9dd"]]);exports.PasswordPrompt=N;