Commit 828a7a79e928cd160e45e441efdb8ffe579e188c

Authored by xp.Huang
2 parents 96fc3929 11aabd82

Merge branch 'ft' into 'main_dev'

feat: 公共接口管理新增自定义脚本,和优化公共接口管理部分代码

See merge request yunteng/thingskit-front!593
Showing 20 changed files with 667 additions and 3561 deletions

Too many changes to show.

To preserve performance only 20 of 28 files are displayed.

  1 +@table-color: #e5e7eb;
  2 +
  3 +.table-border-color {
  4 + border: 1px solid #e5e7eb;
  5 + text-align: center;
  6 +}
  7 +
  8 +.table-content {
  9 + overflow-x: auto;
  10 +
  11 + table {
  12 + border-collapse: collapse;
  13 + width: 35vw;
  14 + &:extend(.table-border-color);
  15 + }
  16 +
  17 + table thead {
  18 + white-space: nowrap;
  19 + }
  20 +
  21 + table td {
  22 + padding: 5px;
  23 + white-space: nowrap;
  24 + &:extend(.table-border-color);
  25 + }
  26 +
  27 + table th {
  28 + padding: 5px;
  29 + &:extend(.table-border-color);
  30 + }
  31 +}
... ...
  1 +@table-color: #e5e7eb;
  2 +
  3 +.table-border-color {
  4 + border: 1px solid #e5e7eb;
  5 + text-align: center;
  6 +}
  7 +
  8 +.table-content {
  9 + table {
  10 + width: 31vw;
  11 + &:extend(.table-border-color);
  12 + }
  13 +
  14 + table td {
  15 + padding: 5px;
  16 + white-space: nowrap;
  17 + &:extend(.table-border-color);
  18 + }
  19 +
  20 + table th {
  21 + padding: 5px;
  22 + &:extend(.table-border-color);
  23 + }
  24 +}
... ...
1   -import type { BasicColumn } from '/@/components/Table';
2   -import type { FormSchema } from '/@/components/Table';
3   -import { getOrganizationList } from '/@/api/system/system';
4   -import { copyTransFun } from '/@/utils/fnUtils';
5   -import { getDeviceDataKeys, getDeviceProfile } from '/@/api/alarm/position';
6   -import { EChartsOption } from 'echarts';
7   -
8   -export enum AggregateDataEnum {
9   - MIN = 'MIN',
10   - MAX = 'MAX',
11   - AVG = 'AVG',
12   - SUM = 'SUM',
13   - COUNT = 'COUNT',
14   - NONE = 'NONE',
15   -}
16   -export const formSchema: FormSchema[] = [
17   - {
18   - field: 'organizationId',
19   - label: '',
20   - component: 'ApiTreeSelect',
21   - componentProps: {
22   - placeholder: '请选择组织',
23   - api: async () => {
24   - const data = await getOrganizationList();
25   - copyTransFun(data as any as any[]);
26   - return data;
27   - },
28   - },
29   - },
30   - {
31   - field: 'deviceProfileId',
32   - label: '',
33   - component: 'ApiSelect',
34   - componentProps: {
35   - api: getDeviceProfile,
36   - placeholder: '请选择产品',
37   - labelField: 'name',
38   - valueField: 'tbProfileId',
39   - },
40   - },
41   - {
42   - field: 'name',
43   - label: '',
44   - component: 'Input',
45   - componentProps: {
46   - maxLength: 255,
47   - placeholder: '请输入设备名称',
48   - },
49   - },
50   - {
51   - field: 'deviceState',
52   - label: '',
53   - component: 'RadioGroup',
54   - componentProps: {
55   - size: 'small',
56   - options: [
57   - { label: '全部', value: null },
58   - { label: '待激活', value: 'INACTIVE' },
59   - { label: '在线', value: 'ONLINE' },
60   - { label: '离线', value: 'OFFLINE' },
61   - ],
62   - },
63   - },
64   - {
65   - field: 'alarmStatus',
66   - label: '是否告警',
67   - component: 'RadioGroup',
68   - labelWidth: '85px',
69   - componentProps: {
70   - size: 'small',
71   - options: [
72   - { label: '是', value: 1 },
73   - { label: '否', value: 0 },
74   - ],
75   - },
76   - },
77   -];
78   -
79   -export const columns: BasicColumn[] = [
80   - {
81   - title: '名称',
82   - dataIndex: 'name',
83   - width: 120,
84   - format: (_text: string, record: Recordable) => {
85   - return record?.alias || record?.name;
86   - },
87   - },
88   - {
89   - title: '设备状态',
90   - dataIndex: 'deviceState',
91   - width: 80,
92   - slots: { customRender: 'deviceState' },
93   - },
94   - {
95   - title: '位置',
96   - dataIndex: 'deviceInfo.address',
97   - width: 120,
98   - },
99   - {
100   - title: '告警状态',
101   - dataIndex: 'alarmStatus',
102   - width: 80,
103   - slots: { customRender: 'alarmStatus' },
104   - },
105   -];
106   -
107   -// 动态生成options
108   -function generateOptions(value: number) {
109   - if (value === 3600000) {
110   - return [
111   - {
112   - label: '10秒',
113   - value: 10000,
114   - },
115   - {
116   - label: '15秒',
117   - value: 15000,
118   - },
119   - {
120   - label: '30秒',
121   - value: 30000,
122   - },
123   - {
124   - label: '1分钟',
125   - value: 60000,
126   - },
127   - {
128   - label: '2分钟',
129   - value: 120000,
130   - },
131   - {
132   - label: '5分钟',
133   - value: 300000,
134   - },
135   - ];
136   - } else if (value === 7200000) {
137   - return [
138   - {
139   - label: '15秒',
140   - value: 15000,
141   - },
142   - {
143   - label: '30秒',
144   - value: 30000,
145   - },
146   - {
147   - label: '1分钟',
148   - value: 60000,
149   - },
150   - {
151   - label: '2分钟',
152   - value: 120000,
153   - },
154   - {
155   - label: '5分钟',
156   - value: 300000,
157   - },
158   - {
159   - label: '10分钟',
160   - value: 600000,
161   - },
162   - {
163   - label: '15分钟',
164   - value: 900000,
165   - },
166   - ];
167   - } else if (value === 18000000) {
168   - return [
169   - {
170   - label: '1分钟',
171   - value: 60000,
172   - },
173   - {
174   - label: '2分钟',
175   - value: 120000,
176   - },
177   - {
178   - label: '5分钟',
179   - value: 300000,
180   - },
181   - {
182   - label: '10分钟',
183   - value: 600000,
184   - },
185   - {
186   - label: '15分钟',
187   - value: 900000,
188   - },
189   - {
190   - label: '30分钟',
191   - value: 1800000,
192   - },
193   - ];
194   - } else if (value === 36000000) {
195   - return [
196   - {
197   - label: '2分钟',
198   - value: 120000,
199   - },
200   - {
201   - label: '5分钟',
202   - value: 300000,
203   - },
204   - {
205   - label: '10分钟',
206   - value: 600000,
207   - },
208   - {
209   - label: '15分钟',
210   - value: 900000,
211   - },
212   - {
213   - label: '30分钟',
214   - value: 1800000,
215   - },
216   - {
217   - label: '1小时',
218   - value: 3600000,
219   - },
220   - ];
221   - } else if (value === 43200000) {
222   - return [
223   - {
224   - label: '2分钟',
225   - value: 120000,
226   - },
227   - {
228   - label: '5分钟',
229   - value: 300000,
230   - },
231   - {
232   - label: '10分钟',
233   - value: 600000,
234   - },
235   - {
236   - label: '15分钟',
237   - value: 900000,
238   - },
239   - {
240   - label: '30分钟',
241   - value: 1800000,
242   - },
243   - {
244   - label: '1小时',
245   - value: 3600000,
246   - },
247   - ];
248   - } else if (value === 86400000) {
249   - return [
250   - {
251   - label: '5分钟',
252   - value: 300000,
253   - },
254   - {
255   - label: '10分钟',
256   - value: 600000,
257   - },
258   - {
259   - label: '15分钟',
260   - value: 900000,
261   - },
262   - {
263   - label: '30分钟',
264   - value: 1800000,
265   - },
266   - {
267   - label: '1小时',
268   - value: 3600000,
269   - },
270   - {
271   - label: '2小时',
272   - value: 7200000,
273   - },
274   - ];
275   - } else if (value === 604800000) {
276   - return [
277   - {
278   - label: '30分钟',
279   - value: 1800000,
280   - },
281   - {
282   - label: '1小时',
283   - value: 3600000,
284   - },
285   - {
286   - label: '2小时',
287   - value: 7200000,
288   - },
289   - {
290   - label: '5小时',
291   - value: 18000000,
292   - },
293   - {
294   - label: '10小时',
295   - value: 36000000,
296   - },
297   - {
298   - label: '12小时',
299   - value: 43200000,
300   - },
301   - {
302   - label: '1天',
303   - value: 86400000,
304   - },
305   - ];
306   - } else {
307   - return [
308   - {
309   - label: '2小时',
310   - value: 7200000,
311   - },
312   - {
313   - label: '5小时',
314   - value: 18000000,
315   - },
316   - {
317   - label: '10小时',
318   - value: 36000000,
319   - },
320   - {
321   - label: '12小时',
322   - value: 43200000,
323   - },
324   - {
325   - label: '1天',
326   - value: 86400000,
327   - },
328   - ];
329   - }
330   -}
331   -export const schemas: FormSchema[] = [
332   - {
333   - field: 'endTs',
334   - label: '最后数据',
335   - component: 'Select',
336   - required: true,
337   - componentProps({ formModel, formActionType }) {
338   - return {
339   - onChange(value) {
340   - const { updateSchema } = formActionType;
341   - console.log(value);
342   - formModel.interval = '';
343   - updateSchema({
344   - field: 'interval',
345   - componentProps: {
346   - placeholder: '请选择分组间隔',
347   - options: generateOptions(value),
348   - },
349   - });
350   - },
351   - getPopupContainer: () => document.body,
352   - options: [
353   - {
354   - label: '最近1小时',
355   - value: 3600000,
356   - },
357   - {
358   - label: '最近2小时',
359   - value: 7200000,
360   - },
361   - {
362   - label: '最近5小时',
363   - value: 18000000,
364   - },
365   - {
366   - label: '最近10小时',
367   - value: 36000000,
368   - },
369   - {
370   - label: '最近12小时',
371   - value: 43200000,
372   - },
373   - {
374   - label: '最近1天',
375   - value: 86400000,
376   - },
377   - {
378   - label: '最近7天',
379   - value: 604800000,
380   - },
381   - {
382   - label: '最近30天',
383   - value: 2592000000,
384   - },
385   - ],
386   - };
387   - },
388   - },
389   - {
390   - field: 'interval',
391   - label: '分组间隔',
392   - component: 'Select',
393   - componentProps: {
394   - placeholder: '请选择分组间隔',
395   - getPopupContainer: () => document.body,
396   - options: [
397   - {
398   - label: '5分钟',
399   - value: 300000,
400   - },
401   - {
402   - label: '10分钟',
403   - value: 600000,
404   - },
405   - {
406   - label: '15分钟',
407   - value: 900000,
408   - },
409   - {
410   - label: '30分钟',
411   - value: 1800000,
412   - },
413   - {
414   - label: '1小时',
415   - value: 3600000,
416   - },
417   - {
418   - label: '2小时',
419   - value: 7200000,
420   - },
421   - ],
422   - },
423   - },
424   - {
425   - field: 'agg',
426   - label: '数据聚合功能',
427   - component: 'Select',
428   - defaultValue: AggregateDataEnum.NONE,
429   - componentProps: {
430   - getPopupContainer: () => document.body,
431   - options: [
432   - {
433   - label: '最小值',
434   - value: AggregateDataEnum.MIN,
435   - },
436   - {
437   - label: '最大值',
438   - value: AggregateDataEnum.MAX,
439   - },
440   - {
441   - label: '平均值',
442   - value: AggregateDataEnum.AVG,
443   - },
444   - {
445   - label: '求和',
446   - value: AggregateDataEnum.SUM,
447   - },
448   - {
449   - label: '计数',
450   - value: AggregateDataEnum.COUNT,
451   - },
452   - {
453   - label: '空',
454   - value: AggregateDataEnum.NONE,
455   - },
456   - ],
457   - },
458   - },
459   - {
460   - field: 'attr',
461   - label: '设备属性',
462   - component: 'Select',
463   - componentProps: {
464   - api: async (id: string) => {
465   - try {
466   - const res = await getDeviceDataKeys(id);
467   - return res.map((item) => ({ label: item, value: item }));
468   - } catch (error) {}
469   - },
470   - },
471   - },
472   -];
473   -
474   -export const selectDeviceAttrSchema: FormSchema[] = [
475   - {
476   - field: 'keys',
477   - label: '设备属性',
478   - component: 'Select',
479   - componentProps: {
480   - getPopupContainer: () => document.body,
481   - },
482   - },
483   -];
484   -
485   -export const eChartOptions = (series: EChartsOption['series'], keys: string[]): EChartsOption => {
486   - return {
487   - tooltip: {
488   - trigger: 'axis',
489   - },
490   - legend: {
491   - data: keys,
492   - },
493   - grid: {
494   - left: '3%',
495   - right: '4%',
496   - bottom: '3%',
497   - containLabel: true,
498   - },
499   - dataZoom: [
500   - {
501   - type: 'inside',
502   - start: 0,
503   - end: 50,
504   - },
505   - {
506   - start: 20,
507   - end: 40,
508   - },
509   - ],
510   - xAxis: {
511   - type: 'time',
512   - boundaryGap: false,
513   - },
514   - yAxis: {
515   - type: 'value',
516   - boundaryGap: [0, '100%'],
517   - },
518   - series,
519   - };
520   -};
521   -
522   -//百度地图设置个性化地图配置
523   -export const setMapStyleV2 = {
524   - styleJson: [
525   - {
526   - featureType: 'land',
527   - elementType: 'geometry',
528   - stylers: {
529   - visibility: 'on',
530   - color: '#091220ff',
531   - },
532   - },
533   - {
534   - featureType: 'water',
535   - elementType: 'geometry',
536   - stylers: {
537   - visibility: 'on',
538   - color: '#113549ff',
539   - },
540   - },
541   - {
542   - featureType: 'green',
543   - elementType: 'geometry',
544   - stylers: {
545   - visibility: 'on',
546   - color: '#0e1b30ff',
547   - },
548   - },
549   - {
550   - featureType: 'building',
551   - elementType: 'geometry',
552   - stylers: {
553   - visibility: 'on',
554   - },
555   - },
556   - {
557   - featureType: 'building',
558   - elementType: 'geometry.topfill',
559   - stylers: {
560   - color: '#113549ff',
561   - },
562   - },
563   - {
564   - featureType: 'building',
565   - elementType: 'geometry.sidefill',
566   - stylers: {
567   - color: '#143e56ff',
568   - },
569   - },
570   - {
571   - featureType: 'building',
572   - elementType: 'geometry.stroke',
573   - stylers: {
574   - color: '#dadada00',
575   - },
576   - },
577   - {
578   - featureType: 'subwaystation',
579   - elementType: 'geometry',
580   - stylers: {
581   - visibility: 'on',
582   - color: '#113549B2',
583   - },
584   - },
585   - {
586   - featureType: 'education',
587   - elementType: 'geometry',
588   - stylers: {
589   - visibility: 'on',
590   - color: '#12223dff',
591   - },
592   - },
593   - {
594   - featureType: 'medical',
595   - elementType: 'geometry',
596   - stylers: {
597   - visibility: 'on',
598   - color: '#12223dff',
599   - },
600   - },
601   - {
602   - featureType: 'scenicspots',
603   - elementType: 'geometry',
604   - stylers: {
605   - visibility: 'on',
606   - color: '#12223dff',
607   - },
608   - },
609   - {
610   - featureType: 'highway',
611   - elementType: 'geometry',
612   - stylers: {
613   - visibility: 'on',
614   - weight: 4,
615   - },
616   - },
617   - {
618   - featureType: 'highway',
619   - elementType: 'geometry.fill',
620   - stylers: {
621   - color: '#12223dff',
622   - },
623   - },
624   - {
625   - featureType: 'highway',
626   - elementType: 'geometry.stroke',
627   - stylers: {
628   - color: '#fed66900',
629   - },
630   - },
631   - {
632   - featureType: 'highway',
633   - elementType: 'labels',
634   - stylers: {
635   - visibility: 'on',
636   - },
637   - },
638   - {
639   - featureType: 'highway',
640   - elementType: 'labels.text.fill',
641   - stylers: {
642   - color: '#12223dff',
643   - },
644   - },
645   - {
646   - featureType: 'highway',
647   - elementType: 'labels.text.stroke',
648   - stylers: {
649   - color: '#ffffff00',
650   - },
651   - },
652   - {
653   - featureType: 'highway',
654   - elementType: 'labels.icon',
655   - stylers: {
656   - visibility: 'on',
657   - },
658   - },
659   - {
660   - featureType: 'arterial',
661   - elementType: 'geometry',
662   - stylers: {
663   - visibility: 'on',
664   - weight: 2,
665   - },
666   - },
667   - {
668   - featureType: 'arterial',
669   - elementType: 'geometry.fill',
670   - stylers: {
671   - color: '#12223dff',
672   - },
673   - },
674   - {
675   - featureType: 'arterial',
676   - elementType: 'geometry.stroke',
677   - stylers: {
678   - color: '#ffeebb00',
679   - },
680   - },
681   - {
682   - featureType: 'arterial',
683   - elementType: 'labels',
684   - stylers: {
685   - visibility: 'on',
686   - },
687   - },
688   - {
689   - featureType: 'arterial',
690   - elementType: 'labels.text.fill',
691   - stylers: {
692   - color: '#2dc4bbff',
693   - },
694   - },
695   - {
696   - featureType: 'arterial',
697   - elementType: 'labels.text.stroke',
698   - stylers: {
699   - color: '#ffffff00',
700   - },
701   - },
702   - {
703   - featureType: 'local',
704   - elementType: 'geometry',
705   - stylers: {
706   - visibility: 'on',
707   - weight: 1,
708   - },
709   - },
710   - {
711   - featureType: 'local',
712   - elementType: 'geometry.fill',
713   - stylers: {
714   - color: '#12223dff',
715   - },
716   - },
717   - {
718   - featureType: 'local',
719   - elementType: 'geometry.stroke',
720   - stylers: {
721   - color: '#ffffff00',
722   - },
723   - },
724   - {
725   - featureType: 'local',
726   - elementType: 'labels',
727   - stylers: {
728   - visibility: 'on',
729   - },
730   - },
731   - {
732   - featureType: 'local',
733   - elementType: 'labels.text.fill',
734   - stylers: {
735   - color: '#979c9aff',
736   - },
737   - },
738   - {
739   - featureType: 'local',
740   - elementType: 'labels.text.stroke',
741   - stylers: {
742   - color: '#ffffffff',
743   - },
744   - },
745   - {
746   - featureType: 'railway',
747   - elementType: 'geometry',
748   - stylers: {
749   - visibility: 'off',
750   - },
751   - },
752   - {
753   - featureType: 'subway',
754   - elementType: 'geometry',
755   - stylers: {
756   - visibility: 'off',
757   - weight: 1,
758   - },
759   - },
760   - {
761   - featureType: 'subway',
762   - elementType: 'geometry.fill',
763   - stylers: {
764   - color: '#d8d8d8ff',
765   - },
766   - },
767   - {
768   - featureType: 'subway',
769   - elementType: 'geometry.stroke',
770   - stylers: {
771   - color: '#ffffff00',
772   - },
773   - },
774   - {
775   - featureType: 'subway',
776   - elementType: 'labels',
777   - stylers: {
778   - visibility: 'on',
779   - },
780   - },
781   - {
782   - featureType: 'subway',
783   - elementType: 'labels.text.fill',
784   - stylers: {
785   - color: '#979c9aff',
786   - },
787   - },
788   - {
789   - featureType: 'subway',
790   - elementType: 'labels.text.stroke',
791   - stylers: {
792   - color: '#ffffffff',
793   - },
794   - },
795   - {
796   - featureType: 'continent',
797   - elementType: 'labels',
798   - stylers: {
799   - visibility: 'on',
800   - },
801   - },
802   - {
803   - featureType: 'continent',
804   - elementType: 'labels.icon',
805   - stylers: {
806   - visibility: 'on',
807   - },
808   - },
809   - {
810   - featureType: 'continent',
811   - elementType: 'labels.text.fill',
812   - stylers: {
813   - color: '#2dc4bbff',
814   - },
815   - },
816   - {
817   - featureType: 'continent',
818   - elementType: 'labels.text.stroke',
819   - stylers: {
820   - color: '#ffffff00',
821   - },
822   - },
823   - {
824   - featureType: 'city',
825   - elementType: 'labels.icon',
826   - stylers: {
827   - visibility: 'off',
828   - },
829   - },
830   - {
831   - featureType: 'city',
832   - elementType: 'labels',
833   - stylers: {
834   - visibility: 'on',
835   - },
836   - },
837   - {
838   - featureType: 'city',
839   - elementType: 'labels.text.fill',
840   - stylers: {
841   - color: '#2dc4bbff',
842   - },
843   - },
844   - {
845   - featureType: 'city',
846   - elementType: 'labels.text.stroke',
847   - stylers: {
848   - color: '#ffffff00',
849   - },
850   - },
851   - {
852   - featureType: 'town',
853   - elementType: 'labels.icon',
854   - stylers: {
855   - visibility: 'on',
856   - },
857   - },
858   - {
859   - featureType: 'town',
860   - elementType: 'labels',
861   - stylers: {
862   - visibility: 'off',
863   - },
864   - },
865   - {
866   - featureType: 'town',
867   - elementType: 'labels.text.fill',
868   - stylers: {
869   - color: '#454d50ff',
870   - },
871   - },
872   - {
873   - featureType: 'town',
874   - elementType: 'labels.text.stroke',
875   - stylers: {
876   - color: '#ffffffff',
877   - },
878   - },
879   - {
880   - featureType: 'road',
881   - elementType: 'geometry.fill',
882   - stylers: {
883   - color: '#12223dff',
884   - },
885   - },
886   - {
887   - featureType: 'poilabel',
888   - elementType: 'labels',
889   - stylers: {
890   - visibility: 'on',
891   - },
892   - },
893   - {
894   - featureType: 'districtlabel',
895   - elementType: 'labels',
896   - stylers: {
897   - visibility: 'off',
898   - },
899   - },
900   - {
901   - featureType: 'road',
902   - elementType: 'geometry',
903   - stylers: {
904   - visibility: 'on',
905   - },
906   - },
907   - {
908   - featureType: 'road',
909   - elementType: 'labels',
910   - stylers: {
911   - visibility: 'off',
912   - },
913   - },
914   - {
915   - featureType: 'road',
916   - elementType: 'geometry.stroke',
917   - stylers: {
918   - color: '#ffffff00',
919   - },
920   - },
921   - {
922   - featureType: 'district',
923   - elementType: 'labels',
924   - stylers: {
925   - visibility: 'on',
926   - },
927   - },
928   - {
929   - featureType: 'poilabel',
930   - elementType: 'labels.icon',
931   - stylers: {
932   - visibility: 'off',
933   - },
934   - },
935   - {
936   - featureType: 'poilabel',
937   - elementType: 'labels.text.fill',
938   - stylers: {
939   - color: '#2dc4bbff',
940   - },
941   - },
942   - {
943   - featureType: 'poilabel',
944   - elementType: 'labels.text.stroke',
945   - stylers: {
946   - color: '#ffffff00',
947   - },
948   - },
949   - {
950   - featureType: 'manmade',
951   - elementType: 'geometry',
952   - stylers: {
953   - color: '#12223dff',
954   - },
955   - },
956   - {
957   - featureType: 'districtlabel',
958   - elementType: 'labels.text.stroke',
959   - stylers: {
960   - color: '#ffffffff',
961   - },
962   - },
963   - {
964   - featureType: 'entertainment',
965   - elementType: 'geometry',
966   - stylers: {
967   - color: '#12223dff',
968   - },
969   - },
970   - {
971   - featureType: 'shopping',
972   - elementType: 'geometry',
973   - stylers: {
974   - color: '#12223dff',
975   - },
976   - },
977   - {
978   - featureType: 'nationalway',
979   - stylers: {
980   - curZoomRegionId: '0',
981   - curZoomRegion: '6,10',
982   - level: '6',
983   - },
984   - },
985   - {
986   - featureType: 'nationalway',
987   - stylers: {
988   - curZoomRegionId: '0',
989   - curZoomRegion: '6,10',
990   - level: '7',
991   - },
992   - },
993   - {
994   - featureType: 'nationalway',
995   - stylers: {
996   - curZoomRegionId: '0',
997   - curZoomRegion: '6,10',
998   - level: '8',
999   - },
1000   - },
1001   - {
1002   - featureType: 'nationalway',
1003   - stylers: {
1004   - curZoomRegionId: '0',
1005   - curZoomRegion: '6,10',
1006   - level: '9',
1007   - },
1008   - },
1009   - {
1010   - featureType: 'nationalway',
1011   - stylers: {
1012   - curZoomRegionId: '0',
1013   - curZoomRegion: '6,10',
1014   - level: '10',
1015   - },
1016   - },
1017   - {
1018   - featureType: 'nationalway',
1019   - elementType: 'geometry',
1020   - stylers: {
1021   - visibility: 'off',
1022   - curZoomRegionId: '0',
1023   - curZoomRegion: '6,10',
1024   - level: '6',
1025   - },
1026   - },
1027   - {
1028   - featureType: 'nationalway',
1029   - elementType: 'geometry',
1030   - stylers: {
1031   - visibility: 'off',
1032   - curZoomRegionId: '0',
1033   - curZoomRegion: '6,10',
1034   - level: '7',
1035   - },
1036   - },
1037   - {
1038   - featureType: 'nationalway',
1039   - elementType: 'geometry',
1040   - stylers: {
1041   - visibility: 'off',
1042   - curZoomRegionId: '0',
1043   - curZoomRegion: '6,10',
1044   - level: '8',
1045   - },
1046   - },
1047   - {
1048   - featureType: 'nationalway',
1049   - elementType: 'geometry',
1050   - stylers: {
1051   - visibility: 'off',
1052   - curZoomRegionId: '0',
1053   - curZoomRegion: '6,10',
1054   - level: '9',
1055   - },
1056   - },
1057   - {
1058   - featureType: 'nationalway',
1059   - elementType: 'geometry',
1060   - stylers: {
1061   - visibility: 'off',
1062   - curZoomRegionId: '0',
1063   - curZoomRegion: '6,10',
1064   - level: '10',
1065   - },
1066   - },
1067   - {
1068   - featureType: 'nationalway',
1069   - elementType: 'labels',
1070   - stylers: {
1071   - visibility: 'off',
1072   - curZoomRegionId: '0',
1073   - curZoomRegion: '6,10',
1074   - level: '6',
1075   - },
1076   - },
1077   - {
1078   - featureType: 'nationalway',
1079   - elementType: 'labels',
1080   - stylers: {
1081   - visibility: 'off',
1082   - curZoomRegionId: '0',
1083   - curZoomRegion: '6,10',
1084   - level: '7',
1085   - },
1086   - },
1087   - {
1088   - featureType: 'nationalway',
1089   - elementType: 'labels',
1090   - stylers: {
1091   - visibility: 'off',
1092   - curZoomRegionId: '0',
1093   - curZoomRegion: '6,10',
1094   - level: '8',
1095   - },
1096   - },
1097   - {
1098   - featureType: 'nationalway',
1099   - elementType: 'labels',
1100   - stylers: {
1101   - visibility: 'off',
1102   - curZoomRegionId: '0',
1103   - curZoomRegion: '6,10',
1104   - level: '9',
1105   - },
1106   - },
1107   - {
1108   - featureType: 'nationalway',
1109   - elementType: 'labels',
1110   - stylers: {
1111   - visibility: 'off',
1112   - curZoomRegionId: '0',
1113   - curZoomRegion: '6,10',
1114   - level: '10',
1115   - },
1116   - },
1117   - {
1118   - featureType: 'cityhighway',
1119   - stylers: {
1120   - curZoomRegionId: '0',
1121   - curZoomRegion: '6,9',
1122   - level: '6',
1123   - },
1124   - },
1125   - {
1126   - featureType: 'cityhighway',
1127   - stylers: {
1128   - curZoomRegionId: '0',
1129   - curZoomRegion: '6,9',
1130   - level: '7',
1131   - },
1132   - },
1133   - {
1134   - featureType: 'cityhighway',
1135   - stylers: {
1136   - curZoomRegionId: '0',
1137   - curZoomRegion: '6,9',
1138   - level: '8',
1139   - },
1140   - },
1141   - {
1142   - featureType: 'cityhighway',
1143   - stylers: {
1144   - curZoomRegionId: '0',
1145   - curZoomRegion: '6,9',
1146   - level: '9',
1147   - },
1148   - },
1149   - {
1150   - featureType: 'cityhighway',
1151   - elementType: 'geometry',
1152   - stylers: {
1153   - visibility: 'off',
1154   - curZoomRegionId: '0',
1155   - curZoomRegion: '6,9',
1156   - level: '6',
1157   - },
1158   - },
1159   - {
1160   - featureType: 'cityhighway',
1161   - elementType: 'geometry',
1162   - stylers: {
1163   - visibility: 'off',
1164   - curZoomRegionId: '0',
1165   - curZoomRegion: '6,9',
1166   - level: '7',
1167   - },
1168   - },
1169   - {
1170   - featureType: 'cityhighway',
1171   - elementType: 'geometry',
1172   - stylers: {
1173   - visibility: 'off',
1174   - curZoomRegionId: '0',
1175   - curZoomRegion: '6,9',
1176   - level: '8',
1177   - },
1178   - },
1179   - {
1180   - featureType: 'cityhighway',
1181   - elementType: 'geometry',
1182   - stylers: {
1183   - visibility: 'off',
1184   - curZoomRegionId: '0',
1185   - curZoomRegion: '6,9',
1186   - level: '9',
1187   - },
1188   - },
1189   - {
1190   - featureType: 'cityhighway',
1191   - elementType: 'labels',
1192   - stylers: {
1193   - visibility: 'off',
1194   - curZoomRegionId: '0',
1195   - curZoomRegion: '6,9',
1196   - level: '6',
1197   - },
1198   - },
1199   - {
1200   - featureType: 'cityhighway',
1201   - elementType: 'labels',
1202   - stylers: {
1203   - visibility: 'off',
1204   - curZoomRegionId: '0',
1205   - curZoomRegion: '6,9',
1206   - level: '7',
1207   - },
1208   - },
1209   - {
1210   - featureType: 'cityhighway',
1211   - elementType: 'labels',
1212   - stylers: {
1213   - visibility: 'off',
1214   - curZoomRegionId: '0',
1215   - curZoomRegion: '6,9',
1216   - level: '8',
1217   - },
1218   - },
1219   - {
1220   - featureType: 'cityhighway',
1221   - elementType: 'labels',
1222   - stylers: {
1223   - visibility: 'off',
1224   - curZoomRegionId: '0',
1225   - curZoomRegion: '6,9',
1226   - level: '9',
1227   - },
1228   - },
1229   - {
1230   - featureType: 'subwaylabel',
1231   - elementType: 'labels',
1232   - stylers: {
1233   - visibility: 'off',
1234   - },
1235   - },
1236   - {
1237   - featureType: 'subwaylabel',
1238   - elementType: 'labels.icon',
1239   - stylers: {
1240   - visibility: 'off',
1241   - },
1242   - },
1243   - {
1244   - featureType: 'tertiarywaysign',
1245   - elementType: 'labels',
1246   - stylers: {
1247   - visibility: 'off',
1248   - },
1249   - },
1250   - {
1251   - featureType: 'tertiarywaysign',
1252   - elementType: 'labels.icon',
1253   - stylers: {
1254   - visibility: 'off',
1255   - },
1256   - },
1257   - {
1258   - featureType: 'provincialwaysign',
1259   - elementType: 'labels',
1260   - stylers: {
1261   - visibility: 'off',
1262   - },
1263   - },
1264   - {
1265   - featureType: 'provincialwaysign',
1266   - elementType: 'labels.icon',
1267   - stylers: {
1268   - visibility: 'off',
1269   - },
1270   - },
1271   - {
1272   - featureType: 'nationalwaysign',
1273   - elementType: 'labels',
1274   - stylers: {
1275   - visibility: 'off',
1276   - },
1277   - },
1278   - {
1279   - featureType: 'nationalwaysign',
1280   - elementType: 'labels.icon',
1281   - stylers: {
1282   - visibility: 'off',
1283   - },
1284   - },
1285   - {
1286   - featureType: 'highwaysign',
1287   - elementType: 'labels',
1288   - stylers: {
1289   - visibility: 'off',
1290   - },
1291   - },
1292   - {
1293   - featureType: 'highwaysign',
1294   - elementType: 'labels.icon',
1295   - stylers: {
1296   - visibility: 'off',
1297   - },
1298   - },
1299   - {
1300   - featureType: 'village',
1301   - elementType: 'labels',
1302   - stylers: {
1303   - visibility: 'off',
1304   - },
1305   - },
1306   - {
1307   - featureType: 'district',
1308   - elementType: 'labels.text',
1309   - stylers: {
1310   - fontsize: 20,
1311   - },
1312   - },
1313   - {
1314   - featureType: 'district',
1315   - elementType: 'labels.text.fill',
1316   - stylers: {
1317   - color: '#2dc4bbff',
1318   - },
1319   - },
1320   - {
1321   - featureType: 'district',
1322   - elementType: 'labels.text.stroke',
1323   - stylers: {
1324   - color: '#ffffff00',
1325   - },
1326   - },
1327   - {
1328   - featureType: 'country',
1329   - elementType: 'labels.text.fill',
1330   - stylers: {
1331   - color: '#2dc4bbff',
1332   - },
1333   - },
1334   - {
1335   - featureType: 'country',
1336   - elementType: 'labels.text.stroke',
1337   - stylers: {
1338   - color: '#ffffff00',
1339   - },
1340   - },
1341   - {
1342   - featureType: 'water',
1343   - elementType: 'labels.text.fill',
1344   - stylers: {
1345   - color: '#2dc4bbff',
1346   - },
1347   - },
1348   - {
1349   - featureType: 'water',
1350   - elementType: 'labels.text.stroke',
1351   - stylers: {
1352   - color: '#ffffff00',
1353   - },
1354   - },
1355   - {
1356   - featureType: 'cityhighway',
1357   - elementType: 'geometry.fill',
1358   - stylers: {
1359   - color: '#12223dff',
1360   - },
1361   - },
1362   - {
1363   - featureType: 'cityhighway',
1364   - elementType: 'geometry.stroke',
1365   - stylers: {
1366   - color: '#ffffff00',
1367   - },
1368   - },
1369   - {
1370   - featureType: 'tertiaryway',
1371   - elementType: 'geometry.fill',
1372   - stylers: {
1373   - color: '#12223dff',
1374   - },
1375   - },
1376   - {
1377   - featureType: 'tertiaryway',
1378   - elementType: 'geometry.stroke',
1379   - stylers: {
1380   - color: '#ffffff10',
1381   - },
1382   - },
1383   - {
1384   - featureType: 'provincialway',
1385   - elementType: 'geometry.fill',
1386   - stylers: {
1387   - color: '#12223dff',
1388   - },
1389   - },
1390   - {
1391   - featureType: 'provincialway',
1392   - elementType: 'geometry.stroke',
1393   - stylers: {
1394   - color: '#ffffff00',
1395   - },
1396   - },
1397   - {
1398   - featureType: 'nationalway',
1399   - elementType: 'geometry.fill',
1400   - stylers: {
1401   - color: '#12223dff',
1402   - },
1403   - },
1404   - {
1405   - featureType: 'nationalway',
1406   - elementType: 'geometry.stroke',
1407   - stylers: {
1408   - color: '#ffffff00',
1409   - },
1410   - },
1411   - {
1412   - featureType: 'highway',
1413   - elementType: 'labels.text',
1414   - stylers: {
1415   - fontsize: 20,
1416   - },
1417   - },
1418   - {
1419   - featureType: 'nationalway',
1420   - elementType: 'labels.text.stroke',
1421   - stylers: {
1422   - color: '#ffffff00',
1423   - },
1424   - },
1425   - {
1426   - featureType: 'nationalway',
1427   - elementType: 'labels.text.fill',
1428   - stylers: {
1429   - color: '#12223dff',
1430   - },
1431   - },
1432   - {
1433   - featureType: 'nationalway',
1434   - elementType: 'labels.text',
1435   - stylers: {
1436   - fontsize: 20,
1437   - },
1438   - },
1439   - {
1440   - featureType: 'provincialway',
1441   - elementType: 'labels.text.fill',
1442   - stylers: {
1443   - color: '#12223dff',
1444   - },
1445   - },
1446   - {
1447   - featureType: 'provincialway',
1448   - elementType: 'labels.text.stroke',
1449   - stylers: {
1450   - color: '#ffffff00',
1451   - },
1452   - },
1453   - {
1454   - featureType: 'provincialway',
1455   - elementType: 'labels.text',
1456   - stylers: {
1457   - fontsize: 20,
1458   - },
1459   - },
1460   - {
1461   - featureType: 'cityhighway',
1462   - elementType: 'labels.text.fill',
1463   - stylers: {
1464   - color: '#12223dff',
1465   - },
1466   - },
1467   - {
1468   - featureType: 'cityhighway',
1469   - elementType: 'labels.text',
1470   - stylers: {
1471   - fontsize: 20,
1472   - },
1473   - },
1474   - {
1475   - featureType: 'cityhighway',
1476   - elementType: 'labels.text.stroke',
1477   - stylers: {
1478   - color: '#ffffff00',
1479   - },
1480   - },
1481   - {
1482   - featureType: 'estate',
1483   - elementType: 'geometry',
1484   - stylers: {
1485   - color: '#12223dff',
1486   - },
1487   - },
1488   - {
1489   - featureType: 'tertiaryway',
1490   - elementType: 'labels.text.fill',
1491   - stylers: {
1492   - color: '#2dc4bbff',
1493   - },
1494   - },
1495   - {
1496   - featureType: 'tertiaryway',
1497   - elementType: 'labels.text.stroke',
1498   - stylers: {
1499   - color: '#ffffff00',
1500   - },
1501   - },
1502   - {
1503   - featureType: 'fourlevelway',
1504   - elementType: 'labels.text.fill',
1505   - stylers: {
1506   - color: '#2dc4bbff',
1507   - },
1508   - },
1509   - {
1510   - featureType: 'fourlevelway',
1511   - elementType: 'labels.text.stroke',
1512   - stylers: {
1513   - color: '#ffffff00',
1514   - },
1515   - },
1516   - {
1517   - featureType: 'scenicspotsway',
1518   - elementType: 'geometry.fill',
1519   - stylers: {
1520   - color: '#12223dff',
1521   - },
1522   - },
1523   - {
1524   - featureType: 'scenicspotsway',
1525   - elementType: 'geometry.stroke',
1526   - stylers: {
1527   - color: '#ffffff00',
1528   - },
1529   - },
1530   - {
1531   - featureType: 'universityway',
1532   - elementType: 'geometry.fill',
1533   - stylers: {
1534   - color: '#12223dff',
1535   - },
1536   - },
1537   - {
1538   - featureType: 'universityway',
1539   - elementType: 'geometry.stroke',
1540   - stylers: {
1541   - color: '#ffffff00',
1542   - },
1543   - },
1544   - {
1545   - featureType: 'vacationway',
1546   - elementType: 'geometry.fill',
1547   - stylers: {
1548   - color: '#12223dff',
1549   - },
1550   - },
1551   - {
1552   - featureType: 'vacationway',
1553   - elementType: 'geometry.stroke',
1554   - stylers: {
1555   - color: '#ffffff00',
1556   - },
1557   - },
1558   - {
1559   - featureType: 'fourlevelway',
1560   - elementType: 'geometry',
1561   - stylers: {
1562   - visibility: 'on',
1563   - },
1564   - },
1565   - {
1566   - featureType: 'fourlevelway',
1567   - elementType: 'geometry.fill',
1568   - stylers: {
1569   - color: '#12223dff',
1570   - },
1571   - },
1572   - {
1573   - featureType: 'fourlevelway',
1574   - elementType: 'geometry.stroke',
1575   - stylers: {
1576   - color: '#ffffff00',
1577   - },
1578   - },
1579   - {
1580   - featureType: 'transportationlabel',
1581   - elementType: 'labels',
1582   - stylers: {
1583   - visibility: 'on',
1584   - },
1585   - },
1586   - {
1587   - featureType: 'transportationlabel',
1588   - elementType: 'labels.icon',
1589   - stylers: {
1590   - visibility: 'off',
1591   - },
1592   - },
1593   - {
1594   - featureType: 'transportationlabel',
1595   - elementType: 'labels.text.fill',
1596   - stylers: {
1597   - color: '#2dc4bbff',
1598   - },
1599   - },
1600   - {
1601   - featureType: 'transportationlabel',
1602   - elementType: 'labels.text.stroke',
1603   - stylers: {
1604   - color: '#ffffff00',
1605   - },
1606   - },
1607   - {
1608   - featureType: 'educationlabel',
1609   - elementType: 'labels',
1610   - stylers: {
1611   - visibility: 'on',
1612   - },
1613   - },
1614   - {
1615   - featureType: 'educationlabel',
1616   - elementType: 'labels.icon',
1617   - stylers: {
1618   - visibility: 'off',
1619   - },
1620   - },
1621   - {
1622   - featureType: 'educationlabel',
1623   - elementType: 'labels.text.fill',
1624   - stylers: {
1625   - color: '#2dc4bbff',
1626   - },
1627   - },
1628   - {
1629   - featureType: 'educationlabel',
1630   - elementType: 'labels.text.stroke',
1631   - stylers: {
1632   - color: '#ffffff00',
1633   - },
1634   - },
1635   - {
1636   - featureType: 'transportation',
1637   - elementType: 'geometry',
1638   - stylers: {
1639   - color: '#113549ff',
1640   - },
1641   - },
1642   - {
1643   - featureType: 'airportlabel',
1644   - elementType: 'labels.text.fill',
1645   - stylers: {
1646   - color: '#2dc4bbff',
1647   - },
1648   - },
1649   - {
1650   - featureType: 'airportlabel',
1651   - elementType: 'labels.text.stroke',
1652   - stylers: {
1653   - color: '#ffffff00',
1654   - },
1655   - },
1656   - {
1657   - featureType: 'scenicspotslabel',
1658   - elementType: 'labels.text.fill',
1659   - stylers: {
1660   - color: '#2dc4bbff',
1661   - },
1662   - },
1663   - {
1664   - featureType: 'scenicspotslabel',
1665   - elementType: 'labels.text.stroke',
1666   - stylers: {
1667   - color: '#ffffff00',
1668   - },
1669   - },
1670   - {
1671   - featureType: 'medicallabel',
1672   - elementType: 'labels.text.fill',
1673   - stylers: {
1674   - color: '#2dc4bbff',
1675   - },
1676   - },
1677   - {
1678   - featureType: 'medicallabel',
1679   - elementType: 'labels.text.stroke',
1680   - stylers: {
1681   - color: '#ffffff00',
1682   - },
1683   - },
1684   - {
1685   - featureType: 'medicallabel',
1686   - elementType: 'labels.icon',
1687   - stylers: {
1688   - visibility: 'off',
1689   - },
1690   - },
1691   - {
1692   - featureType: 'scenicspotslabel',
1693   - elementType: 'labels.icon',
1694   - stylers: {
1695   - visibility: 'off',
1696   - },
1697   - },
1698   - {
1699   - featureType: 'airportlabel',
1700   - elementType: 'labels.icon',
1701   - stylers: {
1702   - visibility: 'off',
1703   - },
1704   - },
1705   - {
1706   - featureType: 'entertainmentlabel',
1707   - elementType: 'labels.icon',
1708   - stylers: {
1709   - visibility: 'off',
1710   - },
1711   - },
1712   - {
1713   - featureType: 'entertainmentlabel',
1714   - elementType: 'labels.text.fill',
1715   - stylers: {
1716   - color: '#2dc4bbff',
1717   - },
1718   - },
1719   - {
1720   - featureType: 'entertainmentlabel',
1721   - elementType: 'labels.text.stroke',
1722   - stylers: {
1723   - color: '#ffffff00',
1724   - },
1725   - },
1726   - {
1727   - featureType: 'estatelabel',
1728   - elementType: 'labels.icon',
1729   - stylers: {
1730   - visibility: 'off',
1731   - },
1732   - },
1733   - {
1734   - featureType: 'estatelabel',
1735   - elementType: 'labels.text.fill',
1736   - stylers: {
1737   - color: '#2dc4bbff',
1738   - },
1739   - },
1740   - {
1741   - featureType: 'estatelabel',
1742   - elementType: 'labels.text.stroke',
1743   - stylers: {
1744   - color: '#ffffff00',
1745   - },
1746   - },
1747   - {
1748   - featureType: 'businesstowerlabel',
1749   - elementType: 'labels.text.fill',
1750   - stylers: {
1751   - color: '#2dc4bbff',
1752   - },
1753   - },
1754   - {
1755   - featureType: 'businesstowerlabel',
1756   - elementType: 'labels.text.stroke',
1757   - stylers: {
1758   - color: '#ffffff00',
1759   - },
1760   - },
1761   - {
1762   - featureType: 'businesstowerlabel',
1763   - elementType: 'labels.icon',
1764   - stylers: {
1765   - visibility: 'off',
1766   - },
1767   - },
1768   - {
1769   - featureType: 'companylabel',
1770   - elementType: 'labels.text.fill',
1771   - stylers: {
1772   - color: '#2dc4bbff',
1773   - },
1774   - },
1775   - {
1776   - featureType: 'companylabel',
1777   - elementType: 'labels.text.stroke',
1778   - stylers: {
1779   - color: '#ffffff00',
1780   - },
1781   - },
1782   - {
1783   - featureType: 'companylabel',
1784   - elementType: 'labels.icon',
1785   - stylers: {
1786   - visibility: 'off',
1787   - },
1788   - },
1789   - {
1790   - featureType: 'governmentlabel',
1791   - elementType: 'labels.icon',
1792   - stylers: {
1793   - visibility: 'off',
1794   - },
1795   - },
1796   - {
1797   - featureType: 'governmentlabel',
1798   - elementType: 'labels.text.fill',
1799   - stylers: {
1800   - color: '#2dc4bbff',
1801   - },
1802   - },
1803   - {
1804   - featureType: 'governmentlabel',
1805   - elementType: 'labels.text.stroke',
1806   - stylers: {
1807   - color: '#ffffff00',
1808   - },
1809   - },
1810   - {
1811   - featureType: 'restaurantlabel',
1812   - elementType: 'labels.text.fill',
1813   - stylers: {
1814   - color: '#2dc4bbff',
1815   - },
1816   - },
1817   - {
1818   - featureType: 'restaurantlabel',
1819   - elementType: 'labels.text.stroke',
1820   - stylers: {
1821   - color: '#ffffff00',
1822   - },
1823   - },
1824   - {
1825   - featureType: 'restaurantlabel',
1826   - elementType: 'labels.icon',
1827   - stylers: {
1828   - visibility: 'off',
1829   - },
1830   - },
1831   - {
1832   - featureType: 'hotellabel',
1833   - elementType: 'labels.icon',
1834   - stylers: {
1835   - visibility: 'off',
1836   - },
1837   - },
1838   - {
1839   - featureType: 'hotellabel',
1840   - elementType: 'labels.text.fill',
1841   - stylers: {
1842   - color: '#2dc4bbff',
1843   - },
1844   - },
1845   - {
1846   - featureType: 'hotellabel',
1847   - elementType: 'labels.text.stroke',
1848   - stylers: {
1849   - color: '#ffffff00',
1850   - },
1851   - },
1852   - {
1853   - featureType: 'shoppinglabel',
1854   - elementType: 'labels.text.fill',
1855   - stylers: {
1856   - color: '#2dc4bbff',
1857   - },
1858   - },
1859   - {
1860   - featureType: 'shoppinglabel',
1861   - elementType: 'labels.text.stroke',
1862   - stylers: {
1863   - color: '#ffffff00',
1864   - },
1865   - },
1866   - {
1867   - featureType: 'shoppinglabel',
1868   - elementType: 'labels.icon',
1869   - stylers: {
1870   - visibility: 'off',
1871   - },
1872   - },
1873   - {
1874   - featureType: 'lifeservicelabel',
1875   - elementType: 'labels.text.fill',
1876   - stylers: {
1877   - color: '#2dc4bbff',
1878   - },
1879   - },
1880   - {
1881   - featureType: 'lifeservicelabel',
1882   - elementType: 'labels.text.stroke',
1883   - stylers: {
1884   - color: '#ffffff00',
1885   - },
1886   - },
1887   - {
1888   - featureType: 'lifeservicelabel',
1889   - elementType: 'labels.icon',
1890   - stylers: {
1891   - visibility: 'off',
1892   - },
1893   - },
1894   - {
1895   - featureType: 'carservicelabel',
1896   - elementType: 'labels.text.fill',
1897   - stylers: {
1898   - color: '#2dc4bbff',
1899   - },
1900   - },
1901   - {
1902   - featureType: 'carservicelabel',
1903   - elementType: 'labels.text.stroke',
1904   - stylers: {
1905   - color: '#ffffff00',
1906   - },
1907   - },
1908   - {
1909   - featureType: 'carservicelabel',
1910   - elementType: 'labels.icon',
1911   - stylers: {
1912   - visibility: 'off',
1913   - },
1914   - },
1915   - {
1916   - featureType: 'financelabel',
1917   - elementType: 'labels.text.fill',
1918   - stylers: {
1919   - color: '#2dc4bbff',
1920   - },
1921   - },
1922   - {
1923   - featureType: 'financelabel',
1924   - elementType: 'labels.text.stroke',
1925   - stylers: {
1926   - color: '#ffffff00',
1927   - },
1928   - },
1929   - {
1930   - featureType: 'financelabel',
1931   - elementType: 'labels.icon',
1932   - stylers: {
1933   - visibility: 'off',
1934   - },
1935   - },
1936   - {
1937   - featureType: 'otherlabel',
1938   - elementType: 'labels.text.fill',
1939   - stylers: {
1940   - color: '#2dc4bbff',
1941   - },
1942   - },
1943   - {
1944   - featureType: 'otherlabel',
1945   - elementType: 'labels.text.stroke',
1946   - stylers: {
1947   - color: '#ffffff00',
1948   - },
1949   - },
1950   - {
1951   - featureType: 'otherlabel',
1952   - elementType: 'labels.icon',
1953   - stylers: {
1954   - visibility: 'off',
1955   - },
1956   - },
1957   - {
1958   - featureType: 'manmade',
1959   - elementType: 'labels.text.fill',
1960   - stylers: {
1961   - color: '#2dc4bbff',
1962   - },
1963   - },
1964   - {
1965   - featureType: 'manmade',
1966   - elementType: 'labels.text.stroke',
1967   - stylers: {
1968   - color: '#ffffff00',
1969   - },
1970   - },
1971   - {
1972   - featureType: 'transportation',
1973   - elementType: 'labels.text.fill',
1974   - stylers: {
1975   - color: '#2dc4bbff',
1976   - },
1977   - },
1978   - {
1979   - featureType: 'transportation',
1980   - elementType: 'labels.text.stroke',
1981   - stylers: {
1982   - color: '#ffffff00',
1983   - },
1984   - },
1985   - {
1986   - featureType: 'education',
1987   - elementType: 'labels.text.fill',
1988   - stylers: {
1989   - color: '#2dc4bbff',
1990   - },
1991   - },
1992   - {
1993   - featureType: 'education',
1994   - elementType: 'labels.text.stroke',
1995   - stylers: {
1996   - color: '#ffffff00',
1997   - },
1998   - },
1999   - {
2000   - featureType: 'medical',
2001   - elementType: 'labels.text.fill',
2002   - stylers: {
2003   - color: '#2dc4bbff',
2004   - },
2005   - },
2006   - {
2007   - featureType: 'medical',
2008   - elementType: 'labels.text.stroke',
2009   - stylers: {
2010   - color: '#ffffff00',
2011   - },
2012   - },
2013   - {
2014   - featureType: 'scenicspots',
2015   - elementType: 'labels.text.fill',
2016   - stylers: {
2017   - color: '#2dc4bbff',
2018   - },
2019   - },
2020   - {
2021   - featureType: 'scenicspots',
2022   - elementType: 'labels.text.stroke',
2023   - stylers: {
2024   - color: '#ffffff00',
2025   - },
2026   - },
2027   - ],
2028   -};
1   -import { FormSchema } from '/@/components/Form';
2   -
3   -export const scheme: FormSchema[] = [
4   - // {
5   - // field: 'effectScope',
6   - // label: '时间周期',
7   - // colProps: { span: 24 },
8   - // component: 'Input',
9   - // defaultValue: 'effectScope',
10   - // componentProps: {
11   - // disabled: true,
12   - // },
13   - // },
14   - {
15   - field: 'agg',
16   - label: '聚合方式',
17   - defaultValue: 'agg',
18   - colProps: { span: 24 },
19   - component: 'Input',
20   - componentProps: {
21   - disabled: true,
22   - },
23   - },
24   - {
25   - field: 'interval',
26   - label: '间隔时间',
27   - defaultValue: 'interval',
28   - colProps: { span: 24 },
29   - component: 'Input',
30   - componentProps: {
31   - disabled: true,
32   - },
33   - },
34   -];
1   -import { Moment } from 'moment';
2   -
3   -enum TimeUnit {
4   - SECOND = 'second',
5   - MINUTE = 'MINUTE',
6   - HOUR = 'HOUR',
7   - DAY = 'DAY',
8   -}
9   -
10   -const unitMapping = {
11   - [TimeUnit.SECOND]: '秒',
12   - [TimeUnit.MINUTE]: '分',
13   - [TimeUnit.HOUR]: '小时',
14   - [TimeUnit.DAY]: '天',
15   -};
16   -
17   -const unitConversion = {
18   - [TimeUnit.SECOND]: 1 * 1000,
19   - [TimeUnit.MINUTE]: 1 * 60 * 1000,
20   - [TimeUnit.HOUR]: 1 * 60 * 60 * 1000,
21   - [TimeUnit.DAY]: 1 * 60 * 60 * 24 * 1000,
22   -};
23   -
24   -export const intervalOption = [
25   - {
26   - id: 1,
27   - unit: TimeUnit.SECOND,
28   - linkage: [{ id: 1, unit: TimeUnit.SECOND }],
29   - },
30   - {
31   - id: 5,
32   - unit: TimeUnit.SECOND,
33   - linkage: [{ id: 1, unit: TimeUnit.SECOND }],
34   - },
35   - {
36   - id: 10,
37   - unit: TimeUnit.SECOND,
38   - linkage: [{ id: 1, unit: TimeUnit.SECOND }],
39   - },
40   - {
41   - id: 15,
42   - unit: TimeUnit.SECOND,
43   - linkage: [{ id: 1, unit: TimeUnit.SECOND }],
44   - },
45   - {
46   - id: 30,
47   - unit: TimeUnit.SECOND,
48   - linkage: [{ id: 1, unit: TimeUnit.SECOND }],
49   - },
50   - {
51   - id: 1,
52   - unit: TimeUnit.MINUTE,
53   - linkage: [
54   - { id: 1, unit: TimeUnit.SECOND },
55   - { id: 5, unit: TimeUnit.SECOND },
56   - ],
57   - },
58   - {
59   - id: 2,
60   - unit: TimeUnit.MINUTE,
61   - linkage: [
62   - { id: 1, unit: TimeUnit.SECOND },
63   - { id: 5, unit: TimeUnit.SECOND },
64   - { id: 10, unit: TimeUnit.SECOND },
65   - { id: 15, unit: TimeUnit.SECOND },
66   - ],
67   - },
68   - {
69   - id: 5,
70   - unit: TimeUnit.MINUTE,
71   - linkage: [
72   - { id: 1, unit: TimeUnit.SECOND },
73   - { id: 5, unit: TimeUnit.SECOND },
74   - { id: 10, unit: TimeUnit.SECOND },
75   - { id: 15, unit: TimeUnit.SECOND },
76   - { id: 30, unit: TimeUnit.SECOND },
77   - ],
78   - },
79   - {
80   - id: 10,
81   - unit: TimeUnit.MINUTE,
82   - linkage: [
83   - { id: 5, unit: TimeUnit.SECOND },
84   - { id: 10, unit: TimeUnit.SECOND },
85   - { id: 15, unit: TimeUnit.SECOND },
86   - { id: 30, unit: TimeUnit.SECOND },
87   - { id: 1, unit: TimeUnit.MINUTE },
88   - ],
89   - },
90   - {
91   - id: 15,
92   - unit: TimeUnit.MINUTE,
93   - linkage: [
94   - { id: 5, unit: TimeUnit.SECOND },
95   - { id: 10, unit: TimeUnit.SECOND },
96   - { id: 15, unit: TimeUnit.SECOND },
97   - { id: 30, unit: TimeUnit.SECOND },
98   - { id: 1, unit: TimeUnit.MINUTE },
99   - { id: 2, unit: TimeUnit.MINUTE },
100   - ],
101   - },
102   - {
103   - id: 30,
104   - unit: TimeUnit.MINUTE,
105   - linkage: [
106   - { id: 5, unit: TimeUnit.SECOND },
107   - { id: 10, unit: TimeUnit.SECOND },
108   - { id: 15, unit: TimeUnit.SECOND },
109   - { id: 30, unit: TimeUnit.SECOND },
110   - { id: 1, unit: TimeUnit.MINUTE },
111   - { id: 2, unit: TimeUnit.MINUTE },
112   - ],
113   - },
114   - {
115   - id: 1,
116   - unit: TimeUnit.HOUR,
117   - linkage: [
118   - { id: 10, unit: TimeUnit.SECOND },
119   - { id: 15, unit: TimeUnit.SECOND },
120   - { id: 30, unit: TimeUnit.SECOND },
121   - { id: 1, unit: TimeUnit.MINUTE },
122   - { id: 2, unit: TimeUnit.MINUTE },
123   - { id: 5, unit: TimeUnit.MINUTE },
124   - ],
125   - },
126   - {
127   - id: 2,
128   - unit: TimeUnit.HOUR,
129   - linkage: [
130   - { id: 15, unit: TimeUnit.SECOND },
131   - { id: 30, unit: TimeUnit.SECOND },
132   - { id: 1, unit: TimeUnit.MINUTE },
133   - { id: 2, unit: TimeUnit.MINUTE },
134   - { id: 5, unit: TimeUnit.MINUTE },
135   - { id: 10, unit: TimeUnit.MINUTE },
136   - { id: 15, unit: TimeUnit.MINUTE },
137   - ],
138   - },
139   - {
140   - id: 5,
141   - unit: TimeUnit.HOUR,
142   - linkage: [
143   - { id: 1, unit: TimeUnit.MINUTE },
144   - { id: 2, unit: TimeUnit.MINUTE },
145   - { id: 5, unit: TimeUnit.MINUTE },
146   - { id: 10, unit: TimeUnit.MINUTE },
147   - { id: 15, unit: TimeUnit.MINUTE },
148   - { id: 30, unit: TimeUnit.MINUTE },
149   - ],
150   - },
151   - {
152   - id: 10,
153   - unit: TimeUnit.HOUR,
154   - linkage: [
155   - { id: 2, unit: TimeUnit.MINUTE },
156   - { id: 5, unit: TimeUnit.MINUTE },
157   - { id: 10, unit: TimeUnit.MINUTE },
158   - { id: 15, unit: TimeUnit.MINUTE },
159   - { id: 30, unit: TimeUnit.MINUTE },
160   - { id: 1, unit: TimeUnit.HOUR },
161   - ],
162   - },
163   - {
164   - id: 12,
165   - unit: TimeUnit.HOUR,
166   - linkage: [
167   - { id: 2, unit: TimeUnit.MINUTE },
168   - { id: 5, unit: TimeUnit.MINUTE },
169   - { id: 10, unit: TimeUnit.MINUTE },
170   - { id: 15, unit: TimeUnit.MINUTE },
171   - { id: 30, unit: TimeUnit.MINUTE },
172   - { id: 1, unit: TimeUnit.HOUR },
173   - ],
174   - },
175   - {
176   - id: 1,
177   - unit: TimeUnit.DAY,
178   - linkage: [
179   - { id: 5, unit: TimeUnit.MINUTE },
180   - { id: 10, unit: TimeUnit.MINUTE },
181   - { id: 15, unit: TimeUnit.MINUTE },
182   - { id: 30, unit: TimeUnit.MINUTE },
183   - { id: 1, unit: TimeUnit.HOUR },
184   - { id: 2, unit: TimeUnit.HOUR },
185   - ],
186   - },
187   - {
188   - id: 7,
189   - unit: TimeUnit.DAY,
190   - linkage: [
191   - { id: 30, unit: TimeUnit.MINUTE },
192   - { id: 1, unit: TimeUnit.HOUR },
193   - { id: 2, unit: TimeUnit.HOUR },
194   - { id: 5, unit: TimeUnit.HOUR },
195   - { id: 10, unit: TimeUnit.HOUR },
196   - { id: 12, unit: TimeUnit.HOUR },
197   - { id: 1, unit: TimeUnit.DAY },
198   - ],
199   - },
200   - {
201   - id: 30,
202   - unit: TimeUnit.DAY,
203   - linkage: [
204   - { id: 2, unit: TimeUnit.HOUR },
205   - { id: 5, unit: TimeUnit.HOUR },
206   - { id: 10, unit: TimeUnit.HOUR },
207   - { id: 12, unit: TimeUnit.HOUR },
208   - { id: 1, unit: TimeUnit.DAY },
209   - ],
210   - },
211   -].map((item) => {
212   - return {
213   - value: item.id * unitConversion[item.unit],
214   - label: item.id + unitMapping[item.unit],
215   - linkage: item.linkage.map((item) => {
216   - return {
217   - value: item.id * unitConversion[item.unit],
218   - label: item.id + unitMapping[item.unit],
219   - };
220   - }),
221   - };
222   -});
223   -
224   -const rangeIntervalOption = [
225   - {
226   - id: 90,
227   - unit: TimeUnit.DAY,
228   - linkage: [
229   - { id: 5, unit: TimeUnit.HOUR },
230   - { id: 10, unit: TimeUnit.HOUR },
231   - { id: 12, unit: TimeUnit.HOUR },
232   - { id: 1, unit: TimeUnit.DAY },
233   - { id: 7, unit: TimeUnit.DAY },
234   - ],
235   - },
236   - {
237   - id: 180,
238   - unit: TimeUnit.DAY,
239   - linkage: [
240   - { id: 10, unit: TimeUnit.HOUR },
241   - { id: 12, unit: TimeUnit.HOUR },
242   - { id: 1, unit: TimeUnit.DAY },
243   - { id: 7, unit: TimeUnit.DAY },
244   - ],
245   - },
246   - {
247   - id: 360,
248   - unit: TimeUnit.DAY,
249   - linkage: [
250   - { id: 1, unit: TimeUnit.DAY },
251   - { id: 7, unit: TimeUnit.DAY },
252   - { id: 30, unit: TimeUnit.DAY },
253   - ],
254   - },
255   -].map((item) => {
256   - return {
257   - value: item.id * unitConversion[item.unit],
258   - label: item.id + unitMapping[item.unit],
259   - linkage: item.linkage.map((item) => {
260   - return {
261   - value: item.id * unitConversion[item.unit],
262   - label: item.id + unitMapping[item.unit],
263   - };
264   - }),
265   - };
266   -});
267   -
268   -/**
269   - * @description
270   - * @param {number} value
271   - * @returns
272   - */
273   -export function getPacketIntervalByValue(value: number) {
274   - return intervalOption.find((item) => item.value === value)?.linkage || [];
275   -}
276   -
277   -export function getPacketIntervalByRange(
278   - [start, end] = [null, null] as [Nullable<Moment>, Nullable<Moment>]
279   -) {
280   - if (start && end) {
281   - const value = end.diff(start, 'ms');
282   - let options: { value: number; label: string }[] = [];
283   - for (const item of [...intervalOption, ...rangeIntervalOption]) {
284   - if (item.value <= value) continue;
285   - if (item.value >= value) {
286   - options = item.linkage;
287   - break;
288   - }
289   - }
290   - return options;
291   - }
292   - return [];
293   -}
1   -<script setup lang="ts">
2   - import { BasicForm, useForm } from '/@/components/Form';
3   - import { scheme } from './config';
4   -
5   - defineEmits(['register']);
6   -
7   - const [registerForm, { getFieldsValue, setFieldsValue, resetFields }] = useForm({
8   - schemas: scheme,
9   - showActionButtonGroup: false,
10   - });
11   -
12   - const getValue = () => {
13   - return getFieldsValue();
14   - };
15   -
16   - const setValue = (objs) => setFieldsValue(objs);
17   -
18   - const resetValue = () => resetFields();
19   -
20   - defineExpose({
21   - getValue,
22   - setValue,
23   - resetValue,
24   - });
25   -</script>
26   -
27   -<template>
28   - <BasicForm @register="registerForm" />
29   -</template>
  1 +<template>
  2 + <div class="flex flex-col justify-between">
  3 + <Tag v-if="scriptType === OnlineEditorTypeEnum.JAVASCRIPT" color="blue" class="tag-text-top">
  4 + <span>function</span>&nbsp;&nbsp;filter(res)&nbsp;&nbsp;{
  5 + </Tag>
  6 + <div class="mt-2 mb-2" ref="aceRef"></div>
  7 + <Tag
  8 + v-if="scriptType === OnlineEditorTypeEnum.JAVASCRIPT"
  9 + color="blue"
  10 + class="mt-2 tag-text-bottom"
  11 + >}</Tag
  12 + >
  13 + <div v-if="scriptType === OnlineEditorTypeEnum.JAVASCRIPT" class="ml-2 -mt-1.5">
  14 + <Button @click="onHandleFormatter" class="mt-8 -ml-2">
  15 + <template #icon>
  16 + <CopyOutlined />
  17 + </template>
  18 + 格式化
  19 + </Button>
  20 + </div>
  21 + </div>
  22 +</template>
  23 +
  24 +<script lang="ts" setup name="aceEditor">
  25 + import { ref, computed, onMounted, nextTick, watch } from 'vue';
  26 + import ace from 'ace-builds';
  27 + import 'ace-builds/src-noconflict/theme-chrome'; // 默认设置的主题
  28 + import 'ace-builds/src-noconflict/theme-terminal'; // 默认设置的主题
  29 + import 'ace-builds/src-noconflict/mode-javascript'; // 默认设置的语言模式javascript
  30 + import 'ace-builds/src-noconflict/snippets/xml'; // 设置xmL
  31 + import { beautify } from 'ace-builds/src-noconflict/ext-beautify.js';
  32 + import { useAppStore } from '/@/store/modules/app';
  33 + import { CopyOutlined } from '@ant-design/icons-vue';
  34 + import { Button, Tag } from 'ant-design-vue';
  35 + import { OnlineEditorTypeEnum } from '../../../config/enum';
  36 +
  37 + const emits = defineEmits(['changeAceContent']);
  38 +
  39 + const props = defineProps({
  40 + restData: {
  41 + type: Object,
  42 + },
  43 + scriptType: {
  44 + type: String,
  45 + default: 'javascript',
  46 + },
  47 + });
  48 +
  49 + const aceEditor = ref();
  50 +
  51 + const aceRef = ref();
  52 +
  53 + const userStore = useAppStore();
  54 +
  55 + const getAceClass = computed((): string => userStore.getDarkMode);
  56 +
  57 + const getRestData: any = ref(null);
  58 +
  59 + watch(
  60 + () => props.restData,
  61 + (newVal) => {
  62 + getRestData.value = newVal;
  63 + onHandleFormatter();
  64 + },
  65 + { deep: true }
  66 + );
  67 +
  68 + // 初始化编辑器
  69 + const initEditor = () => {
  70 + aceEditor.value = ace.edit(aceRef.value, {
  71 + maxLines: 50, // 最大行数,超过会自动出现滚动条
  72 + minLines: props.scriptType === OnlineEditorTypeEnum.JAVASCRIPT ? 36 : 14, // 最小行数,还未到最大行数时,编辑器会自动伸缩大小
  73 + fontSize: 14, // 编辑器内字体大小
  74 + theme: 'ace/theme/chrome', // 默认设置的主题
  75 + mode:
  76 + props.scriptType === OnlineEditorTypeEnum.JAVASCRIPT
  77 + ? 'ace/mode/javascript'
  78 + : 'ace/mode/xml', // 默认设置的语言模式
  79 + tabSize: 2, // 制表符设置为 4 个空格大小
  80 + });
  81 +
  82 + aceEditor.value.setOptions({
  83 + enableBasicAutocompletion: true,
  84 + enableLiveAutocompletion: true,
  85 + enableSnippets: true,
  86 + enableEmmet: true,
  87 + theme: getAceClass.value === 'dark' ? 'ace/theme/terminal' : 'ace/theme/chrome',
  88 + });
  89 + doFilter();
  90 + beautify(aceEditor.value.session);
  91 + };
  92 +
  93 + const doFilter = () => {
  94 + aceEditor.value.getSession().on('change', async () => {
  95 + try {
  96 + await nextTick();
  97 + const jsCode = aceEditor.value.getValue();
  98 + const res = getRestData.value ?? props.restData;
  99 + const fn = new Function('data', 'res', jsCode)(res?.data, res);
  100 + emits('changeAceContent', fn);
  101 + } catch (error) {
  102 + return `过滤函数错误,日志:${error}`;
  103 + }
  104 + });
  105 + };
  106 +
  107 + const onHandleFormatter = () => {
  108 + let oldValue = aceEditor.value?.getValue() || '';
  109 + oldValue = oldValue.replaceAll(/;(\n+)?/g, ';\n');
  110 + aceEditor.value?.setValue(oldValue);
  111 + beautify(aceEditor.value.session);
  112 + };
  113 +
  114 + const getValue = () => {
  115 + return aceEditor?.value?.getValue();
  116 + };
  117 +
  118 + const setValue = (data) => {
  119 + return aceEditor?.value?.setValue(data);
  120 + };
  121 +
  122 + onMounted(() => {
  123 + initEditor();
  124 + });
  125 +
  126 + defineExpose({
  127 + getValue,
  128 + setValue,
  129 + });
  130 +</script>
  131 +
  132 +<style lang="less" scoped>
  133 + .jsoneditor {
  134 + border: none;
  135 + }
  136 +
  137 + .tag-text {
  138 + white-space: normal;
  139 + height: auto;
  140 + }
  141 +
  142 + .tag-text-top {
  143 + width: 8vw;
  144 + &:extend(.tag-text);
  145 + }
  146 +
  147 + .tag-text-bottom {
  148 + width: 1vw;
  149 + &:extend(.tag-text);
  150 + }
  151 +</style>
... ...
... ... @@ -8,30 +8,28 @@
8 8 </a-radio-group>
9 9 <div class="mt-3">
10 10 <a-textarea
11   - v-show="getRequestBody.content.requestParamsBodyType === 'none'"
  11 + v-show="getRequestBody.content.requestParamsBodyType === RequestBodyTypeEnum.NONE"
12 12 disabled
13 13 placeholder="该接口没有 Body 体"
14   - :rows="2"
15 14 />
16 15 <BodyTable
17 16 ref="bodyCellFormDataTableRef"
18   - v-show="getRequestBody.content.requestParamsBodyType === 'form-data'"
  17 + v-show="getRequestBody.content.requestParamsBodyType === RequestBodyTypeEnum.FORMDATA"
19 18 />
20 19 <BodyTable
21 20 ref="bodyCellXwwwTableRef"
22   - v-show="getRequestBody.content.requestParamsBodyType === 'x-www-form-urlencoded'"
  21 + v-show="getRequestBody.content.requestParamsBodyType === RequestBodyTypeEnum.XWWW"
23 22 />
24 23 <JsonEditor
25 24 :showBtn="false"
26   - style="width: 35vw; height: 30vh"
27   - v-show="getRequestBody.content.requestParamsBodyType === 'json'"
  25 + style="width: 35vw; height: 25vh"
  26 + v-show="getRequestBody.content.requestParamsBodyType === RequestBodyTypeEnum.JSON"
28 27 ref="jsonEditorRef"
29 28 />
30   - <a-textarea
31   - v-model:value="getRequestBody.content.xml"
32   - v-show="getRequestBody.content.requestParamsBodyType === 'xml'"
33   - placeholder="请输入xml"
34   - :rows="6"
  29 + <AceTypeXmlEditor
  30 + ref="aceEditorRef"
  31 + v-show="getRequestBody.content.requestParamsBodyType === RequestBodyTypeEnum.XML"
  32 + :scriptType="OnlineEditorTypeEnum.XML"
35 33 />
36 34 </div>
37 35 </div>
... ... @@ -39,10 +37,12 @@
39 37 <script lang="ts" setup name="body">
40 38 import { reactive, ref, nextTick } from 'vue';
41 39 import { RequestBodyTypeEnum } from '../../../config/enum';
42   - import BodyTable from './bodyTable.vue';
  40 + import BodyTable from './paramsTable.vue';
43 41 import { isEmpty } from '/@/utils/is';
44 42 import { useUtils } from '../../../hooks/useUtils';
45 43 import JsonEditor from './jsonEditor.vue';
  44 + import AceTypeXmlEditor from './aceEditor.vue';
  45 + import { OnlineEditorTypeEnum } from '../../../config/enum';
46 46
47 47 const getRequestBody = reactive({
48 48 content: {
... ... @@ -62,6 +62,8 @@
62 62
63 63 const jsonEditorRef = ref<InstanceType<typeof JsonEditor>>();
64 64
  65 + const aceEditorRef = ref<InstanceType<typeof AceTypeXmlEditor>>();
  66 +
65 67 const bodyCellXwwwTableRef = ref<InstanceType<typeof BodyTable>>();
66 68
67 69 const handleChange = ({ target }) => {
... ... @@ -76,9 +78,11 @@
76 78 const valuesFormData = bodyCellFormDataTableRef.value?.getValue();
77 79 const valuesXWww = bodyCellXwwwTableRef.value?.getValue();
78 80 const jsonEditorValue = jsonEditorRef.value?.getJsonValue();
79   - getRequestBody.content['form-data'] = valuesFormData as any;
80   - getRequestBody.content['x-www-form-urlencoded'] = valuesXWww as any;
81   - getRequestBody.content['json'] = jsonEditorValue as any;
  81 + const xmlEditorValue = aceEditorRef.value?.getValue();
  82 + getRequestBody.content[RequestBodyTypeEnum.FORMDATA] = valuesFormData as any;
  83 + getRequestBody.content[RequestBodyTypeEnum.XWWW] = valuesXWww as any;
  84 + getRequestBody.content[RequestBodyTypeEnum.JSON] = jsonEditorValue as any;
  85 + getRequestBody.content[RequestBodyTypeEnum.XML] = xmlEditorValue as any;
82 86 if (type === 'none') getRequestBody.content = {} as any;
83 87 return getRequestBody.content;
84 88 };
... ... @@ -90,18 +94,22 @@
90 94 getRequestBody.content.requestParamsBodyType = type;
91 95 await nextTick();
92 96 await nextTick();
93   - bodyCellFormDataTableRef.value?.setValue(isEmpty(data) ? [pushObj] : data['form-data']);
94   - bodyCellXwwwTableRef.value?.setValue(isEmpty(data) ? [pushObj] : data['x-www-form-urlencoded']);
  97 + bodyCellFormDataTableRef.value?.setValue(
  98 + isEmpty(data) ? [pushObj] : data[RequestBodyTypeEnum.FORMDATA]
  99 + );
  100 + bodyCellXwwwTableRef.value?.setValue(
  101 + isEmpty(data) ? [pushObj] : data[RequestBodyTypeEnum.XWWW]
  102 + );
95 103 jsonEditorRef.value?.setJsonValue(data['json'] || '{}');
96   - getRequestBody.content.xml = data['xml'];
  104 + aceEditorRef.value?.setValue(data['xml'] || '');
97 105 };
98 106
99 107 //重置数据
100 108 const resetValue = () => {
101 109 for (let i in getRequestBody.content) Reflect.set(getRequestBody.content, i, '');
102   - getRequestBody.content['form-data'] = {};
103   - getRequestBody.content['x-www-form-urlencoded'] = {};
104   - getRequestBody.content.requestParamsBodyType = 'none';
  110 + getRequestBody.content[RequestBodyTypeEnum.FORMDATA] = {};
  111 + getRequestBody.content[RequestBodyTypeEnum.XWWW] = {};
  112 + getRequestBody.content.requestParamsBodyType = RequestBodyTypeEnum.NONE;
105 113 nextTick(() => {
106 114 bodyCellFormDataTableRef?.value?.resetValue();
107 115 bodyCellXwwwTableRef?.value?.resetValue();
... ...
1   -<template>
2   - <div class="table-content">
3   - <!-- 采用的原生表格 -->
4   - <table align="center">
5   - <thead>
6   - <tr>
7   - <th v-for="item in editCellTableTHeadConfig" :key="item">{{ item }}</th>
8   - </tr>
9   - </thead>
10   - <tbody>
11   - <tr v-for="(item, index) in tableArray.content" :key="index">
12   - <td>
13   - {{ index + 1 }}
14   - </td>
15   - <td style="width: 12vw">
16   - <Select
17   - v-model:value="item.key"
18   - placeholder="请选择"
19   - :options="selectOptions"
20   - @change="handleChange"
21   - @dropdownVisibleChange="hanldeDropdownVisibleChange"
22   - allowClear
23   - />
24   - </td>
25   - <td style="width: 12vw">
26   - <div v-if="item.key === 'date_range'">
27   - <a-input style="width: 6vw" placeholder="请输入" v-model:value="item.date1" />
28   - <span>~</span>
29   - <a-input style="width: 6vw" placeholder="请输入" v-model:value="item.date2" />
30   - </div>
31   - <div v-else>
32   - <a-input
33   - :disabled="item.editDisabled"
34   - placeholder="请输入"
35   - v-model:value="item.value"
36   - />
37   - </div>
38   - </td>
39   - <td style="width: 4vw">
40   - <a-switch v-model:checked="item.required" />
41   - </td>
42   - <td style="width: 4vw">
43   - <div>
44   - <Button type="dashed" @click="add(item, index)">
45   - <template #icon><PlusOutlined /></template
46   - ></Button>
47   - <Button type="dashed" style="margin-left: 5px" @click="remove(item, index)">
48   - <template #icon> <MinusOutlined /></template>
49   - </Button>
50   - </div>
51   - </td>
52   - </tr>
53   - </tbody>
54   - </table>
55   - </div>
56   -</template>
57   -<script lang="ts" setup name="editCellTable">
58   - import { reactive, ref, onMounted, nextTick } from 'vue';
59   - import { Select, Button } from 'ant-design-vue';
60   - import { findDictItemByCode } from '/@/api/system/dict';
61   - import { PlusOutlined, MinusOutlined } from '@ant-design/icons-vue';
62   - import { editCellTableTHeadConfig } from '../../../config/config';
63   - import { selectType, tableItems } from '../../../config/types';
64   -
65   - defineProps({
66   - method: {
67   - type: String,
68   - },
69   - });
70   -
71   - const selectOptions = ref<selectType[]>([]);
72   -
73   - onMounted(() => {
74   - getSelectOptions();
75   - });
76   -
77   - const getSelectOptions = async () => {
78   - const res = await findDictItemByCode({ dictCode: 'dataview_builtin_params' });
79   - selectOptions.value = res.map((m) => ({ label: m.itemText, value: m.itemValue }));
80   - selectOptions.value.push({
81   - label: '自定义',
82   - value: 'scope',
83   - });
84   - };
85   -
86   - const tableArray = reactive<{
87   - content: tableItems[];
88   - }>({
89   - content: [
90   - {
91   - key: undefined,
92   - value: '',
93   - editDisabled: false,
94   - required: false,
95   - date1: '',
96   - date2: '',
97   - },
98   - ],
99   - });
100   -
101   - // 新增
102   - const add = (_, index: number) => {
103   - tableArray.content.splice(index + 1, 0, {
104   - key: undefined,
105   - value: '',
106   - editDisabled: false,
107   - required: false,
108   - date1: '',
109   - date2: '',
110   - });
111   - };
112   -
113   - // 减少
114   - const remove = (item, index: number) => {
115   - if (tableArray.content.length > 1) {
116   - selectOptions.value.forEach((ele) => {
117   - if (ele.value == item.key) {
118   - ele.disabled = false;
119   - }
120   - });
121   - tableArray.content.splice(index, 1);
122   - } else {
123   - resetValue();
124   - }
125   - };
126   -
127   - const hanldeDropdownVisibleChange = () => handleChange();
128   -
129   - //Select互斥
130   - const handleChange = () => {
131   - selectOptions.value.forEach((ele) => {
132   - ele.disabled = false;
133   - tableArray.content.forEach((element) => {
134   - if (element.key === 'scope' || element.key === 'fixed_date') {
135   - element.editDisabled = false;
136   - } else {
137   - element.value = '';
138   - element.editDisabled = true;
139   - }
140   - if (element.key === ele.value && element.key !== 'scope' && element.key !== 'fixed_date') {
141   - ele.disabled = true;
142   - }
143   - });
144   - });
145   - };
146   -
147   - //获取数据
148   - const getValue = () => {
149   - const assemblyData = tableArray.content.map((it) => {
150   - return {
151   - key: it.key,
152   - value: it.key === 'date_range' ? `${it.date1},${it.date2}` : it.value,
153   - editDisabled: it.editDisabled,
154   - required: it.required,
155   - };
156   - });
157   - return assemblyData;
158   - };
159   -
160   - //设置数据
161   - const setValue = async (data) => {
162   - await nextTick();
163   - const assemblyData = data.map((it) => {
164   - return {
165   - key: it.key,
166   - value: it.value,
167   - editDisabled: it.editDisabled,
168   - required: it.required,
169   - date1: it.key === 'date_range' ? it.value?.split(',')?.at(-2) : '',
170   - date2: it.key === 'date_range' ? it.value?.split(',')?.at(-1) : '',
171   - };
172   - });
173   - tableArray.content = assemblyData;
174   - tableArray.content.forEach(() => {
175   - handleChange();
176   - });
177   - };
178   -
179   - //重置数据
180   - const resetValue = () => {
181   - tableArray.content = [];
182   - tableArray.content.push({
183   - key: undefined,
184   - value: '',
185   - editDisabled: false,
186   - required: false,
187   - date1: '',
188   - date2: '',
189   - });
190   - nextTick(() => {
191   - tableArray.content.forEach(() => {
192   - handleChange();
193   - });
194   - });
195   - };
196   - defineExpose({
197   - getValue,
198   - setValue,
199   - resetValue,
200   - });
201   -</script>
202   -
203   -<style scoped lang="less">
204   - @table-color: #e5e7eb;
205   -
206   - .table-border-color {
207   - border: 1px solid #e5e7eb;
208   - text-align: center;
209   - }
210   -
211   - .table-content {
212   - overflow-x: auto;
213   -
214   - table {
215   - border-collapse: collapse;
216   - width: 35vw;
217   - &:extend(.table-border-color);
218   - }
219   -
220   - table thead {
221   - white-space: nowrap;
222   - }
223   -
224   - table td {
225   - padding: 5px;
226   - white-space: nowrap;
227   - &:extend(.table-border-color);
228   - }
229   -
230   - table th {
231   - padding: 5px;
232   - &:extend(.table-border-color);
233   - }
234   - }
235   -</style>
... ... @@ -42,43 +42,42 @@
42 42 import { PlusOutlined, MinusOutlined } from '@ant-design/icons-vue';
43 43 import { editTestCellTableTHeaderConfig } from '../../../config/config';
44 44 import { tableItems } from '../../../config/types';
45   - defineProps({
46   - method: {
47   - type: String,
48   - },
49   - });
  45 + import { useUtils } from '../../../hooks/useUtils';
  46 +
  47 + const { CommonFuncValue } = useUtils();
50 48
51 49 const tableArray = reactive<{
52 50 content: tableItems[];
53 51 }>({
54 52 content: [
55 53 {
56   - key: 'ContentType',
57   - value: 'none',
  54 + key: '',
  55 + value: '',
58 56 required: false,
59 57 },
60 58 ],
61 59 });
62 60
63   - // 新增
64 61 const add = (_, index: number) => {
65 62 tableArray.content.splice(index + 1, 0, {
66   - key: 'ContentType',
67   - value: 'none',
  63 + key: '',
  64 + value: '',
68 65 required: false,
69 66 });
70 67 };
71 68
72   - // 减少
73 69 const remove = (index: number) => {
74   - if (tableArray.content.length !== 1) {
  70 + if (tableArray.content.length > 1) {
75 71 tableArray.content.splice(index, 1);
  72 + } else {
  73 + resetValue();
76 74 }
77 75 };
78 76
79 77 //获取数据
80 78 const getValue = () => {
81   - return tableArray.content;
  79 + const newFuncValue = new CommonFuncValue(tableArray.content as tableItems[]);
  80 + return newFuncValue.get();
82 81 };
83 82
84 83 //设置数据
... ... @@ -104,35 +103,5 @@
104 103 </script>
105 104
106 105 <style scoped lang="less">
107   - @table-color: #e5e7eb;
108   -
109   - .table-border-color {
110   - border: 1px solid #e5e7eb;
111   - text-align: center;
112   - }
113   -
114   - .table-content {
115   - overflow-x: auto;
116   -
117   - table {
118   - border-collapse: collapse;
119   - width: 35vw;
120   - &:extend(.table-border-color);
121   - }
122   -
123   - table thead {
124   - white-space: nowrap;
125   - }
126   -
127   - table td {
128   - padding: 5px;
129   - white-space: nowrap;
130   - &:extend(.table-border-color);
131   - }
132   -
133   - table th {
134   - padding: 5px;
135   - &:extend(.table-border-color);
136   - }
137   - }
  106 + @import '../common/commonTable.less';
138 107 </style>
... ...
1 1 <template>
2 2 <div class="flex flex-col justify-between">
3   - <div ref="jsoneditorRef" style="height: 100%; width: 100%"></div>
  3 + <div ref="jsoneditorRef" style="height: 100%"></div>
4 4 <div class="ml-2 -mt-1.5">
5 5 <Button v-if="showBtn" @click="onHandleCopy" class="mt-8 -ml-2">
6 6 <template #icon>
... ...
... ... @@ -14,7 +14,6 @@
14 14 </td>
15 15 <td style="width: 12vw">
16 16 <Select
17   - :disabled="item.key === 'agg,interval' ? true : false"
18 17 v-model:value="item.key"
19 18 placeholder="请选择"
20 19 :options="selectOptions"
... ... @@ -23,12 +22,12 @@
23 22 allowClear
24 23 />
25 24 </td>
26   - <td style="width: 12vw">
  25 + <td>
27 26 <div v-if="item.key === 'date_range'">
28   - <div>
29   - <a-input style="width: 6vw" placeholder="请输入" v-model:value="item.date1" />
  27 + <div class="flex">
  28 + <a-input placeholder="请输入" v-model:value="item.date1" />
30 29 <span>~</span>
31   - <a-input style="width: 6vw" placeholder="请输入" v-model:value="item.date2" />
  30 + <a-input placeholder="请输入" v-model:value="item.date2" />
32 31 </div>
33 32 <div class="flex mt-2">
34 33 <a-checkbox @change="onHandleCheck" v-model:checked="mores">更多选项</a-checkbox>
... ... @@ -43,15 +42,15 @@
43 42 />
44 43 </div>
45 44 </td>
46   - <td style="width: 4vw">
  45 + <td>
47 46 <a-switch v-model:checked="item.required" />
48 47 </td>
49   - <td style="width: 4vw">
  48 + <td>
50 49 <div>
51 50 <Button type="dashed" @click="add(item, index)">
52 51 <template #icon><PlusOutlined /></template
53 52 ></Button>
54   - <Button type="dashed" style="margin-left: 5px" @click="remove(item, index)">
  53 + <Button type="dashed" class="ml-1" @click="remove(item, index)">
55 54 <template #icon> <MinusOutlined /></template>
56 55 </Button>
57 56 </div>
... ... @@ -60,18 +59,6 @@
60 59 </tbody>
61 60 </table>
62 61 </div>
63   - <BasicModal
64   - @register="registerModal"
65   - title=""
66   - width="40%"
67   - :minHeight="90"
68   - wrap-class-name="history-trend-model"
69   - :canFullscreen="false"
70   - @cancel="handleCancelModal"
71   - @ok="onHandleModal"
72   - >
73   - <DateRangeSelect ref="dateRangeSelectRef" />
74   - </BasicModal>
75 62 </template>
76 63 <script lang="ts" setup name="editCellTable">
77 64 import { reactive, ref, onMounted, nextTick } from 'vue';
... ... @@ -80,42 +67,16 @@
80 67 import { PlusOutlined, MinusOutlined } from '@ant-design/icons-vue';
81 68 import { editCellTableTHeadConfig } from '../../../config/config';
82 69 import { selectType, tableItems } from '../../../config/types';
83   - import { useModal, BasicModal } from '/@/components/Modal';
84   - import DateRangeSelect from './DateRangeSelect/index.vue';
  70 + import { useUtils } from '../../../hooks/useUtils';
85 71
86   - defineProps({
87   - method: {
88   - type: String,
89   - },
90   - });
  72 + const { ParamsFuncValue } = useUtils();
91 73
92 74 const selectOptions = ref<selectType[]>([]);
93 75
94   - const dateRangeSelectRef = ref<InstanceType<typeof DateRangeSelect>>();
95   -
96   - const [registerModal, { closeModal }] = useModal();
97   -
98 76 const mores = ref(false);
99 77
100 78 const onHandleCheck = ({ target }) => {
101 79 mores.value = target?.checked;
102   - if (mores.value) {
103   - // openModal(true);
104   - }
105   - };
106   -
107   - const handleCancelModal = () => {
108   - closeModal();
109   - dateRangeSelectRef.value?.resetValue();
110   - mores.value = false;
111   - };
112   -
113   - const getDateRangeValue = ref<any>({});
114   -
115   - const onHandleModal = () => {
116   - const values = dateRangeSelectRef.value?.getValue();
117   - getDateRangeValue.value = values;
118   - closeModal();
119 80 };
120 81
121 82 onMounted(() => {
... ... @@ -146,7 +107,6 @@
146 107 ],
147 108 });
148 109
149   - // 新增
150 110 const add = (_, index: number) => {
151 111 tableArray.content.splice(index + 1, 0, {
152 112 key: undefined,
... ... @@ -158,7 +118,6 @@
158 118 });
159 119 };
160 120
161   - // 减少
162 121 const remove = (item, index: number) => {
163 122 if (tableArray.content.length > 1) {
164 123 selectOptions.value.forEach((ele) => {
... ... @@ -177,44 +136,34 @@
177 136 selectOptions.value.forEach((ele) => {
178 137 ele.disabled = false;
179 138 tableArray.content.forEach((element) => {
180   - if (element.key === 'scope' || element.key === 'fixed_date') {
  139 + if (element.key === 'scope') {
181 140 element.editDisabled = false;
182 141 } else {
183 142 element.value = '';
184 143 element.editDisabled = true;
185 144 }
186   - if (element.key === ele.value && element.key !== 'scope' && element.key !== 'fixed_date') {
  145 + if (element.key === ele.value && element.key !== 'scope') {
187 146 ele.disabled = true;
188 147 }
189 148 });
190 149 });
191 150 };
192 151
  152 + //fix 解决编辑回显下拉框已选择应禁用问题
193 153 const hanldeDropdownVisibleChange = () => handleChange();
194 154
  155 + const commonHandleChange = (tableArray) => {
  156 + nextTick(() => {
  157 + tableArray.forEach(() => {
  158 + handleChange();
  159 + });
  160 + });
  161 + };
  162 +
195 163 //获取数据
196 164 const getValue = () => {
197   - let assemblyData: any = tableArray.content.map((it) => {
198   - return {
199   - key: it.key,
200   - value: it.key === 'date_range' ? `${it.date1},${it.date2}` : it.value,
201   - mores: it.key === 'date_range' ? mores.value : null,
202   - editDisabled: it.editDisabled,
203   - required: it.required,
204   - };
205   - });
206   - // assemblyData = assemblyData.filter((item) => item.key !== 'agg,interval');
207   - // if (getDateRangeValue.value) {
208   - // const joinStr = Object.keys(getDateRangeValue.value)?.join(',');
209   - // if (mores.value) {
210   - // assemblyData.push({
211   - // key: joinStr,
212   - // value: '',
213   - // mores: mores.value,
214   - // });
215   - // }
216   - // }
217   - return assemblyData;
  165 + const paramsFuncValue = new ParamsFuncValue(tableArray.content as any, mores.value);
  166 + return paramsFuncValue.get();
218 167 };
219 168
220 169 //设置数据
... ... @@ -233,17 +182,11 @@
233 182 const findIsDateRange = data.find((it) => it?.mores === true);
234 183 if (findIsDateRange?.mores) {
235 184 mores.value = findIsDateRange?.mores;
236   - getDateRangeValue.value = {
237   - agg: 'agg',
238   - interval: 'interval',
239   - };
240 185 } else {
241 186 assemblyData = assemblyData.filter((item) => item?.mores == false || !item?.mores);
242 187 }
243 188 tableArray.content = assemblyData;
244   - tableArray.content.forEach(() => {
245   - handleChange();
246   - });
  189 + commonHandleChange(tableArray.content);
247 190 };
248 191
249 192 //重置数据
... ... @@ -258,11 +201,7 @@
258 201 date1: '',
259 202 date2: '',
260 203 });
261   - nextTick(() => {
262   - tableArray.content.forEach(() => {
263   - handleChange();
264   - });
265   - });
  204 + commonHandleChange(tableArray.content);
266 205 };
267 206 defineExpose({
268 207 getValue,
... ... @@ -272,35 +211,5 @@
272 211 </script>
273 212
274 213 <style scoped lang="less">
275   - @table-color: #e5e7eb;
276   -
277   - .table-border-color {
278   - border: 1px solid #e5e7eb;
279   - text-align: center;
280   - }
281   -
282   - .table-content {
283   - overflow-x: auto;
284   -
285   - table {
286   - border-collapse: collapse;
287   - width: 35vw;
288   - &:extend(.table-border-color);
289   - }
290   -
291   - table thead {
292   - white-space: nowrap;
293   - }
294   -
295   - table td {
296   - padding: 5px;
297   - white-space: nowrap;
298   - &:extend(.table-border-color);
299   - }
300   -
301   - table th {
302   - padding: 5px;
303   - &:extend(.table-border-color);
304   - }
305   - }
  214 + @import '../common/commonTable.less';
306 215 </style>
... ...
1 1 <template>
2 2 <div>
3   - <!--TODO: 待优化三者共存下的测试和是否能复用表格 -->
4   - <Tabs @change="handleChange" v-model:activeKey="activeKey">
5   - <TabPane class="tab-pane" forceRender key="Params" tab="Params">
6   - <ParamsTable ref="paramsCellTableRef" :method="method" />
7   - <ParamsTest
8   - @testParamsInterface="handleTestParamsInterface"
9   - @closeTest="onCloseTest"
10   - ref="testParamsRequestRef"
11   - :data="dataMap.mapParamsObj"
12   - :interfaceType="interfaceType"
13   - />
14   - </TabPane>
15   - <TabPane
16   - v-if="method !== '2' && requestTypeAndUrl?.requestHttpType !== 'GET'"
17   - class="tab-pane"
18   - forceRender
19   - key="Body"
20   - tab="Body"
21   - >
22   - <Body ref="bodyRef" @resetValue="handleResetValue" />
23   - <BodyTest
24   - v-if="bodyType !== 'none'"
25   - @testBodyInterface="handleTestBodyInterface"
26   - @closeTest="onCloseTest"
27   - ref="testBodyRequestRef"
28   - :interfaceType="interfaceType"
29   - :data="dataMap.mapBodyObj"
30   - />
31   - </TabPane>
32   - <TabPane v-if="method !== '2'" class="tab-pane" forceRender key="Header" tab="Header">
33   - <HeaderTable ref="editHeaderCellTableRef" :method="method" />
34   - <HeaderTest
35   - @testHeaderInterface="handleTestHeaderInterface"
36   - @closeTest="onCloseTest"
37   - ref="testHeaderRequestRef"
38   - :interfaceType="interfaceType"
39   - :data="dataMap.mapHeaderObj"
40   - />
41   - </TabPane>
42   - </Tabs>
43   - <ExcuteTest ref="excuteTestRef" @emitExcute="handleEmitExcute" :data="excuteData" />
  3 + <div>
  4 + <Tabs @change="handleChange" v-model:activeKey="activeKey">
  5 + <TabPane class="tab-pane" forceRender key="Params" tab="Params">
  6 + <ParamsTable ref="paramsCellTableRef" />
  7 + <ParamsTest
  8 + @testParamsInterface="handleTestParamsInterface"
  9 + @closeTest="onCloseTest"
  10 + ref="testParamsRequestRef"
  11 + :data="dataMap.mapParamsObj"
  12 + :interfaceType="interfaceType"
  13 + />
  14 + </TabPane>
  15 + <TabPane
  16 + v-if="
  17 + method !== RequestMethodTypeEnum.WEBSOCKET &&
  18 + requestTypeAndUrl?.requestHttpType !== RequestHttpTypeEnum.GET
  19 + "
  20 + class="tab-pane"
  21 + forceRender
  22 + key="Body"
  23 + tab="Body"
  24 + >
  25 + <Body ref="bodyRef" @resetValue="handleResetValue" />
  26 + <BodyTest
  27 + v-if="bodyType !== RequestBodyTypeEnum.NONE"
  28 + @testBodyInterface="handleTestBodyInterface"
  29 + @closeTest="onCloseTest"
  30 + ref="testBodyRequestRef"
  31 + :interfaceType="interfaceType"
  32 + :data="dataMap.mapBodyObj"
  33 + />
  34 + </TabPane>
  35 + <TabPane
  36 + v-if="method !== RequestMethodTypeEnum.WEBSOCKET"
  37 + class="tab-pane"
  38 + forceRender
  39 + key="Header"
  40 + tab="Header"
  41 + >
  42 + <HeaderTable ref="editHeaderCellTableRef" />
  43 + <HeaderTest
  44 + @testHeaderInterface="handleTestHeaderInterface"
  45 + @closeTest="onCloseTest"
  46 + ref="testHeaderRequestRef"
  47 + :interfaceType="interfaceType"
  48 + :data="dataMap.mapHeaderObj"
  49 + />
  50 + </TabPane>
  51 + </Tabs>
  52 + </div>
  53 + <div>
  54 + <ExcuteTest
  55 + ref="excuteTestRef"
  56 + @emitExcute="handleEmitExcute"
  57 + :data="excuteData"
  58 + :method="method"
  59 + :httpType="requestTypeAndUrl?.requestHttpType"
  60 + />
  61 + </div>
44 62 </div>
45 63 </template>
46 64 <script lang="ts" setup name="simpleRequest">
... ... @@ -53,6 +71,12 @@
53 71 import { isEmpty } from '/@/utils/is';
54 72 import { useUtils } from '../../hooks/useUtils';
55 73 import ExcuteTest from '../TestInterface/components/excuteTest.vue';
  74 + import {
  75 + RequestMethodTypeEnum,
  76 + RequestHttpTypeEnum,
  77 + RequestBodyTypeEnum,
  78 + RequestOriginTypeEnum,
  79 + } from '../../config/enum';
56 80
57 81 const props = defineProps({
58 82 method: {
... ... @@ -127,18 +151,18 @@
127 151
128 152 const handleEmitExcute = () => {
129 153 let apiGetUrl = '';
130   - if (props?.method === '2') {
131   - if (props?.originUrlType === 'server_url') {
  154 + if (props?.method === RequestMethodTypeEnum.WEBSOCKET) {
  155 + if (props?.originUrlType === RequestOriginTypeEnum.SERVER_URL) {
132 156 const pathUrl = window.location.host;
133 157 const protocol = window.location.protocol;
134 158 apiGetUrl = `${
135   - protocol === 'http' ? 'ws:' : protocol === 'https' ? 'wss:' : 'ws:'
  159 + protocol === 'http:' ? 'ws:' : protocol === 'https:' ? 'wss:' : 'ws:'
136 160 }//${pathUrl}${props?.requestTypeAndUrl?.requestUrl}`;
137 161 } else {
138 162 apiGetUrl = `${props?.requestOriginUrl}${props?.requestTypeAndUrl?.requestUrl}`;
139 163 }
140 164 } else {
141   - if (props?.originUrlType === 'server_url') {
  165 + if (props?.originUrlType === RequestOriginTypeEnum.SERVER_URL) {
142 166 const pathUrl = window.location.host;
143 167 const protocol = window.location.protocol;
144 168 apiGetUrl = `${protocol}//${pathUrl}${props?.requestTypeAndUrl?.requestUrl}`;
... ... @@ -215,6 +239,11 @@
215 239 };
216 240 };
217 241
  242 + //获取编写过滤器里的数
  243 + const getFilterValue = () => {
  244 + return excuteTestRef?.value?.getFilterValue();
  245 + };
  246 +
218 247 //设置数据
219 248 const setValue = (data, flag, defaultValue) => {
220 249 if (!flag) {
... ... @@ -247,6 +276,7 @@
247 276 getValue,
248 277 setValue,
249 278 resetValue,
  279 + getFilterValue,
250 280 });
251 281 </script>
252 282
... ...
... ... @@ -2,28 +2,10 @@
2 2 <div>
3 3 <div class="mt-8">
4 4 <div class="flex">
5   - <div class="flex" v-if="interfaceType === 'SYSTEM' && isAdmin(role)">
6   - <Select
7   - v-model:value="selectTenant"
8   - allowClear
9   - @change="onSelect"
10   - style="width: 150px"
11   - placeholder="请选择租户"
12   - :options="selectOptions"
13   - />
14   - <Select
15   - v-model:value="selectSysTenant"
16   - allowClear
17   - @change="onSelctTenant"
18   - style="width: 150px; margin-left: 10px"
19   - v-if="selectTenantOptions.length > 0"
20   - placeholder="请选择租户"
21   - :options="selectTenantOptions"
22   - />
23   - </div>
  5 + <SelectTenant :interfaceType="interfaceType" @emitToken="onHandleEmitToken" />
  6 + <div v-if="role === 'SYS_ADMIN'" class="ml-2"></div>
24 7 <Button
25 8 :disabled="interfaceType === 'SYSTEM' && isAdmin(role) ? testDisabled : false"
26   - class="ml-2"
27 9 @click="handleTest(isSingleClickText)"
28 10 type="primary"
29 11 >{{ `${isSingleClickText === 'open' ? '打开' : '关闭'}测试接口` }}
... ... @@ -33,37 +15,44 @@
33 15 <a-row type="flex" justify="center">
34 16 <a-col :span="3"> 参数设置 </a-col>
35 17 <a-col :span="21">
36   - <div v-if="data?.type === 'x-www-form-urlencoded' || data?.type === 'form-data'">
  18 + <div
  19 + v-if="
  20 + data?.type === RequestBodyTypeEnum.XWWW ||
  21 + data?.type === RequestBodyTypeEnum.FORMDATA
  22 + "
  23 + >
37 24 <TestBodyCellTable :token="getToken" ref="testEditCellTableRef" />
38 25 </div>
39   - <div style="width: 30vw" v-else-if="data?.type === 'json'">
  26 + <div style="width: 30vw" v-else-if="data?.type === RequestBodyTypeEnum.JSON">
40 27 <JsonEditor :showBtn="false" style="width: 35vw; height: 30vh" ref="jsonEditorRef" />
41 28 </div>
42   - <div style="width: 30vw" v-else-if="data?.type === 'xml'">
43   - <a-textarea v-model:value="xmlContent" placeholder="请输入xml" :rows="6" />
  29 + <div style="width: 30vw" v-else-if="data?.type === RequestBodyTypeEnum.XML">
  30 + <AceTypeXmlEditor ref="aceEditorRef" :scriptType="OnlineEditorTypeEnum.XML" />
44 31 </div>
45 32 </a-col>
46 33 </a-row>
47 34 </div>
48 35 </div>
49   - <div class="mt-8"> </div>
50 36 </div>
51 37 </template>
52 38 <script lang="ts" setup name="testRequest">
53   - import { ref, nextTick, onMounted } from 'vue';
  39 + import { ref, nextTick } from 'vue';
54 40 import { Button } from 'ant-design-vue';
55   - import TestBodyCellTable from './testEditBodyCellTable.vue';
  41 + import TestBodyCellTable from '../paramsTest/testEditParamsCellTable.vue';
56 42 import moment from 'moment';
57 43 import { useUtils } from '../../../hooks/useUtils';
58 44 import JsonEditor from '../../SimpleRequest/components/jsonEditor.vue';
59 45 import { useMessage } from '/@/hooks/web/useMessage';
60   - import { getTenantAllPageLists, getTenantPageList } from '/@/api/tenant/tenantApi';
61   - import { selectType } from '../../../config/types';
62   - import { Select } from 'ant-design-vue';
63   - import { getUserToken } from '/@/api/sys/user';
64 46 import { USER_INFO_KEY } from '/@/enums/cacheEnum';
65 47 import { getAuthCache } from '/@/utils/auth';
66 48 import { isAdmin } from '/@/enums/roleEnum';
  49 + import AceTypeXmlEditor from '../../SimpleRequest/components/aceEditor.vue';
  50 + import {
  51 + OnlineEditorTypeEnum,
  52 + RequestBodyTypeEnum,
  53 + TableDefaultTypeEnum,
  54 + } from '../../../config/enum';
  55 + import SelectTenant from '../components/selectTenant.vue';
67 56
68 57 const userInfo: any = getAuthCache(USER_INFO_KEY);
69 58
... ... @@ -80,21 +69,6 @@
80 69 },
81 70 });
82 71
83   - onMounted(async () => {
84   - if (isAdmin(role)) {
85   - const res = await getTenantPageList();
86   - selectOptions.value = res.map((m) => ({ label: m.name, value: m.tenantId }));
87   - } else {
88   - //租户
89   - const { token } = await getUserToken(userInfo?.userId);
90   - getToken.value = token;
91   - }
92   - });
93   -
94   - const selectOptions = ref<selectType[]>([]);
95   -
96   - const selectTenantOptions = ref<selectType[]>([]);
97   -
98 72 const { createMessage } = useMessage();
99 73
100 74 const showTestEditCell = ref(false);
... ... @@ -103,52 +77,26 @@
103 77
104 78 const excuteData = ref({});
105 79
106   - const selectTenant = ref(undefined);
107   -
108   - const selectSysTenant = ref(undefined);
109   -
110   - const xmlContent = ref('');
111   -
112 80 const testEditCellTableRef = ref<InstanceType<typeof TestBodyCellTable>>();
113 81
114 82 const jsonEditorRef = ref<InstanceType<typeof JsonEditor>>();
115 83
  84 + const aceEditorRef = ref<InstanceType<typeof AceTypeXmlEditor>>();
  85 +
116 86 const testResult = ref('');
117 87
118 88 const { getMultipleKeys } = useUtils();
119 89
120 90 const getToken = ref('');
121 91
122   - const onSelect = async (e) => {
123   - if (e) {
124   - testDisabled.value = false;
125   - } else {
126   - testDisabled.value = true;
127   - }
128   - selectSysTenant.value = undefined;
129   - const rest = (await getTenantAllPageLists(e)) as any;
130   - selectTenantOptions.value = rest?.map((m) => ({ label: m.realName, value: m.id }));
131   - };
  92 + const isSingleClickText = ref('open');
132 93
133   - const onSelctTenant = async (e) => {
134   - if (e) {
135   - testDisabled.value = false;
136   - } else {
137   - testDisabled.value = true;
138   - }
139   - const { token } = await getUserToken(e);
  94 + const onHandleEmitToken = (token, flag) => {
140 95 getToken.value = token;
  96 + testDisabled.value = flag;
141 97 };
142 98
143   - const isSingleClickText = ref('open');
144   -
145 99 const handleTest = (o) => {
146   - if (isAdmin(role)) {
147   - if (!selectTenant.value || !selectSysTenant.value) {
148   - createMessage.error('请选择租户或者租户管理员');
149   - throw Error('请选择租户或者租户管理员');
150   - }
151   - }
152 100 if (o === 'open') {
153 101 showTestEditCell.value = true;
154 102 emits('testBodyInterface');
... ... @@ -163,8 +111,10 @@
163 111 const getValue = async () => {
164 112 await nextTick();
165 113 await nextTick(() => {
166   - console.log(props.data?.list);
167   - if (props.data?.type === 'x-www-form-urlencoded' || props.data?.type === 'form-data') {
  114 + if (
  115 + props.data?.type === RequestBodyTypeEnum.XWWW ||
  116 + props.data?.type === RequestBodyTypeEnum.FORMDATA
  117 + ) {
168 118 const getSingleKey = props.data?.list;
169 119 const getMuteKey = props.data?.list?.filter((it: any) => it.key.split(',').length > 1);
170 120 const getMuteKeys = getMultipleKeys(getMuteKey);
... ... @@ -172,10 +122,10 @@
172 122 (it: any) => it.key.split(',').length === 1
173 123 );
174 124 testEditCellTableRef.value?.setTableArray(mergeKeys);
175   - } else if (props.data?.type === 'json') {
  125 + } else if (props.data?.type === RequestBodyTypeEnum.JSON) {
176 126 jsonEditorRef.value?.setJsonValue(props.data?.list);
177   - } else if (props.data?.type === 'xml') {
178   - xmlContent.value = props.data?.list;
  127 + } else if (props.data?.type === RequestBodyTypeEnum.XML) {
  128 + aceEditorRef?.value?.setValue(props.data?.list);
179 129 }
180 130 });
181 131 };
... ... @@ -186,8 +136,9 @@
186 136 //把日期拆分成多个
187 137 const keyValueList: any = [];
188 138 testEditCellTableRef.value?.getValue()?.forEach((item: any) => {
189   - const splitDateKey = item?.key === 'date_range' ? item?.value?.split(',') : [];
190   - const splitDateValue = item?.key === 'date_range' ? item?.dateValue : [];
  139 + const splitDateKey =
  140 + item?.key === TableDefaultTypeEnum.DATERANGE ? item?.value?.split(',') : [];
  141 + const splitDateValue = item?.key === TableDefaultTypeEnum.DATERANGE ? item?.dateValue : [];
191 142 for (let i in splitDateKey) {
192 143 const obj = {
193 144 key: splitDateKey[i],
... ... @@ -199,15 +150,10 @@
199 150 return testEditCellTableRef.value
200 151 ?.getValue()
201 152 .concat(keyValueList)
202   - .filter((it) => it.key !== 'date_range')
  153 + .filter((it) => it.key !== TableDefaultTypeEnum.DATERANGE)
203 154 .map((it: any) => {
204   - const value =
205   - it?.key === 'scope'
206   - ? it?.keyValue
207   - : it?.key === 'fixed_date'
208   - ? moment(it?.fixed_date_value).valueOf()
209   - : it?.value;
210   - const key = it?.key === 'scope' || it?.key === 'fixed_date' ? it?.value : it?.key;
  155 + const value = it?.key === TableDefaultTypeEnum.SCOPE ? it?.keyValue : it?.value;
  156 + const key = it?.key === TableDefaultTypeEnum.SCOPE ? it?.value : it?.key;
211 157 return {
212 158 key,
213 159 value,
... ... @@ -219,7 +165,10 @@
219 165 //获取数据
220 166 const getTestValue = () => {
221 167 let params: any = {};
222   - if (props.data?.type === 'x-www-form-urlencoded' || props.data?.type === 'form-data') {
  168 + if (
  169 + props.data?.type === RequestBodyTypeEnum.XWWW ||
  170 + props.data?.type === RequestBodyTypeEnum.FORMDATA
  171 + ) {
223 172 const getTable = getTestTableKeyValue();
224 173 const hasRequired = getTable?.some((it) => it.required === true && !it.value);
225 174 if (hasRequired) {
... ... @@ -227,10 +176,10 @@
227 176 throw new Error('参数不能为空');
228 177 }
229 178 getTable?.map((it) => (params[it.key!] = it.value!));
230   - } else if (props.data?.type === 'json') {
  179 + } else if (props.data?.type === RequestBodyTypeEnum.JSON) {
231 180 params = jsonEditorRef.value?.getJsonValue();
232   - } else if (props.data?.type === 'xml') {
233   - params = xmlContent.value;
  181 + } else if (props.data?.type === RequestBodyTypeEnum.XML) {
  182 + params = aceEditorRef?.value?.getValue();
234 183 }
235 184 if (params['keys']) {
236 185 Reflect.set(params, 'keys', params['keys'].join(','));
... ... @@ -245,11 +194,9 @@
245 194
246 195 //设置数据
247 196 const setValue = () => {
  197 + isSingleClickText.value = 'open';
248 198 showTestEditCell.value = false;
249 199 testResult.value = '';
250   - selectTenant.value = undefined;
251   - selectSysTenant.value = undefined;
252   - selectTenantOptions.value = [];
253 200 };
254 201
255 202 const onCloseTest = () => {
... ...
1   -<!-- eslint-disable vue/valid-v-model -->
2   -<template>
3   - <div class="table-content">
4   - <!-- TODO: 待优化测试表格 -->
5   - <table align="center">
6   - <thead>
7   - <tr>
8   - <th v-for="item in editTestCellTableTHeadConfig" :key="item">
9   - <a-tooltip v-if="item === '参数值'">
10   - <template #title>当自定义为entityType,应输入DEVICE</template>
11   - <QuestionCircleOutlined :style="{ fontSize: '14px', marginLeft: '5px' }" />
12   - </a-tooltip>
13   - {{ item }}
14   - </th>
15   - </tr>
16   - </thead>
17   - <tbody>
18   - <tr v-for="(item, index) in tableTestArray.content" :key="index">
19   - <td style="width: 7.5vw">
20   - <Select
21   - :getPopupContainer="
22   - (triggerNode) => {
23   - return triggerNode.parentNode;
24   - }
25   - "
26   - :disabled="true"
27   - v-model:value="item.key"
28   - placeholder="请选择"
29   - :options="selectOptions"
30   - />
31   - </td>
32   - <td style="width: 6.5vw">
33   - <a-input v-if="item.key === 'scope'" placeholder="请输入" v-model:value="item.value" />
34   - <a-tree-select
35   - :getPopupContainer="
36   - (triggerNode) => {
37   - return triggerNode.parentNode;
38   - }
39   - "
40   - v-else-if="item.key === 'organizationId'"
41   - v-model:value="item.value"
42   - show-search
43   - :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
44   - placeholder="请选择组织"
45   - allow-clear
46   - tree-default-expand-all
47   - :tree-data="treeData"
48   - @change="handleOrgnationChange(item)"
49   - />
50   - <Select
51   - :getPopupContainer="
52   - (triggerNode) => {
53   - return triggerNode.parentNode;
54   - }
55   - "
56   - v-else-if="item.key === 'entityId'"
57   - v-model:value="item.value"
58   - placeholder="请选择"
59   - notFoundContent="请选择"
60   - :options="entityOptions"
61   - allowClear
62   - />
63   - <Select
64   - :getPopupContainer="
65   - (triggerNode) => {
66   - return triggerNode.parentNode;
67   - }
68   - "
69   - v-else-if="item.key === 'keys'"
70   - v-model:value="item.value"
71   - placeholder="请选择"
72   - notFoundContent="请选择"
73   - :options="attributeOptions"
74   - mode="multiple"
75   - allowClear
76   - />
77   - <div v-else-if="item.key === 'date_range'">
78   - <a-button disabled type="primary">{{ item.value?.split(',').at(-2) }}</a-button>
79   - <span>~</span>
80   - <a-button disabled type="primary">{{ item.value?.split(',').at(-1) }}</a-button>
81   - </div>
82   - <div v-else-if="item.key === 'fixed_date'">
83   - <a-button disabled type="primary">{{ item.value }}</a-button>
84   - </div>
85   - <Select
86   - :getPopupContainer="
87   - (triggerNode) => {
88   - return triggerNode.parentNode;
89   - }
90   - "
91   - v-else
92   - v-model:value="item.value"
93   - placeholder="请选择"
94   - notFoundContent="请选择"
95   - :options="valueOptions"
96   - allowClear
97   - @change="handleValueChange(item)"
98   - />
99   - </td>
100   - <td style="width: 6.5vw">
101   - <a-input
102   - v-if="item.key === 'scope'"
103   - placeholder="请输入"
104   - v-model:value="item.keyValue"
105   - />
106   - <a-date-picker
107   - v-else-if="item.key === 'fixed_date'"
108   - style="width: 6.5vw"
109   - v-model:value="item.keyValue"
110   - :show-time="{ format: 'HH:mm' }"
111   - format="YYYY-MM-DD HH:mm:ss"
112   - placeholder="日期时间"
113   - />
114   - <a-range-picker
115   - v-else-if="item.key == 'date_range'"
116   - style="width: 6.5vw"
117   - v-model:value="item.dateValue"
118   - :show-time="{ format: 'HH:mm' }"
119   - format="YYYY-MM-DD HH:mm"
120   - :placeholder="['开始', '结束']"
121   - />
122   - <a-input v-else disabled placeholder="请输入" v-model:value="item.keyValue" />
123   - </td>
124   - </tr>
125   - </tbody>
126   - </table>
127   - </div>
128   -</template>
129   -<script lang="ts" setup name="editCellTable">
130   - import { reactive, ref, onMounted } from 'vue';
131   - import { Select } from 'ant-design-vue';
132   - import { findDictItemByCode } from '/@/api/system/dict';
133   - import { useApi } from '../../../hooks/useApi';
134   - import { useUtils } from '../../../hooks/useUtils';
135   - import { cloneDeep } from 'lodash-es';
136   - import { tableItems, selectType } from '../../../config/types';
137   - import { editTestCellTableTHeadConfig } from '../../../config/config';
138   - import { QuestionCircleOutlined } from '@ant-design/icons-vue';
139   -
140   - const props = defineProps({
141   - method: {
142   - type: String,
143   - },
144   - token: {
145   - type: String,
146   - },
147   - });
148   -
149   - onMounted(async () => {
150   - const res = await findDictItemByCode({ dictCode: 'dataview_builtin_params' });
151   - selectOptions.value = res.map((m) => ({ label: m.itemText, value: m.itemValue }));
152   - selectOptions.value.push({
153   - label: '自定义',
154   - value: 'scope',
155   - });
156   - if (props.method === '2')
157   - selectOptions.value = selectOptions.value.filter((f) => f.value !== 'scope');
158   - });
159   -
160   - const { isOtherHttp } = useUtils();
161   -
162   - const selectOptions = ref<selectType[]>([]);
163   -
164   - const valueOptions = ref<selectType[]>([]);
165   -
166   - const entityOptions = ref<selectType[]>([]);
167   -
168   - const attributeOptions = ref<selectType[]>([]);
169   -
170   - const treeData = ref([]);
171   -
172   - const tableTestArray = reactive<{
173   - content: tableItems[];
174   - }>({
175   - content: [
176   - {
177   - key: undefined,
178   - value: undefined,
179   - keyValue: null,
180   - editDisabled: false,
181   - dateValue: null,
182   - },
183   - ],
184   - });
185   -
186   - //设置数据
187   - const setTableArray = (data) => {
188   - const list = cloneDeep(data);
189   - list?.forEach((it) => {
190   - if (it.key === 'keys') it.value = [];
191   - });
192   - if (Array.isArray(list)) (tableTestArray.content = list) && getApi(list);
193   - if (list.hasOwnProperty('form-data') && Array.isArray(list['form-data']))
194   - (tableTestArray.content = list['form-data']) && getApi(list['form-data']);
195   - if (
196   - list.hasOwnProperty('x-www-form-urlencoded') &&
197   - Array.isArray(list['x-www-form-urlencoded'])
198   - )
199   - (tableTestArray.content = list['x-www-form-urlencoded']) &&
200   - getApi(list['x-www-form-urlencoded']);
201   - };
202   -
203   - const getApi = (list) => {
204   - list?.forEach(async (it) => {
205   - if (it.key === 'deviceProfileId') {
206   - const { options } = await useApi(it.key, props.token);
207   - valueOptions.value = options;
208   - } else if (it.key === 'organizationId') {
209   - const { options } = await useApi(it.key, props.token);
210   - treeData.value = options as any;
211   - }
212   - });
213   - };
214   -
215   - const handleOrgnationChange = async (e) => {
216   - let deviceProfileId = '';
217   - tableTestArray.content.forEach((f: any) => {
218   - if (f.key === 'entityId') {
219   - f.value = null;
220   - }
221   - if (f.key === 'deviceProfileId') deviceProfileId = f.value;
222   - });
223   - getEntityOptions(e.value, deviceProfileId);
224   - };
225   -
226   - const getEntityOptions = async (organizationId: string, deviceProfileId?: string) => {
227   - const res = await isOtherHttp('api/yt/device/list', props.token, {
228   - organizationId,
229   - deviceProfileId,
230   - });
231   - entityOptions.value = res.map((item) => ({
232   - label: item.alias || item.name,
233   - value: item.tbDeviceId,
234   - }));
235   - };
236   -
237   - const getAttributeOptions = async (params) => {
238   - const { deviceProfileId, dataType } = params;
239   - const res = await isOtherHttp(`api/yt/device/attributes/${deviceProfileId}`, props.token, {
240   - dataType,
241   - });
242   - if (Object.keys(res).length === 0) return (attributeOptions.value.length = 0);
243   - attributeOptions.value = res?.map((item) => ({ label: item.name, value: item.identifier }));
244   - };
245   -
246   - const handleValueChange = (e) => {
247   - let organizationId = '';
248   - if (e.key === 'deviceProfileId') {
249   - tableTestArray.content.forEach((f: any) => {
250   - if (f.key === 'keys') {
251   - f.value = [];
252   - }
253   - if (f.key === 'organizationId') organizationId = f.value;
254   - if (f.key === 'entityId') f.value = null;
255   - });
256   - if (e.value) {
257   - getAttributeOptions({ deviceProfileId: e.value });
258   - }
259   - if (organizationId !== '') {
260   - getEntityOptions(organizationId, e.value);
261   - }
262   - }
263   - };
264   -
265   - //获取数据
266   - const getValue = () => {
267   - return tableTestArray.content;
268   - };
269   - defineExpose({
270   - getValue,
271   - setTableArray,
272   - });
273   -</script>
274   -
275   -<style scoped lang="less">
276   - @table-color: #e5e7eb;
277   -
278   - .table-border-color {
279   - border: 1px solid #e5e7eb;
280   - text-align: center;
281   - }
282   -
283   - .table-content {
284   - table {
285   - width: 31vw;
286   - &:extend(.table-border-color);
287   - }
288   -
289   - table td {
290   - padding: 5px;
291   - white-space: nowrap;
292   - &:extend(.table-border-color);
293   - }
294   -
295   - table th {
296   - padding: 5px;
297   - &:extend(.table-border-color);
298   - }
299   - }
300   -</style>
... ... @@ -4,7 +4,7 @@
4 4 <a-row>
5 5 <Button @click="handleExcute" type="primary"> 执行测试请求 </Button>
6 6 </a-row>
7   - <div v-if="isShowTestResult" style="display: flex; justify-content: space-between">
  7 + <div v-if="isShowTestResult" class="flex justify-between">
8 8 <a-row class="mt-8" type="flex" justify="center" align="middle">
9 9 <a-col :span="3"> 测试地址 </a-col>
10 10 <a-col :span="21">
... ... @@ -16,22 +16,52 @@
16 16 </div>
17 17 </div>
18 18 <div class="mt-8">
19   - <a-row type="flex" justify="space-between" align="middle">
20   - <a-col :span="24">
21   - <div>
22   - <JsonEditor
23   - :showBtn="true"
24   - v-if="isWebSocketType === '2'"
25   - style="width: 40vw; height: 40vh"
26   - ref="jsonWebsocketEditorRef"
27   - />
28   - <JsonEditor
29   - :showBtn="true"
30   - v-else
31   - style="width: 40vw; height: 40vh"
32   - ref="jsonEditorRef"
33   - />
34   - </div>
  19 + <a-row type="flex" align="top">
  20 + <a-col
  21 + :span="
  22 + method === RequestMethodTypeEnum.WEBSOCKET
  23 + ? 11
  24 + : httpType === RequestHttpTypeEnum.POST
  25 + ? 4
  26 + : 6
  27 + "
  28 + >
  29 + <p>过滤器函数编写:</p>
  30 + <AceTypeIsJsEditor
  31 + :restData="getRestData"
  32 + @changeAceContent="onHandleAceContent"
  33 + ref="aceTypeIsJsEditorRef"
  34 + />
  35 + </a-col>
  36 + <a-col :span="1">
  37 + <a-divider type="vertical" class="divider-color" />
  38 + </a-col>
  39 + <a-col
  40 + :span="
  41 + method === RequestMethodTypeEnum.WEBSOCKET
  42 + ? 12
  43 + : httpType === RequestHttpTypeEnum.POST
  44 + ? 19
  45 + : 17
  46 + "
  47 + style="position: relative"
  48 + :style="{
  49 + left:
  50 + (method === RequestMethodTypeEnum.WEBSOCKET
  51 + ? 1.5
  52 + : httpType === RequestHttpTypeEnum.POST
  53 + ? -1.5
  54 + : 0) + 'vw',
  55 + }"
  56 + >
  57 + <a-col>
  58 + <p>接口返回数据(res):</p>
  59 + <JsonEditor style="height: 35vh" :showBtn="true" ref="jsonEditorRef" />
  60 + </a-col>
  61 + <a-col class="mt-3">
  62 + <p>过滤器结果:</p>
  63 + <JsonFilterEditor style="height: 35vh" :showBtn="true" ref="jsonEditorFilterRef" />
  64 + </a-col>
35 65 </a-col>
36 66 </a-row>
37 67 </div>
... ... @@ -44,8 +74,11 @@
44 74 import { useWebSocket } from '@vueuse/core';
45 75 import { useUtils } from '../../../hooks/useUtils';
46 76 import JsonEditor from '../../SimpleRequest/components/jsonEditor.vue';
  77 + import JsonFilterEditor from '../../SimpleRequest/components/jsonEditor.vue';
  78 + import AceTypeIsJsEditor from '../../SimpleRequest/components/aceEditor.vue';
47 79 import { Tag } from 'ant-design-vue';
48 80 import { useThrottleFn } from '@vueuse/shared';
  81 + import { RequestMethodTypeEnum, RequestHttpTypeEnum } from '../../../config/enum';
49 82
50 83 const emits = defineEmits(['emitExcute']);
51 84
... ... @@ -53,13 +86,25 @@
53 86 data: {
54 87 type: Object,
55 88 },
  89 + method: {
  90 + type: String,
  91 + },
  92 + httpType: {
  93 + type: String,
  94 + },
56 95 });
57 96
58 97 const showTestFlag = ref(false);
59 98
  99 + const openFilterFlag = ref(false);
  100 +
60 101 const jsonEditorRef = ref<InstanceType<typeof JsonEditor>>();
61 102
62   - const jsonWebsocketEditorRef = ref<InstanceType<typeof JsonEditor>>();
  103 + const jsonEditorFilterRef = ref<InstanceType<typeof JsonFilterEditor>>();
  104 +
  105 + const aceTypeIsJsEditorRef = ref<InstanceType<typeof AceTypeIsJsEditor>>();
  106 +
  107 + const getRestData: any = ref(null);
63 108
64 109 const socketUrls = ref('');
65 110
... ... @@ -70,6 +115,12 @@
70 115 },
71 116 });
72 117
  118 + const { staticWebSocketParams, commonRest } = useUtils();
  119 +
  120 + const onHandleAceContent = (resp) => {
  121 + commonRest(resp, jsonEditorFilterRef.value?.setJsonValue);
  122 + };
  123 +
73 124 //格式化替换像"http:xxxx/api/xx/{xx}/{xx}/{xx}这种格式"
74 125 String.prototype.restfulFormat = function (replacements) {
75 126 var formatString = function (str, replacements) {
... ... @@ -109,7 +160,7 @@
109 160 isShowTestResult.value = true;
110 161 nextTick(() => {
111 162 jsonEditorRef.value?.setJsonValue('测试结果为');
112   - jsonWebsocketEditorRef.value?.setJsonValue('测试结果为');
  163 + jsonEditorFilterRef.value?.setJsonValue('过滤结果为');
113 164 });
114 165 };
115 166
... ... @@ -121,17 +172,17 @@
121 172 await nextTick();
122 173 //获取Params和Header和Body
123 174 const Objects = props.data;
124   - isWebSocketType.value = Objects?.method;
125 175 const apiType = Objects?.apiType;
126 176 const url = Objects?.apiGetUrl;
127 177 const headers = Objects?.Header?.params;
128 178 const params = Objects?.Params?.params;
129   - isToken.value = Objects?.Params?.token;
130 179 const body = Objects?.Body?.params;
  180 + isWebSocketType.value = Objects?.method;
  181 + isToken.value = Objects?.Params?.token;
131 182 isPostToken.value = Objects?.Body?.token;
132 183 postBodyType.value = Objects?.Body?.type;
133 184 apiUrl.value = url?.restfulFormat(params);
134   - if (isWebSocketType.value === '2') {
  185 + if (isWebSocketType.value === RequestMethodTypeEnum.WEBSOCKET) {
135 186 socketUrls.value = url;
136 187 socketMessage.server = `${socketUrls.value}?token=${isToken.value}`;
137 188 const list = Object.values(params);
... ... @@ -154,19 +205,10 @@
154 205 postBodyType.value
155 206 );
156 207 if (!resp) return;
157   - if (Object.prototype.toString.call(resp) === '[object Object]') {
158   - jsonEditorRef.value?.setJsonValue(resp);
159   - } else if (typeof resp === 'string') {
160   - jsonEditorRef.value?.setJsonValue(resp);
161   - } else if (Array.isArray(resp)) {
162   - const temp = {
163   - data: resp,
164   - };
165   - jsonEditorRef.value?.setJsonValue(temp);
166   - } else {
167   - jsonEditorRef.value?.setJsonValue(JSON.stringify(resp));
168   - }
  208 + getRestData.value = resp;
  209 + commonRest(resp, jsonEditorRef.value?.setJsonValue);
169 210 } catch (e) {
  211 + console.log(e);
170 212 if (Object.prototype.toString.call(e) === '[object Object]') {
171 213 jsonEditorRef.value?.setJsonValue(e);
172 214 } else {
... ... @@ -176,50 +218,45 @@
176 218 }
177 219 };
178 220
179   - //websocket请求
  221 + //ws请求
180 222 const websocketRequest = (params, destroy = false) => {
181   - //websocket请求
182   - if (Object.prototype.toString.call(params) === '[object Object]') {
183   - Reflect.deleteProperty(params, 'deviceProfileId');
184   - Reflect.deleteProperty(params, 'organizationId');
185   - Reflect.set(params, 'cmdId', 1);
186   - Reflect.set(params, 'scope', 'LATEST_TELEMETRY');
187   - Reflect.set(params, 'entityType', 'DEVICE');
  223 + try {
  224 + let webSocketParams: any = null;
  225 + if (Object.prototype.toString.call(params) === '[object Object]') {
  226 + const { entityId, keys } = params;
  227 + webSocketParams = {
  228 + entityId,
  229 + keys,
  230 + ...staticWebSocketParams,
  231 + };
  232 + }
  233 + socketMessage.sendValue.tsSubCmds = [webSocketParams];
  234 + const { send, close } = useWebSocket(socketMessage.server, {
  235 + onConnected() {
  236 + send(JSON.stringify(socketMessage.sendValue));
  237 + },
  238 + onMessage(_, e) {
  239 + const { data } = JSON.parse(e.data);
  240 + getRestData.value = data;
  241 + commonRest(data, jsonEditorRef.value?.setJsonValue);
  242 + },
  243 + onDisconnected() {
  244 + close();
  245 + },
  246 + onError() {},
  247 + });
  248 + if (destroy) close();
  249 + } finally {
188 250 }
189   - socketMessage.sendValue.tsSubCmds = [params];
190   - const { send, close } = useWebSocket(socketMessage.server, {
191   - onConnected() {
192   - send(JSON.stringify(socketMessage.sendValue));
193   - console.log('建立连接了');
194   - },
195   - onMessage(_, e) {
196   - const { data } = JSON.parse(e.data);
197   - if (Object.prototype.toString.call(data) === '[object Object]') {
198   - jsonWebsocketEditorRef.value?.setJsonValue(data);
199   - } else if (typeof data === 'string') {
200   - jsonWebsocketEditorRef.value?.setJsonValue(data);
201   - } else if (Array.isArray(data)) {
202   - jsonWebsocketEditorRef.value?.setJsonValue(JSON.stringify(data));
203   - } else {
204   - jsonEditorRef.value?.setJsonValue(JSON.stringify(data));
205   - }
206   - },
207   - onDisconnected() {
208   - console.log('断开连接了');
209   - close();
210   - },
211   - onError() {},
212   - });
213   - if (destroy) close();
214 251 };
215 252
216 253 onUnmounted(() => {
217   - if (isWebSocketType.value === '2') {
  254 + if (isWebSocketType.value === RequestMethodTypeEnum.WEBSOCKET) {
218 255 websocketRequest(null, true);
219 256 }
220 257 });
221 258
222   - //TODO: 待优化 项目自带第三方请求
  259 + //http请求
223 260 const otherHttpRequest = async (
224 261 apiType,
225 262 apiUrl,
... ... @@ -228,69 +265,27 @@
228 265 body,
229 266 token,
230 267 postToken,
231   - postBodyType,
232   - joinPrefix = false
  268 + postBodyType
233 269 ) => {
234   - const { convertObj } = useUtils();
  270 + const { convertObj, commonHttpParams, commonParams } = useUtils();
235 271 switch (apiType) {
236 272 case 'GET':
237   - const objGet = Object.assign(
238   - {},
239   - {
240   - 'X-Authorization': `Bearer ${!token ? postToken : token}`,
241   - },
242   - headers
243   - );
244 273 return await otherHttp.get(
245   - { url: apiUrl, params, headers: objGet },
246 274 {
247   - apiUrl: '',
248   - joinPrefix,
249   - withToken: false,
250   - errorMessageMode: 'none',
251   - }
252   - );
253   - case 'POST':
254   - const objPost = Object.assign(
255   - {},
256   - {
257   - 'X-Authorization': `Bearer ${!postToken ? token : postToken}`,
  275 + url: apiUrl,
  276 + params,
  277 + headers: commonHttpParams(postToken, token, postBodyType, headers),
258 278 },
259   - {
260   - 'Content-Type':
261   - postBodyType === 'xml'
262   - ? 'text/xml'
263   - : postBodyType === 'form-data'
264   - ? 'multipart/form-data'
265   - : postBodyType === 'x-www-form-urlencoded'
266   - ? 'application/x-www-form-urlencoded'
267   - : postBodyType === 'json'
268   - ? 'application/json'
269   - : 'application/json',
270   - },
271   - headers
  279 + commonParams
272 280 );
  281 + case 'POST':
273 282 return await otherHttp.post(
274   - { url: `${apiUrl}?${convertObj(params)}`, data: body, headers: objPost },
275 283 {
276   - apiUrl: '',
277   - joinPrefix,
278   - withToken: false,
279   - errorMessageMode: 'none',
280   - }
281   - );
282   - case 'PUT':
283   - const objPut = Object.assign({}, headers, {
284   - 'X-Authorization': `Bearer ${!postToken ? token : postToken}`,
285   - });
286   - return await otherHttp.put(
287   - { url: `${apiUrl}?${convertObj(params)}`, data: body, headers: objPut, params },
288   - {
289   - apiUrl: '',
290   - joinPrefix,
291   - withToken: false,
292   - errorMessageMode: 'none',
293   - }
  284 + url: `${apiUrl}${`?${convertObj(params)}`}`,
  285 + data: body,
  286 + headers: commonHttpParams(postToken, token, postBodyType, headers),
  287 + },
  288 + commonParams
294 289 );
295 290 }
296 291 };
... ... @@ -298,19 +293,25 @@
298 293 const resetValue = (flag) => {
299 294 if (flag) {
300 295 showTestFlag.value = false;
  296 + openFilterFlag.value = false;
301 297 }
302 298 nextTick(() => {
303 299 jsonEditorRef.value?.setJsonValue('测试结果为');
304   - jsonWebsocketEditorRef.value?.setJsonValue('测试结果为');
  300 + jsonEditorFilterRef.value?.setJsonValue('过滤结果为');
305 301 });
306   - isWebSocketType.value = '0';
  302 + isWebSocketType.value = RequestMethodTypeEnum.COMMOM;
307 303 };
308 304
309 305 const showTest = () => (showTestFlag.value = true);
310 306
  307 + const getFilterValue = () => {
  308 + return aceTypeIsJsEditorRef?.value?.getValue();
  309 + };
  310 +
311 311 defineExpose({
312 312 resetValue,
313 313 showTest,
  314 + getFilterValue,
314 315 });
315 316 </script>
316 317
... ... @@ -318,4 +319,11 @@
318 319 :deep(.ant-input-textarea-show-count) {
319 320 width: 30vw;
320 321 }
  322 +
  323 + .divider-color {
  324 + height: 78.5vh;
  325 + background-color: #e5e7eb;
  326 + position: relative;
  327 + left: 1.16vw;
  328 + }
321 329 </style>
... ...
  1 +<template>
  2 + <div class="flex" v-if="interfaceType === 'SYSTEM' && isAdmin(role)">
  3 + <Select
  4 + v-model:value="selectTenant"
  5 + @change="onSelect"
  6 + style="width: 150px"
  7 + placeholder="请选择租户"
  8 + :options="selectOptions"
  9 + show-search
  10 + :filter-option="filterOption"
  11 + />
  12 + <Select
  13 + v-model:value="selectSysTenant"
  14 + @change="onSelctTenant"
  15 + style="width: 150px; margin-left: 10px"
  16 + v-if="selectTenantOptions.length > 0"
  17 + placeholder="请选择租户"
  18 + :options="selectTenantOptions"
  19 + show-search
  20 + :filter-option="filterTenantOption"
  21 + />
  22 + </div>
  23 +</template>
  24 +<script lang="ts" setup name="selectTenant">
  25 + import { onMounted, ref, onUnmounted } from 'vue';
  26 + import { selectType } from '../../../config/types';
  27 + import { Select } from 'ant-design-vue';
  28 + import { getUserToken } from '/@/api/sys/user';
  29 + import { USER_INFO_KEY } from '/@/enums/cacheEnum';
  30 + import { getAuthCache } from '/@/utils/auth';
  31 + import { isAdmin } from '/@/enums/roleEnum';
  32 + import { getTenantAllPageLists, getTenantPageList } from '/@/api/tenant/tenantApi';
  33 +
  34 + defineProps({
  35 + interfaceType: {
  36 + type: String,
  37 + },
  38 + });
  39 +
  40 + const emits = defineEmits(['emitToken']);
  41 +
  42 + const userInfo: any = getAuthCache(USER_INFO_KEY);
  43 +
  44 + const role: string = userInfo?.roles[0];
  45 +
  46 + onMounted(async () => {
  47 + if (isAdmin(role)) {
  48 + const res = await getTenantPageList();
  49 + selectOptions.value = res.map((m) => ({ label: m.name, value: m.tenantId }));
  50 + } else {
  51 + //租户
  52 + const { token } = await getUserToken(userInfo?.userId);
  53 + getToken.value = token;
  54 + emits('emitToken', getToken.value, testDisabled.value);
  55 + }
  56 + });
  57 +
  58 + const selectOptions = ref<selectType[]>([]);
  59 +
  60 + const testDisabled = ref(true);
  61 +
  62 + const selectTenantOptions = ref<selectType[]>([]);
  63 +
  64 + const selectTenant = ref(undefined);
  65 +
  66 + const selectSysTenant = ref(undefined);
  67 +
  68 + const getToken = ref('');
  69 +
  70 + const filterOption = (input: string, option: any) => {
  71 + return option.label.includes(input);
  72 + };
  73 +
  74 + const filterTenantOption = (input: string, option: any) => {
  75 + return option.label.includes(input);
  76 + };
  77 +
  78 + const onSelect = async (e) => {
  79 + if (e) {
  80 + testDisabled.value = false;
  81 + } else {
  82 + testDisabled.value = true;
  83 + }
  84 + selectSysTenant.value = undefined;
  85 + const rest = (await getTenantAllPageLists(e)) as any;
  86 + selectTenantOptions.value = rest?.map((m) => ({ label: m.realName, value: m.id }));
  87 + };
  88 +
  89 + const onSelctTenant = async (e) => {
  90 + if (e) {
  91 + testDisabled.value = false;
  92 + } else {
  93 + testDisabled.value = true;
  94 + }
  95 + const { token } = await getUserToken(e);
  96 + getToken.value = token;
  97 + emits('emitToken', getToken.value, testDisabled.value);
  98 + };
  99 +
  100 + onUnmounted(() => {
  101 + selectTenant.value = undefined;
  102 + selectSysTenant.value = undefined;
  103 + selectTenantOptions.value = [];
  104 + getToken.value = '';
  105 + });
  106 +</script>
  107 +
  108 +<style scoped lang="less"></style>
... ...
... ... @@ -2,28 +2,10 @@
2 2 <div>
3 3 <div class="mt-8">
4 4 <div class="flex">
5   - <div class="flex" v-if="interfaceType === 'SYSTEM' && isAdmin(role)">
6   - <Select
7   - allowClear
8   - v-model:value="selectTenant"
9   - @change="onSelect"
10   - style="width: 150px"
11   - placeholder="请选择租户"
12   - :options="selectOptions"
13   - />
14   - <Select
15   - v-model:value="selectSysTenant"
16   - allowClear
17   - @change="onSelctTenant"
18   - style="width: 150px; margin-left: 10px"
19   - v-if="selectTenantOptions.length > 0"
20   - placeholder="请选择租户"
21   - :options="selectTenantOptions"
22   - />
23   - </div>
  5 + <SelectTenant :interfaceType="interfaceType" @emitToken="onHandleEmitToken" />
  6 + <div v-if="role === 'SYS_ADMIN'" class="ml-2"></div>
24 7 <Button
25 8 :disabled="interfaceType === 'SYSTEM' && isAdmin(role) ? testDisabled : false"
26   - class="ml-2"
27 9 @click="handleTest(isSingleClickText)"
28 10 type="primary"
29 11 >{{ `${isSingleClickText === 'open' ? '打开' : '关闭'}测试接口` }}
... ... @@ -38,21 +20,17 @@
38 20 </a-row>
39 21 </div>
40 22 </div>
41   - <div class="mt-8"> </div>
42 23 </div>
43 24 </template>
44 25 <script lang="ts" setup name="testRequest">
45   - import { ref, nextTick, onMounted } from 'vue';
  26 + import { ref, nextTick } from 'vue';
46 27 import { Button } from 'ant-design-vue';
47 28 import TestHeaderEditCellTable from './testEditHeaderCellTable.vue';
48 29 import { useMessage } from '/@/hooks/web/useMessage';
49   - import { selectType } from '../../../config/types';
50   - import { Select } from 'ant-design-vue';
51   - import { getUserToken } from '/@/api/sys/user';
52 30 import { USER_INFO_KEY } from '/@/enums/cacheEnum';
53   - import { getTenantAllPageLists, getTenantPageList } from '/@/api/tenant/tenantApi';
54 31 import { getAuthCache } from '/@/utils/auth';
55 32 import { isAdmin } from '/@/enums/roleEnum';
  33 + import SelectTenant from '../components/selectTenant.vue';
56 34
57 35 const emits = defineEmits(['testHeaderInterface', 'closeTest']);
58 36
... ... @@ -69,21 +47,6 @@
69 47 },
70 48 });
71 49
72   - onMounted(async () => {
73   - if (isAdmin(role)) {
74   - const res = await getTenantPageList();
75   - selectOptions.value = res.map((m) => ({ label: m.name, value: m.tenantId }));
76   - } else {
77   - //租户
78   - const { token } = await getUserToken(userInfo?.userId);
79   - getToken.value = token;
80   - }
81   - });
82   -
83   - const selectOptions = ref<selectType[]>([]);
84   -
85   - const selectTenantOptions = ref<selectType[]>([]);
86   -
87 50 const testDisabled = ref(true);
88 51
89 52 const { createMessage } = useMessage();
... ... @@ -92,46 +55,20 @@
92 55
93 56 const excuteData = ref({});
94 57
95   - const selectTenant = ref(undefined);
96   -
97   - const selectSysTenant = ref(undefined);
98   -
99 58 const testEditCellTableRef = ref<InstanceType<typeof TestHeaderEditCellTable>>();
100 59
101 60 const testResult = ref('');
102 61
103 62 const getToken = ref('');
104 63
105   - const onSelect = async (e) => {
106   - if (e) {
107   - testDisabled.value = false;
108   - } else {
109   - testDisabled.value = true;
110   - }
111   - selectSysTenant.value = undefined;
112   - const rest = (await getTenantAllPageLists(e)) as any;
113   - selectTenantOptions.value = rest?.map((m) => ({ label: m.realName, value: m.id }));
114   - };
  64 + const isSingleClickText = ref('open');
115 65
116   - const onSelctTenant = async (e) => {
117   - if (e) {
118   - testDisabled.value = false;
119   - } else {
120   - testDisabled.value = true;
121   - }
122   - const { token } = await getUserToken(e);
  66 + const onHandleEmitToken = (token, flag) => {
123 67 getToken.value = token;
  68 + testDisabled.value = flag;
124 69 };
125 70
126   - const isSingleClickText = ref('open');
127   -
128 71 const handleTest = (o) => {
129   - if (isAdmin(role)) {
130   - if (!selectTenant.value || !selectSysTenant.value) {
131   - createMessage.error('请选择租户或者租户管理员');
132   - throw Error('请选择租户或者租户管理员');
133   - }
134   - }
135 72 if (o === 'open') {
136 73 showTestEditCell.value = true;
137 74 emits('testHeaderInterface');
... ... @@ -177,9 +114,6 @@
177 114 const setValue = () => {
178 115 showTestEditCell.value = false;
179 116 testResult.value = '';
180   - selectTenant.value = undefined;
181   - selectSysTenant.value = undefined;
182   - selectTenantOptions.value = [];
183 117 };
184 118
185 119 const onCloseTest = () => {
... ...
1   -<!-- eslint-disable vue/valid-v-model -->
2 1 <template>
3 2 <div class="table-content">
4   - <!-- TODO: 待优化测试表格 -->
5 3 <table align="center">
6 4 <thead>
7 5 <tr>
... ... @@ -10,10 +8,10 @@
10 8 </thead>
11 9 <tbody>
12 10 <tr v-for="(item, index) in tableTestArray.content" :key="index">
13   - <td style="width: 7.5vw">
14   - <a-input disabled placeholder="请输入" v-model:value="item.key" />
  11 + <td>
  12 + <a-input disabled v-model:value="item.key" />
15 13 </td>
16   - <td style="width: 6.5vw">
  14 + <td>
17 15 <a-input placeholder="请输入" v-model:value="item.value" />
18 16 </td>
19 17 </tr>
... ... @@ -27,12 +25,6 @@
27 25 import { tableItems } from '../../../config/types';
28 26 import { editTestCellTableTHeadConfig } from '../../../config/config';
29 27
30   - defineProps({
31   - method: {
32   - type: String,
33   - },
34   - });
35   -
36 28 const tableTestArray = reactive<{
37 29 content: tableItems[];
38 30 }>({
... ... @@ -57,6 +49,7 @@
57 49 const getValue = () => {
58 50 return tableTestArray.content;
59 51 };
  52 +
60 53 defineExpose({
61 54 getValue,
62 55 setTableArray,
... ... @@ -64,28 +57,5 @@
64 57 </script>
65 58
66 59 <style scoped lang="less">
67   - @table-color: #e5e7eb;
68   -
69   - .table-border-color {
70   - border: 1px solid #e5e7eb;
71   - text-align: center;
72   - }
73   -
74   - .table-content {
75   - table {
76   - width: 31vw;
77   - &:extend(.table-border-color);
78   - }
79   -
80   - table td {
81   - padding: 5px;
82   - white-space: nowrap;
83   - &:extend(.table-border-color);
84   - }
85   -
86   - table th {
87   - padding: 5px;
88   - &:extend(.table-border-color);
89   - }
90   - }
  60 + @import '../../SimpleRequest/common/commonTestTable.less';
91 61 </style>
... ...
... ... @@ -2,28 +2,10 @@
2 2 <div>
3 3 <div class="mt-8">
4 4 <div class="flex">
5   - <div class="flex" v-if="interfaceType === 'SYSTEM' && isAdmin(role)">
6   - <Select
7   - allowClear
8   - v-model:value="selectTenant"
9   - @change="onSelect"
10   - style="width: 150px"
11   - placeholder="请选择租户"
12   - :options="selectOptions"
13   - />
14   - <Select
15   - v-model:value="selectSysTenant"
16   - allowClear
17   - @change="onSelctTenant"
18   - style="width: 150px; margin-left: 10px"
19   - v-if="selectTenantOptions.length > 0"
20   - placeholder="请选择租户"
21   - :options="selectTenantOptions"
22   - />
23   - </div>
  5 + <SelectTenant :interfaceType="interfaceType" @emitToken="onHandleEmitToken" />
  6 + <div v-if="role === 'SYS_ADMIN'" class="ml-2"></div>
24 7 <Button
25 8 :disabled="interfaceType === 'SYSTEM' && isAdmin(role) ? testDisabled : false"
26   - class="ml-2"
27 9 @click="handleTest(isSingleClickText)"
28 10 type="primary"
29 11 >{{ `${isSingleClickText === 'open' ? '打开' : '关闭'}测试接口` }}
... ... @@ -38,23 +20,21 @@
38 20 </a-row>
39 21 </div>
40 22 </div>
41   - <div class="mt-8"> </div>
42 23 </div>
43 24 </template>
44 25 <script lang="ts" setup name="testRequest">
45   - import { ref, nextTick, onMounted } from 'vue';
  26 + import { ref, nextTick } from 'vue';
46 27 import { Button } from 'ant-design-vue';
47 28 import TestParamsCellTable from './testEditParamsCellTable.vue';
48 29 import moment from 'moment';
49 30 import { useUtils } from '../../../hooks/useUtils';
50 31 import { useMessage } from '/@/hooks/web/useMessage';
51   - import { getTenantAllPageLists, getTenantPageList } from '/@/api/tenant/tenantApi';
52   - import { selectType } from '../../../config/types';
53   - import { Select } from 'ant-design-vue';
54   - import { getUserToken } from '/@/api/sys/user';
55 32 import { USER_INFO_KEY } from '/@/enums/cacheEnum';
56 33 import { getAuthCache } from '/@/utils/auth';
57 34 import { isAdmin } from '/@/enums/roleEnum';
  35 + import { TableDefaultTypeEnum } from '../../../config/enum';
  36 + import { AggregateDataEnum } from '/@/views/report/config/timeConfig';
  37 + import SelectTenant from '../components/selectTenant.vue';
58 38
59 39 const userInfo: any = getAuthCache(USER_INFO_KEY);
60 40
... ... @@ -71,33 +51,14 @@
71 51 },
72 52 });
73 53
74   - onMounted(async () => {
75   - if (isAdmin(role)) {
76   - const res = await getTenantPageList();
77   - selectOptions.value = res.map((m) => ({ label: m.name, value: m.tenantId }));
78   - } else {
79   - //租户
80   - const { token } = await getUserToken(userInfo?.userId);
81   - getToken.value = token;
82   - }
83   - });
84   -
85   - const selectOptions = ref<selectType[]>([]);
86   -
87 54 const testDisabled = ref(true);
88 55
89   - const selectTenantOptions = ref<selectType[]>([]);
90   -
91 56 const { createMessage } = useMessage();
92 57
93 58 const showTestEditCell = ref(false);
94 59
95 60 const excuteData = ref({});
96 61
97   - const selectTenant = ref(undefined);
98   -
99   - const selectSysTenant = ref(undefined);
100   -
101 62 const testEditCellTableRef = ref<InstanceType<typeof TestParamsCellTable>>();
102 63
103 64 const testResult = ref('');
... ... @@ -106,26 +67,11 @@
106 67
107 68 const getToken = ref('');
108 69
109   - const onSelect = async (e) => {
110   - if (e) {
111   - testDisabled.value = false;
112   - } else {
113   - testDisabled.value = true;
114   - }
115   - selectSysTenant.value = undefined;
116   - const rest = (await getTenantAllPageLists(e)) as any;
117   - selectTenantOptions.value = rest?.map((m) => ({ label: m.realName, value: m.id }));
118   - };
119   -
120   - const onSelctTenant = async (e) => {
121   - if (e) {
122   - testDisabled.value = false;
123   - } else {
124   - testDisabled.value = true;
125   - }
126   - const { token } = await getUserToken(e);
  70 + const onHandleEmitToken = (token, flag) => {
127 71 getToken.value = token;
  72 + testDisabled.value = flag;
128 73 };
  74 +
129 75 const isSingleClickText = ref('open');
130 76
131 77 const handleTest = (o) => {
... ... @@ -147,7 +93,7 @@
147 93 const getSingleKey = props.data?.list;
148 94 let getMuteDateRangeKeys: any = null;
149 95 const findDateRange = getSingleKey.find(
150   - (item) => item?.key == 'date_range' && item?.mores === true
  96 + (item) => item?.key == TableDefaultTypeEnum.DATERANGE && item?.mores === true
151 97 );
152 98 if (findDateRange) {
153 99 getMuteDateRangeKeys = getMultipleKeys([{ key: 'agg', value: '' }]);
... ... @@ -164,14 +110,13 @@
164 110 };
165 111
166 112 //测试表格里的数据转化为 key value 数组对象形式
167   - //TODO:待优化这里的TS类型
168 113 const getTestTableKeyValue = () => {
169 114 //把日期拆分成多个
170 115 const keyValueList: any = [];
171   - console.log(testEditCellTableRef.value?.getValue());
172 116 testEditCellTableRef.value?.getValue()?.forEach((item: any) => {
173   - const splitDateKey = item?.key === 'date_range' ? item?.value?.split(',') : [];
174   - const splitDateValue = item?.key === 'date_range' ? item?.dateValue : [];
  117 + const splitDateKey =
  118 + item?.key === TableDefaultTypeEnum.DATERANGE ? item?.value?.split(',') : [];
  119 + const splitDateValue = item?.key === TableDefaultTypeEnum.DATERANGE ? item?.dateValue : [];
175 120 for (let i in splitDateKey) {
176 121 const obj = {
177 122 key: splitDateKey[i],
... ... @@ -183,17 +128,11 @@
183 128 return testEditCellTableRef.value
184 129 ?.getValue()
185 130 .concat(keyValueList)
186   - .filter((it) => it.key !== 'date_range')
  131 + .filter((it) => it.key !== TableDefaultTypeEnum.DATERANGE)
187 132 .map((it: any) => {
188   - const value =
189   - it?.key === 'scope'
190   - ? it?.keyValue
191   - : it?.key === 'fixed_date'
192   - ? moment(it?.fixed_date_value).valueOf()
193   - : it?.value;
194   - const key = it?.key === 'scope' || it?.key === 'fixed_date' ? it?.value : it?.key;
  133 + const value = it?.key === TableDefaultTypeEnum.SCOPE ? it?.keyValue : it?.value;
  134 + const key = it?.key === TableDefaultTypeEnum.SCOPE ? it?.value : it?.key;
195 135 const limit = it?.limit;
196   - console.log(limit);
197 136 return {
198 137 key,
199 138 value,
... ... @@ -213,16 +152,15 @@
213 152 }
214 153 const params: any = {};
215 154 getTable?.map((it) => {
216   - console.log(it);
217 155 params[it.key!] = it.value!;
218   - if (it.key === 'agg') {
  156 + if (it.key === TableDefaultTypeEnum.AGG) {
219 157 params.limit = it.limit;
220 158 }
221 159 });
222 160 if (params['keys']) {
223 161 Reflect.set(params, 'keys', params['keys'].join(','));
224 162 }
225   - if (params['agg'] !== 'NONE') {
  163 + if (params['agg'] !== AggregateDataEnum.NONE) {
226 164 Reflect.set(params, 'limit', null);
227 165 }
228 166 excuteData.value = {
... ... @@ -234,11 +172,9 @@
234 172
235 173 //设置数据
236 174 const setValue = () => {
  175 + isSingleClickText.value = 'open';
237 176 showTestEditCell.value = false;
238 177 testResult.value = '';
239   - selectTenant.value = undefined;
240   - selectSysTenant.value = undefined;
241   - selectTenantOptions.value = [];
242 178 };
243 179
244 180 const onCloseTest = () => {
... ...