st-comp 0.0.270 → 0.0.272

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.
@@ -1,9 +1,8 @@
1
1
  <script setup>
2
- import axios from "axios";
3
2
  import { inject, ref, onMounted, computed, watch } from "vue";
4
3
  import { getAlarDict, getAlarFreq, getAlarFactor } from "./api.js";
5
4
 
6
- const { request } = inject("stConfig"); // 组件库全局配置
5
+ const { request } = inject("stConfig");
7
6
 
8
7
  const searchData = ref({});
9
8
 
@@ -33,6 +32,9 @@ const multipleTableRef = ref();
33
32
  const orderByInfo = ref({ code: "asc" });
34
33
  const sortable = ref("tableHeader");
35
34
 
35
+ // 侧面板开关
36
+ const drawerVisible = ref(false);
37
+
36
38
  // 前端筛选条件格式化成API接口入参
37
39
  const apiParams = computed(() => {
38
40
  return { ...(varietySearchRef.value?.formatData(varietySearchData.value) ?? {}) };
@@ -45,41 +47,27 @@ const getTableData = async () => {
45
47
  pageNum: 1,
46
48
  pageSize: 20,
47
49
  };
48
- /**
49
- * @description: 根据用户最后一次操作交互的时机, 决定排序使用哪个维度
50
- * 常规排序字段: orderByInfo
51
- * 表头的orderByInfo和预警组的orderByInfo为顺序互斥, 谁最后操作就用谁
52
- *
53
- * 组合排序字段: compositeOrder
54
- * 表头的orderByInfo与compositeOrder为顺序互斥, 谁最后操作就用谁
55
- * 预警组的orderByInfo与compositeOrder为强制互斥, compositeOrder有值就一定优先使用compositeOrder
56
- */
57
50
  switch (sortable.value) {
58
51
  case "tableHeader": {
59
- delete params.compositeOrder; // 删除组合排序参数
60
- params.orderByInfo = orderByInfo.value; // 传入常规排序参数
52
+ delete params.compositeOrder;
53
+ params.orderByInfo = orderByInfo.value;
61
54
  break;
62
55
  }
63
56
  case "alarmGroup": {
64
- // 1. 如果存在组合排序, 那就直接使用组合排序
65
57
  if (params.compositeOrder && params.compositeOrder.length) {
66
58
  // 不进行额外处理
67
- }
68
- // 2. 如果不存在组合排序, 预警组选项存在
69
- else if (searchData.value.groupId) {
59
+ } else if (searchData.value.groupId) {
70
60
  orderByInfo.value = { orderByIndex: "asc" };
71
61
  params.orderByInfo = orderByInfo.value;
72
- }
73
- // 3. 如果不存在组合排序, 预警组选项也不存在, 就传递常规排序初始值
74
- else {
62
+ } else {
75
63
  orderByInfo.value = { code: "asc" };
76
64
  params.orderByInfo = orderByInfo.value;
77
- multipleTableRef.value.clearSort();
65
+ multipleTableRef.value?.clearSort();
78
66
  }
79
67
  break;
80
68
  }
81
69
  case "compositeOrder": {
82
- multipleTableRef.value.clearSort(); // 清除表头排序样式
70
+ multipleTableRef.value?.clearSort();
83
71
  break;
84
72
  }
85
73
  }
@@ -87,6 +75,7 @@ const getTableData = async () => {
87
75
  const { body } = await request.post("/common/qt/getFeatureInfosByPage", params);
88
76
  data.value = body.list;
89
77
  };
78
+
90
79
  // 表格: 排序
91
80
  const sortChange = ({ column, prop, order }) => {
92
81
  const sortValueMap = new Map([
@@ -99,7 +88,7 @@ const sortChange = ({ column, prop, order }) => {
99
88
  };
100
89
  } else {
101
90
  orderByInfo.value = {
102
- code: "asc", //默认值
91
+ code: "asc",
103
92
  };
104
93
  }
105
94
  sortable.value = "tableHeader";
@@ -108,16 +97,15 @@ const sortChange = ({ column, prop, order }) => {
108
97
 
109
98
  // 埋点
110
99
  const actionState = (...args) => {
111
- console.log(...args);
100
+ console.log("Demo页面埋点console, 实际项目埋点这里使用埋点函数", ...args);
112
101
  };
102
+
113
103
  // 品种池参数解析助手的回调
114
104
  const varietyAiHelperCallBack = (data) => {
115
105
  if (typeof data === "string") {
116
106
  return;
117
107
  } else {
118
- // 重置
119
- varietySearchRef.value.reset();
120
- // 参数合并
108
+ varietySearchRef.value?.reset();
121
109
  varietySearchData.value = { ...varietySearchData.value, ...data };
122
110
  }
123
111
  };
@@ -127,7 +115,6 @@ onMounted(async () => {
127
115
  const dicCycle = await getAlarFreq();
128
116
  const dicFactor = await getAlarFactor();
129
117
  varietySearchConfig.value = {
130
- // 品种市场 [选项: 接口获取 1000]
131
118
  varietyMarket: {
132
119
  show: true,
133
120
  options: dicAlar[1000].map((item) => {
@@ -139,7 +126,6 @@ onMounted(async () => {
139
126
  };
140
127
  }),
141
128
  },
142
- // 常用选项 [选项: 接口获取 1003]
143
129
  commonOption: {
144
130
  show: true,
145
131
  options: dicAlar[1003].map((item) => {
@@ -150,7 +136,6 @@ onMounted(async () => {
150
136
  };
151
137
  }),
152
138
  },
153
- // 上市板块 [选项: 接口获取 1030]
154
139
  marketIds: {
155
140
  show: true,
156
141
  options: dicAlar[1030].map((item) => {
@@ -160,15 +145,12 @@ onMounted(async () => {
160
145
  };
161
146
  }),
162
147
  },
163
- // 自定标签 [选项: 接口获取]
164
148
  customTag: {
165
149
  show: true,
166
150
  },
167
- // 价差转换 [选项: 前端默认]
168
151
  jcTranslate: {
169
152
  show: true,
170
153
  },
171
- // 因子筛选 [选项: 接口获取]
172
154
  factorScreen: {
173
155
  show: true,
174
156
  sqlShow: true,
@@ -181,19 +163,18 @@ onMounted(async () => {
181
163
  factorOptions: dicFactor,
182
164
  factorDescriptions: dicFactor,
183
165
  },
184
- // 常用指标 [选项: 组件默认]
185
166
  commonIndicator: {
186
167
  show: true,
187
168
  },
188
- // 组合排序 [选项: 组合默认]
189
169
  compositeOrder: {
190
170
  show: true,
191
171
  },
192
172
  };
193
173
  });
174
+
194
175
  watch(
195
176
  () => varietySearchData.value.compositeOrder,
196
- (newValue) => {
177
+ () => {
197
178
  sortable.value = "compositeOrder";
198
179
  },
199
180
  {
@@ -229,57 +210,258 @@ watch(
229
210
  :config="varietySearchConfig"
230
211
  @actionState="actionState"
231
212
  />
232
- <div>
233
- <div style="font-size: 14px; display: flex">
234
- <pre style="flex: 1">前端组件参数: {{ varietySearchData }}</pre>
235
- <pre style="flex: 0.5">后端接口参数: {{ apiParams }}</pre>
213
+ <el-table
214
+ ref="multipleTableRef"
215
+ size="small"
216
+ :stripe="true"
217
+ :border="true"
218
+ :data="data"
219
+ @sort-change="sortChange"
220
+ >
221
+ <el-table-column
222
+ type="selection"
223
+ width="40"
224
+ fixed
225
+ />
226
+ <el-table-column
227
+ label="编号"
228
+ prop="id"
229
+ width="80"
230
+ fixed
231
+ />
232
+ <el-table-column
233
+ label="代码"
234
+ prop="code"
235
+ width="90"
236
+ sortable="custom"
237
+ fixed
238
+ show-overflow-tooltip
239
+ />
240
+ <el-table-column
241
+ label="名称"
242
+ prop="featureName"
243
+ sortable="custom"
244
+ fixed
245
+ show-overflow-tooltip
246
+ />
247
+ <el-table-column
248
+ label="市场"
249
+ prop="exchangeName"
250
+ width="70"
251
+ />
252
+ </el-table>
253
+ </el-scrollbar>
254
+
255
+ <!-- 悬浮球 -->
256
+ <div
257
+ class="json-float-btn"
258
+ @click="drawerVisible = true"
259
+ >
260
+ <span class="json-float-icon">{ }</span>
261
+ </div>
262
+
263
+ <!-- ========================================== -->
264
+ <!-- 自定义侧面板(无遮罩,不阻塞事件) -->
265
+ <!-- ========================================== -->
266
+ <transition name="slide">
267
+ <div
268
+ v-if="drawerVisible"
269
+ class="custom-drawer-overlay"
270
+ @click.self="drawerVisible = false"
271
+ >
272
+ <div class="custom-drawer">
273
+ <!-- 标题栏 -->
274
+ <div class="custom-drawer-header">
275
+ <span class="custom-drawer-title">参数查看</span>
276
+ <span
277
+ class="custom-drawer-close"
278
+ @click="drawerVisible = false"
279
+ >✕</span
280
+ >
281
+ </div>
282
+ <!-- 内容 -->
283
+ <div class="custom-drawer-body">
284
+ <div class="json-section">
285
+ <div class="json-label">前端组件参数</div>
286
+ <pre class="json-content">{{ JSON.stringify(varietySearchData, null, 2) }}</pre>
287
+ </div>
288
+ <div class="json-section">
289
+ <div class="json-label">后端接口参数</div>
290
+ <pre class="json-content">{{ JSON.stringify(apiParams, null, 2) }}</pre>
291
+ </div>
292
+ </div>
236
293
  </div>
237
- <el-table
238
- ref="multipleTableRef"
239
- size="small"
240
- :stripe="true"
241
- :border="true"
242
- :data="data"
243
- @sort-change="sortChange"
244
- >
245
- <el-table-column
246
- type="selection"
247
- width="40"
248
- fixed
249
- />
250
- <el-table-column
251
- label="编号"
252
- prop="id"
253
- width="80"
254
- fixed
255
- />
256
- <el-table-column
257
- label="代码"
258
- prop="code"
259
- width="90"
260
- sortable="custom"
261
- fixed
262
- show-overflow-tooltip
263
- />
264
- <el-table-column
265
- label="名称"
266
- prop="featureName"
267
- sortable="custom"
268
- fixed
269
- show-overflow-tooltip
270
- />
271
- <el-table-column
272
- label="市场"
273
- prop="exchangeName"
274
- width="70"
275
- />
276
- </el-table>
277
294
  </div>
278
- </el-scrollbar>
295
+ </transition>
279
296
  </template>
280
297
 
281
298
  <style lang="scss" scoped>
282
299
  .el-table {
283
- height: calc(100vh - 420px);
300
+ margin-top: 10px;
301
+ height: calc(100vh - 460px);
302
+ }
303
+
304
+ // ==========================================
305
+ // 悬浮球
306
+ // ==========================================
307
+ .json-float-btn {
308
+ position: fixed;
309
+ bottom: 40px;
310
+ right: 40px;
311
+ width: 52px;
312
+ height: 52px;
313
+ border-radius: 50%;
314
+ background: #409eff;
315
+ color: #fff;
316
+ display: flex;
317
+ align-items: center;
318
+ justify-content: center;
319
+ cursor: pointer;
320
+ box-shadow: 0 4px 16px rgba(64, 158, 255, 0.4);
321
+ transition: all 0.25s ease;
322
+ z-index: 999;
323
+ user-select: none;
324
+
325
+ &:hover {
326
+ transform: scale(1.08);
327
+ box-shadow: 0 6px 24px rgba(64, 158, 255, 0.55);
328
+ }
329
+
330
+ &:active {
331
+ transform: scale(0.95);
332
+ }
333
+
334
+ .json-float-icon {
335
+ font-size: 20px;
336
+ font-weight: 700;
337
+ font-family: "Courier New", monospace;
338
+ }
339
+ }
340
+
341
+ // ==========================================
342
+ // 自定义侧面板(无遮罩,不阻塞页面操作)
343
+ // ==========================================
344
+ .custom-drawer-overlay {
345
+ position: fixed;
346
+ top: 0;
347
+ left: 0;
348
+ right: 0;
349
+ bottom: 0;
350
+ z-index: 1000;
351
+ pointer-events: none; // 关键:让所有点击穿透
352
+ }
353
+
354
+ .custom-drawer {
355
+ position: fixed;
356
+ top: 0;
357
+ right: 0;
358
+ width: 500px;
359
+ height: 100vh;
360
+ background: #ffffff;
361
+ box-shadow: -4px 0 20px rgba(0, 0, 0, 0.12);
362
+ z-index: 1001;
363
+ pointer-events: auto; // 抽屉本身可交互
364
+ display: flex;
365
+ flex-direction: column;
366
+
367
+ .custom-drawer-header {
368
+ display: flex;
369
+ align-items: center;
370
+ justify-content: space-between;
371
+ padding: 16px 20px;
372
+ border-bottom: 1px solid #e8ecf1;
373
+ flex-shrink: 0;
374
+
375
+ .custom-drawer-title {
376
+ font-size: 16px;
377
+ font-weight: 600;
378
+ color: #1d2129;
379
+ }
380
+
381
+ .custom-drawer-close {
382
+ font-size: 20px;
383
+ color: #86909c;
384
+ cursor: pointer;
385
+ padding: 0 4px;
386
+ transition: color 0.15s;
387
+ line-height: 1;
388
+
389
+ &:hover {
390
+ color: #1d2129;
391
+ }
392
+ }
393
+ }
394
+
395
+ .custom-drawer-body {
396
+ flex: 1;
397
+ padding: 16px 20px;
398
+ overflow: hidden;
399
+ display: flex;
400
+ flex-direction: column;
401
+ gap: 16px;
402
+ }
403
+ }
404
+
405
+ // ==========================================
406
+ // 滑动动画
407
+ // ==========================================
408
+ .slide-enter-active,
409
+ .slide-leave-active {
410
+ transition: all 0.25s ease;
411
+ }
412
+
413
+ .slide-enter-from {
414
+ transform: translateX(100%);
415
+ opacity: 0;
416
+ }
417
+
418
+ .slide-enter-to {
419
+ transform: translateX(0);
420
+ opacity: 1;
421
+ }
422
+
423
+ .slide-leave-from {
424
+ transform: translateX(0);
425
+ opacity: 1;
426
+ }
427
+
428
+ .slide-leave-to {
429
+ transform: translateX(100%);
430
+ opacity: 0;
431
+ }
432
+
433
+ // ==========================================
434
+ // JSON 展示样式
435
+ // ==========================================
436
+ .json-section {
437
+ flex: 1;
438
+ display: flex;
439
+ flex-direction: column;
440
+ min-height: 0;
441
+
442
+ .json-label {
443
+ font-size: 16px;
444
+ font-weight: 500;
445
+ color: #4e5969;
446
+ margin-bottom: 6px;
447
+ flex-shrink: 0;
448
+ }
449
+
450
+ .json-content {
451
+ flex: 1;
452
+ margin: 0;
453
+ padding: 12px 16px;
454
+ background: #1a1a2e;
455
+ border-radius: 6px;
456
+ font-size: 14px;
457
+ line-height: 1.7;
458
+ font-family: "Consolas", "Monaco", "Courier New", monospace;
459
+ color: white;
460
+ overflow: auto;
461
+ white-space: pre-wrap;
462
+ word-break: break-all;
463
+ min-height: 150px;
464
+ max-height: 300px;
465
+ }
284
466
  }
285
467
  </style>
@@ -1,4 +0,0 @@
1
- "use strict";const x=(g,c)=>{var u;const h=g.split(`
2
- `);let e=null;for(const t of h){if(t.startsWith("event:")){e=t.substring(6).trim();continue}if(t.startsWith("data:")){const r=t.substring(5).trim();if(r&&r!=="[DONE]")try{const s=JSON.parse(r);if(e==="error"||s.code||s.message){const o=s.message||s.code||"未知错误";c("error",`百炼服务端错误: ${o}`);return}const n=(u=s==null?void 0:s.output)==null?void 0:u.text;n&&c&&c("message",n)}catch{}e=null}}},w=async({appId:g,apiKey:c,value:h,callback:e})=>{var u;try{const t=await fetch(`https://dashscope.aliyuncs.com/api/v1/apps/${g}/completion`,{method:"POST",body:JSON.stringify({input:{prompt:h},parameters:{incremental_output:"true"},debug:{}}),headers:{Authorization:`Bearer ${c}`,"Content-Type":"application/json","X-DashScope-SSE":"enable"}});if(!t.ok){e("error",`HTTP ${t.status}: ${t.statusText}`);return}const r=t.body.getReader(),s=new TextDecoder;let n="",o=null;for(;;){const{done:f,value:S}=await r.read();if(f){n.trim()&&x(n,e),e("finish","");break}n+=s.decode(S,{stream:!0});let y;for(;(y=n.indexOf(`
3
- `))!==-1;){const p=n.substring(0,y).trim();if(n=n.substring(y+1),p.startsWith("event:")){o=p.substring(6).trim();continue}if(p.startsWith("data:")){const d=p.substring(5).trim();if(o==="error"||d&&d.startsWith("{"))try{const a=JSON.parse(d);if(a.code||a.message||o==="error"){const i=a.message||a.code||"未知错误";e("error",`百炼服务端错误: ${i}`);return}const m=(u=a==null?void 0:a.output)==null?void 0:u.text;m&&e&&e("message",m)}catch{console.debug("JSON 解析失败:",d)}o=null}}}}catch(t){console.error("流式请求失败:",t),e("error",t.message)}},N=async({baseUrl:g,token:c,value:h,callback:e})=>{var u,t;try{const r=await fetch(`${g}/middleLayer/ai/varietyAiHelper`,{method:"POST",headers:{"Content-Type":"application/json",token:c},body:JSON.stringify({query:h,origin:"web",stream:!0})});if(!r.ok){e("error",`HTTP ${r.status}: ${r.statusText}`);return}const s=r.body.getReader(),n=new TextDecoder;let o="",f="";const S={};for(;;){const{done:y,value:p}=await s.read();if(y){f&&e("message",f),e("finish","");break}o+=n.decode(p,{stream:!0});let d;for(;(d=o.indexOf(`
4
- `))!==-1;){const a=o.substring(0,d).trim();if(o=o.substring(d+1),a.startsWith("data: ")){const m=a.substring(6).trim();if(!m||m==="[DONE]")continue;try{const i=JSON.parse(m);if(i.node_name&&i.node_status){const T=i.node_name,l=i.node_status==="success"?"success":"executing";S[T]!==l&&(S[T]=l,e("node",{name:T,status:l}))}if(((u=i.output)==null?void 0:u.finish_reason)==="stop"&&((t=i.output)!=null&&t.text)&&(f=i.output.text,e("message",f)),i.error){e("error",i.error);return}}catch{}}}}}catch(r){console.error("Node服务请求失败:",r),e("error",r.message)}};exports.sendToBaiLianAppStreaming=w;exports.sendToNodeVarietyAiHelper=N;
@@ -1,149 +0,0 @@
1
- const T = (g, c) => {
2
- var u;
3
- const h = g.split(`
4
- `);
5
- let e = null;
6
- for (const t of h) {
7
- if (t.startsWith("event:")) {
8
- e = t.substring(6).trim();
9
- continue;
10
- }
11
- if (t.startsWith("data:")) {
12
- const r = t.substring(5).trim();
13
- if (r && r !== "[DONE]")
14
- try {
15
- const s = JSON.parse(r);
16
- if (e === "error" || s.code || s.message) {
17
- const o = s.message || s.code || "未知错误";
18
- c("error", `百炼服务端错误: ${o}`);
19
- return;
20
- }
21
- const n = (u = s == null ? void 0 : s.output) == null ? void 0 : u.text;
22
- n && c && c("message", n);
23
- } catch {
24
- }
25
- e = null;
26
- }
27
- }
28
- }, w = async ({ appId: g, apiKey: c, value: h, callback: e }) => {
29
- var u;
30
- try {
31
- const t = await fetch(`https://dashscope.aliyuncs.com/api/v1/apps/${g}/completion`, {
32
- method: "POST",
33
- body: JSON.stringify({
34
- input: { prompt: h },
35
- parameters: { incremental_output: "true" },
36
- debug: {}
37
- }),
38
- headers: {
39
- Authorization: `Bearer ${c}`,
40
- "Content-Type": "application/json",
41
- "X-DashScope-SSE": "enable"
42
- }
43
- });
44
- if (!t.ok) {
45
- e("error", `HTTP ${t.status}: ${t.statusText}`);
46
- return;
47
- }
48
- const r = t.body.getReader(), s = new TextDecoder();
49
- let n = "", o = null;
50
- for (; ; ) {
51
- const { done: f, value: x } = await r.read();
52
- if (f) {
53
- n.trim() && T(n, e), e("finish", "");
54
- break;
55
- }
56
- n += s.decode(x, { stream: !0 });
57
- let y;
58
- for (; (y = n.indexOf(`
59
- `)) !== -1; ) {
60
- const m = n.substring(0, y).trim();
61
- if (n = n.substring(y + 1), m.startsWith("event:")) {
62
- o = m.substring(6).trim();
63
- continue;
64
- }
65
- if (m.startsWith("data:")) {
66
- const d = m.substring(5).trim();
67
- if (o === "error" || d && d.startsWith("{"))
68
- try {
69
- const a = JSON.parse(d);
70
- if (a.code || a.message || o === "error") {
71
- const i = a.message || a.code || "未知错误";
72
- e("error", `百炼服务端错误: ${i}`);
73
- return;
74
- }
75
- const p = (u = a == null ? void 0 : a.output) == null ? void 0 : u.text;
76
- p && e && e("message", p);
77
- } catch {
78
- console.debug("JSON 解析失败:", d);
79
- }
80
- o = null;
81
- }
82
- }
83
- }
84
- } catch (t) {
85
- console.error("流式请求失败:", t), e("error", t.message);
86
- }
87
- }, O = async ({ baseUrl: g, token: c, value: h, callback: e }) => {
88
- var u, t;
89
- try {
90
- const r = await fetch(`${g}/middleLayer/ai/varietyAiHelper`, {
91
- method: "POST",
92
- headers: {
93
- "Content-Type": "application/json",
94
- token: c
95
- },
96
- body: JSON.stringify({
97
- query: h,
98
- origin: "web",
99
- stream: !0
100
- })
101
- });
102
- if (!r.ok) {
103
- e("error", `HTTP ${r.status}: ${r.statusText}`);
104
- return;
105
- }
106
- const s = r.body.getReader(), n = new TextDecoder();
107
- let o = "", f = "";
108
- const x = {};
109
- for (; ; ) {
110
- const { done: y, value: m } = await s.read();
111
- if (y) {
112
- f && e("message", f), e("finish", "");
113
- break;
114
- }
115
- o += n.decode(m, { stream: !0 });
116
- let d;
117
- for (; (d = o.indexOf(`
118
- `)) !== -1; ) {
119
- const a = o.substring(0, d).trim();
120
- if (o = o.substring(d + 1), a.startsWith("data: ")) {
121
- const p = a.substring(6).trim();
122
- if (!p || p === "[DONE]")
123
- continue;
124
- try {
125
- const i = JSON.parse(p);
126
- if (i.node_name && i.node_status) {
127
- const S = i.node_name, l = i.node_status === "success" ? "success" : "executing";
128
- x[S] !== l && (x[S] = l, e("node", {
129
- name: S,
130
- status: l
131
- }));
132
- }
133
- if (((u = i.output) == null ? void 0 : u.finish_reason) === "stop" && ((t = i.output) != null && t.text) && (f = i.output.text, e("message", f)), i.error) {
134
- e("error", i.error);
135
- return;
136
- }
137
- } catch {
138
- }
139
- }
140
- }
141
- }
142
- } catch (r) {
143
- console.error("Node服务请求失败:", r), e("error", r.message);
144
- }
145
- };
146
- export {
147
- w as a,
148
- O as s
149
- };