|
@@ -4,43 +4,55 @@ |
|
@@ -4,43 +4,55 @@ |
4
|
v-bind="$attrs"
|
4
|
v-bind="$attrs"
|
5
|
:active-tab-key="activeKey"
|
5
|
:active-tab-key="activeKey"
|
6
|
@tabChange="onTabChange"
|
6
|
@tabChange="onTabChange"
|
|
|
7
|
+ v-if="!isAdmin(role)"
|
7
|
>
|
8
|
>
|
8
|
- <template #tabBarExtraContent v-if="!isAdmin(role)">
|
9
|
+ <template #tabBarExtraContent>
|
9
|
<div class="extra-date">
|
10
|
<div class="extra-date">
|
10
|
- <template v-for="(item, index) in dateList" :key="item">
|
|
|
11
|
- <span @click="changeDate(index)" :class="{ active: index === activeIndex }">{{
|
|
|
12
|
- item
|
|
|
13
|
- }}</span>
|
11
|
+ <template v-for="(item, index) in dateList" :key="item.value">
|
|
|
12
|
+ <span
|
|
|
13
|
+ @click="quickQueryDate(index, item.value)"
|
|
|
14
|
+ :class="{ active: index === activeIndex }"
|
|
|
15
|
+ >{{ item.label }}</span
|
|
|
16
|
+ >
|
14
|
</template>
|
17
|
</template>
|
15
|
<DatePicker @change="onDateChange" />
|
18
|
<DatePicker @change="onDateChange" />
|
16
|
</div>
|
19
|
</div>
|
17
|
</template>
|
20
|
</template>
|
18
|
<div v-if="activeKey === '1'">
|
21
|
<div v-if="activeKey === '1'">
|
19
|
- <p class="center">{{ !isAdmin(role) ? '告警数' : '租户趋势' }}</p>
|
22
|
+ <p class="center">告警数</p>
|
|
|
23
|
+ <!-- 折线图 -->
|
20
|
<VisitAnalysis v-if="!isAdmin(role)" :alarmList="state.alarmList" />
|
24
|
<VisitAnalysis v-if="!isAdmin(role)" :alarmList="state.alarmList" />
|
21
|
- <VisitAnalysisBar v-else />
|
|
|
22
|
</div>
|
25
|
</div>
|
23
|
<div v-if="activeKey === '2'">
|
26
|
<div v-if="activeKey === '2'">
|
24
|
<p class="center">消息量</p>
|
27
|
<p class="center">消息量</p>
|
25
|
- <VisitAnalysisBar :dataPointList="state.dataPointList" :messageList="state.messageList" />
|
28
|
+ <!-- 柱形图 -->
|
|
|
29
|
+ <VisitAnalysisBar
|
|
|
30
|
+ v-if="!isAdmin(role)"
|
|
|
31
|
+ :dataPointList="state.dataPointList"
|
|
|
32
|
+ :messageList="state.messageList"
|
|
|
33
|
+ />
|
26
|
</div>
|
34
|
</div>
|
27
|
</Card>
|
35
|
</Card>
|
28
|
- <Card v-bind="$attrs" :tab-list="tab1ListTitle" v-if="isAdmin(role)">
|
|
|
29
|
- <p class="center">客户趋势</p>
|
|
|
30
|
- <VisitAnalysis
|
|
|
31
|
- /></Card>
|
36
|
+ <Card v-bind="$attrs" v-if="isAdmin(role)" title="租户趋势">
|
|
|
37
|
+ <TenantTrend />
|
|
|
38
|
+ </Card>
|
|
|
39
|
+ <Card v-bind="$attrs" v-if="isAdmin(role)" title="客户趋势">
|
|
|
40
|
+ <CustomerTrend />
|
|
|
41
|
+ </Card>
|
32
|
</template>
|
42
|
</template>
|
33
|
<script lang="ts" setup>
|
43
|
<script lang="ts" setup>
|
34
|
- import { ref, defineExpose, reactive } from 'vue';
|
44
|
+ import { ref, reactive } from 'vue';
|
35
|
import { Card, DatePicker } from 'ant-design-vue';
|
45
|
import { Card, DatePicker } from 'ant-design-vue';
|
36
|
import VisitAnalysis from './VisitAnalysis.vue';
|
46
|
import VisitAnalysis from './VisitAnalysis.vue';
|
37
|
import VisitAnalysisBar from './VisitAnalysisBar.vue';
|
47
|
import VisitAnalysisBar from './VisitAnalysisBar.vue';
|
38
|
- import { defineProps } from 'vue';
|
|
|
39
|
import { isAdmin } from '/@/enums/roleEnum';
|
48
|
import { isAdmin } from '/@/enums/roleEnum';
|
40
|
import { useWebSocket } from '@vueuse/core';
|
49
|
import { useWebSocket } from '@vueuse/core';
|
41
|
import { getAuthCache } from '/@/utils/auth';
|
50
|
import { getAuthCache } from '/@/utils/auth';
|
|
|
51
|
+ import CustomerTrend from './CustomerTrend.vue';
|
|
|
52
|
+ import TenantTrend from './TenantTrend.vue';
|
42
|
import { JWT_TOKEN_KEY } from '/@/enums/cacheEnum';
|
53
|
import { JWT_TOKEN_KEY } from '/@/enums/cacheEnum';
|
43
|
-
|
54
|
+ import { formatToDateTime } from '/@/utils/dateUtil';
|
|
|
55
|
+ import { getEntitiesId } from '/@/api/dashboard/index';
|
44
|
defineExpose({
|
56
|
defineExpose({
|
45
|
isAdmin,
|
57
|
isAdmin,
|
46
|
});
|
58
|
});
|
|
@@ -48,84 +60,29 @@ |
|
@@ -48,84 +60,29 @@ |
48
|
role: string;
|
60
|
role: string;
|
49
|
}>();
|
61
|
}>();
|
50
|
const activeKey = ref('1');
|
62
|
const activeKey = ref('1');
|
51
|
-
|
|
|
52
|
- // 动态根据登录角色来判断
|
|
|
53
|
- const tabListTitle = !isAdmin(props.role)
|
|
|
54
|
- ? [
|
|
|
55
|
- {
|
|
|
56
|
- key: '1',
|
|
|
57
|
- tab: '告警数统计',
|
|
|
58
|
- },
|
|
|
59
|
- {
|
|
|
60
|
- key: '2',
|
|
|
61
|
- tab: '消息量统计',
|
|
|
62
|
- },
|
|
|
63
|
- ]
|
|
|
64
|
- : [
|
|
|
65
|
- {
|
|
|
66
|
- key: '1',
|
|
|
67
|
- tab: '租户',
|
|
|
68
|
- },
|
|
|
69
|
- ];
|
|
|
70
|
-
|
|
|
71
|
- const tab1ListTitle = [
|
63
|
+ let entityId = null;
|
|
|
64
|
+ // 图表tab切换选项卡
|
|
|
65
|
+ const tabListTitle = [
|
72
|
{
|
66
|
{
|
73
|
key: '1',
|
67
|
key: '1',
|
74
|
- tab: '客户',
|
68
|
+ tab: '告警数统计',
|
|
|
69
|
+ },
|
|
|
70
|
+ {
|
|
|
71
|
+ key: '2',
|
|
|
72
|
+ tab: '消息量统计',
|
75
|
},
|
73
|
},
|
76
|
];
|
74
|
];
|
77
|
-
|
|
|
78
|
- const dateList = ref(['1小时', '1天', '7天', '30天']);
|
75
|
+ // 快速选择日期
|
|
|
76
|
+ const activeIndex = ref(1);
|
|
|
77
|
+ const dateList = ref([
|
|
|
78
|
+ { label: '1小时', value: 3600000 },
|
|
|
79
|
+ { label: '1天', value: 86400000 },
|
|
|
80
|
+ { label: '7天', value: 604800000 },
|
|
|
81
|
+ { label: '30天', value: 2592000000 },
|
|
|
82
|
+ ]);
|
79
|
// web Socket
|
83
|
// web Socket
|
80
|
const token: string = getAuthCache(JWT_TOKEN_KEY);
|
84
|
const token: string = getAuthCache(JWT_TOKEN_KEY);
|
81
|
- const sendValue = JSON.stringify({
|
|
|
82
|
- entityDataCmds: [
|
|
|
83
|
- {
|
|
|
84
|
- query: {
|
|
|
85
|
- entityFilter: {
|
|
|
86
|
- type: 'singleEntity',
|
|
|
87
|
- singleEntity: {
|
|
|
88
|
- id: '33782740-5d97-11ec-8ac9-f38ed935ea2a',
|
|
|
89
|
- entityType: 'API_USAGE_STATE',
|
|
|
90
|
- },
|
|
|
91
|
- },
|
|
|
92
|
- pageLink: {
|
|
|
93
|
- pageSize: 1024,
|
|
|
94
|
- page: 0,
|
|
|
95
|
- sortOrder: {
|
|
|
96
|
- key: {
|
|
|
97
|
- type: 'ENTITY_FIELD',
|
|
|
98
|
- key: 'createdTime',
|
|
|
99
|
- },
|
|
|
100
|
- direction: 'DESC',
|
|
|
101
|
- },
|
|
|
102
|
- },
|
|
|
103
|
- entityFields: [
|
|
|
104
|
- {
|
|
|
105
|
- type: 'ENTITY_FIELD',
|
|
|
106
|
- key: 'name',
|
|
|
107
|
- },
|
|
|
108
|
- {
|
|
|
109
|
- type: 'ENTITY_FIELD',
|
|
|
110
|
- key: 'label',
|
|
|
111
|
- },
|
|
|
112
|
- {
|
|
|
113
|
- type: 'ENTITY_FIELD',
|
|
|
114
|
- key: 'additionalInfo',
|
|
|
115
|
- },
|
|
|
116
|
- ],
|
|
|
117
|
- latestValues: [
|
|
|
118
|
- {
|
|
|
119
|
- type: 'TIME_SERIES',
|
|
|
120
|
- key: 'createdAlarmsCountHourly',
|
|
|
121
|
- },
|
|
|
122
|
- ],
|
|
|
123
|
- },
|
|
|
124
|
- cmdId: activeKey.value,
|
|
|
125
|
- },
|
|
|
126
|
- ],
|
|
|
127
|
- });
|
|
|
128
|
- const activeIndex = ref(0);
|
85
|
+
|
129
|
const state = reactive({
|
86
|
const state = reactive({
|
130
|
server: `${import.meta.env.VITE_WEB_SOCKET}${token}`,
|
87
|
server: `${import.meta.env.VITE_WEB_SOCKET}${token}`,
|
131
|
alarmList: new Array<[number, string]>(),
|
88
|
alarmList: new Array<[number, string]>(),
|
|
@@ -136,12 +93,60 @@ |
|
@@ -136,12 +93,60 @@ |
136
|
MsgCount: new Array<[number, string]>(),
|
93
|
MsgCount: new Array<[number, string]>(),
|
137
|
});
|
94
|
});
|
138
|
const { send, close } = useWebSocket(state.server, {
|
95
|
const { send, close } = useWebSocket(state.server, {
|
139
|
- onConnected() {
|
96
|
+ async onConnected() {
|
|
|
97
|
+ if (isAdmin(props.role)) return;
|
|
|
98
|
+ const res = await getEntitiesId();
|
|
|
99
|
+ entityId = res.data[0].entityId;
|
|
|
100
|
+ const sendValue = JSON.stringify({
|
|
|
101
|
+ entityDataCmds: [
|
|
|
102
|
+ {
|
|
|
103
|
+ query: {
|
|
|
104
|
+ entityFilter: {
|
|
|
105
|
+ type: 'singleEntity',
|
|
|
106
|
+ singleEntity: entityId,
|
|
|
107
|
+ },
|
|
|
108
|
+ pageLink: {
|
|
|
109
|
+ pageSize: 1024,
|
|
|
110
|
+ page: 0,
|
|
|
111
|
+ sortOrder: {
|
|
|
112
|
+ key: {
|
|
|
113
|
+ type: 'ENTITY_FIELD',
|
|
|
114
|
+ key: 'createdTime',
|
|
|
115
|
+ },
|
|
|
116
|
+ direction: 'DESC',
|
|
|
117
|
+ },
|
|
|
118
|
+ },
|
|
|
119
|
+ entityFields: [
|
|
|
120
|
+ {
|
|
|
121
|
+ type: 'ENTITY_FIELD',
|
|
|
122
|
+ key: 'name',
|
|
|
123
|
+ },
|
|
|
124
|
+ {
|
|
|
125
|
+ type: 'ENTITY_FIELD',
|
|
|
126
|
+ key: 'label',
|
|
|
127
|
+ },
|
|
|
128
|
+ {
|
|
|
129
|
+ type: 'ENTITY_FIELD',
|
|
|
130
|
+ key: 'additionalInfo',
|
|
|
131
|
+ },
|
|
|
132
|
+ ],
|
|
|
133
|
+ latestValues: [
|
|
|
134
|
+ {
|
|
|
135
|
+ type: 'TIME_SERIES',
|
|
|
136
|
+ key: 'createdAlarmsCountHourly',
|
|
|
137
|
+ },
|
|
|
138
|
+ ],
|
|
|
139
|
+ },
|
|
|
140
|
+ cmdId: activeKey.value,
|
|
|
141
|
+ },
|
|
|
142
|
+ ],
|
|
|
143
|
+ });
|
140
|
send(sendValue);
|
144
|
send(sendValue);
|
141
|
console.log('建立连接了');
|
145
|
console.log('建立连接了');
|
142
|
},
|
146
|
},
|
143
|
onMessage(_, e) {
|
147
|
onMessage(_, e) {
|
144
|
const { data, update } = JSON.parse(e.data);
|
148
|
const { data, update } = JSON.parse(e.data);
|
|
|
149
|
+ console.log('来新消息了', data, update);
|
145
|
if (activeKey.value === '1') {
|
150
|
if (activeKey.value === '1') {
|
146
|
if (data) {
|
151
|
if (data) {
|
147
|
const { createdAlarmsCountHourly } = data.data[0].latest.TIME_SERIES;
|
152
|
const { createdAlarmsCountHourly } = data.data[0].latest.TIME_SERIES;
|
|
@@ -154,7 +159,7 @@ |
|
@@ -154,7 +159,7 @@ |
154
|
for (const item of createdAlarmsCountHourly) {
|
159
|
for (const item of createdAlarmsCountHourly) {
|
155
|
newArray.push([item.ts, item.value]);
|
160
|
newArray.push([item.ts, item.value]);
|
156
|
}
|
161
|
}
|
157
|
- state.alarmList = [state.alarmItem, ...newArray];
|
162
|
+ state.alarmList = [[...state.alarmItem], ...newArray];
|
158
|
}
|
163
|
}
|
159
|
} else {
|
164
|
} else {
|
160
|
if (data) {
|
165
|
if (data) {
|
|
@@ -164,7 +169,6 @@ |
|
@@ -164,7 +169,6 @@ |
164
|
transportDataPointsCountHourly.ts,
|
169
|
transportDataPointsCountHourly.ts,
|
165
|
transportDataPointsCountHourly.value,
|
170
|
transportDataPointsCountHourly.value,
|
166
|
];
|
171
|
];
|
167
|
-
|
|
|
168
|
state.MsgCount = [
|
172
|
state.MsgCount = [
|
169
|
transportDataPointsCountHourly.ts,
|
173
|
transportDataPointsCountHourly.ts,
|
170
|
transportDataPointsCountHourly.value,
|
174
|
transportDataPointsCountHourly.value,
|
|
@@ -177,16 +181,16 @@ |
|
@@ -177,16 +181,16 @@ |
177
|
}
|
181
|
}
|
178
|
if (update) {
|
182
|
if (update) {
|
179
|
const { transportDataPointsCountHourly, transportMsgCountHourly } = update[0].timeseries;
|
183
|
const { transportDataPointsCountHourly, transportMsgCountHourly } = update[0].timeseries;
|
180
|
- const newArray: any = [];
|
|
|
181
|
- const newArray1: any = [];
|
184
|
+ const newArray: any[] = [];
|
|
|
185
|
+ const newArray1: any[] = [];
|
182
|
for (const item of transportDataPointsCountHourly) {
|
186
|
for (const item of transportDataPointsCountHourly) {
|
183
|
newArray.push([item.ts, item.value]);
|
187
|
newArray.push([item.ts, item.value]);
|
184
|
}
|
188
|
}
|
185
|
for (const item of transportMsgCountHourly) {
|
189
|
for (const item of transportMsgCountHourly) {
|
186
|
newArray1.push([item.ts, item.value]);
|
190
|
newArray1.push([item.ts, item.value]);
|
187
|
}
|
191
|
}
|
188
|
- state.dataPointList = [state.dataPoint, ...newArray];
|
|
|
189
|
- state.messageList = [state.MsgCount, ...newArray1];
|
192
|
+ state.dataPointList = [[...state.dataPoint], ...newArray];
|
|
|
193
|
+ state.messageList = [[...state.MsgCount], ...newArray1];
|
190
|
}
|
194
|
}
|
191
|
}
|
195
|
}
|
192
|
},
|
196
|
},
|
|
@@ -204,11 +208,11 @@ |
|
@@ -204,11 +208,11 @@ |
204
|
cmdId: activeKey.value,
|
208
|
cmdId: activeKey.value,
|
205
|
historyCmd: {
|
209
|
historyCmd: {
|
206
|
keys: ['createdAlarmsCountHourly'],
|
210
|
keys: ['createdAlarmsCountHourly'],
|
207
|
- startTs: 1638778336692,
|
|
|
208
|
- endTs: 1641370336692,
|
|
|
209
|
- interval: 43200000,
|
|
|
210
|
- limit: 60,
|
|
|
211
|
- agg: 'SUM',
|
211
|
+ startTs: Date.now() - 86400000,
|
|
|
212
|
+ endTs: Date.now(),
|
|
|
213
|
+ interval: 7200000,
|
|
|
214
|
+ limit: 12,
|
|
|
215
|
+ agg: 'COUNT',
|
212
|
},
|
216
|
},
|
213
|
},
|
217
|
},
|
214
|
],
|
218
|
],
|
|
@@ -221,10 +225,7 @@ |
|
@@ -221,10 +225,7 @@ |
221
|
query: {
|
225
|
query: {
|
222
|
entityFilter: {
|
226
|
entityFilter: {
|
223
|
type: 'singleEntity',
|
227
|
type: 'singleEntity',
|
224
|
- singleEntity: {
|
|
|
225
|
- id: '33782740-5d97-11ec-8ac9-f38ed935ea2a',
|
|
|
226
|
- entityType: 'API_USAGE_STATE',
|
|
|
227
|
- },
|
228
|
+ singleEntity: entityId,
|
228
|
},
|
229
|
},
|
229
|
pageLink: {
|
230
|
pageLink: {
|
230
|
pageSize: 1024,
|
231
|
pageSize: 1024,
|
|
@@ -272,11 +273,11 @@ |
|
@@ -272,11 +273,11 @@ |
272
|
cmdId: activeKey.value,
|
273
|
cmdId: activeKey.value,
|
273
|
historyCmd: {
|
274
|
historyCmd: {
|
274
|
keys: ['transportMsgCountHourly', 'transportDataPointsCountHourly'],
|
275
|
keys: ['transportMsgCountHourly', 'transportDataPointsCountHourly'],
|
275
|
- startTs: 1641283221226,
|
|
|
276
|
- endTs: 1641369621226,
|
276
|
+ startTs: Date.now() - 86400000,
|
|
|
277
|
+ endTs: Date.now(),
|
277
|
interval: 7200000,
|
278
|
interval: 7200000,
|
278
|
limit: 12,
|
279
|
limit: 12,
|
279
|
- agg: 'AVG',
|
280
|
+ agg: 'COUNT',
|
280
|
},
|
281
|
},
|
281
|
},
|
282
|
},
|
282
|
],
|
283
|
],
|
|
@@ -285,11 +286,62 @@ |
|
@@ -285,11 +286,62 @@ |
285
|
send(sendMessageValue2);
|
286
|
send(sendMessageValue2);
|
286
|
}
|
287
|
}
|
287
|
}
|
288
|
}
|
288
|
- function onDateChange(date, dateString) {
|
|
|
289
|
- console.log(date, dateString);
|
289
|
+ // 选择日期
|
|
|
290
|
+ function onDateChange(_, dateString) {
|
|
|
291
|
+ activeIndex.value = -1;
|
|
|
292
|
+ const dateTime = Number(formatToDateTime(dateString, 'x'));
|
|
|
293
|
+ // 动态发送ws数据
|
|
|
294
|
+ const sendValue = JSON.stringify({
|
|
|
295
|
+ entityDataCmds: [
|
|
|
296
|
+ {
|
|
|
297
|
+ cmdId: activeKey.value,
|
|
|
298
|
+ historyCmd: {
|
|
|
299
|
+ keys:
|
|
|
300
|
+ activeKey.value === '1'
|
|
|
301
|
+ ? ['createdAlarmsCountHourly']
|
|
|
302
|
+ : ['transportMsgCountHourly', 'transportDataPointsCountHourly'],
|
|
|
303
|
+ startTs: dateTime,
|
|
|
304
|
+ endTs: dateTime + 86400000,
|
|
|
305
|
+ interval: 7200000,
|
|
|
306
|
+ limit: 12,
|
|
|
307
|
+ agg: 'COUNT',
|
|
|
308
|
+ },
|
|
|
309
|
+ },
|
|
|
310
|
+ ],
|
|
|
311
|
+ });
|
|
|
312
|
+ send(sendValue);
|
290
|
}
|
313
|
}
|
291
|
- function changeDate(index: number) {
|
314
|
+ // 快速选择时间
|
|
|
315
|
+ function quickQueryDate(index: number, value: number) {
|
292
|
activeIndex.value = index;
|
316
|
activeIndex.value = index;
|
|
|
317
|
+ let limit = 12;
|
|
|
318
|
+ if (value === 604800000) {
|
|
|
319
|
+ limit = 7;
|
|
|
320
|
+ } else if (value === 2592000000) {
|
|
|
321
|
+ limit = 30;
|
|
|
322
|
+ }
|
|
|
323
|
+ // 动态发送ws数据
|
|
|
324
|
+ const sendValue = JSON.stringify({
|
|
|
325
|
+ entityDataCmds: [
|
|
|
326
|
+ {
|
|
|
327
|
+ cmdId: activeKey.value,
|
|
|
328
|
+ historyCmd: {
|
|
|
329
|
+ keys:
|
|
|
330
|
+ activeKey.value === '1'
|
|
|
331
|
+ ? ['createdAlarmsCountHourly']
|
|
|
332
|
+ : ['transportMsgCountHourly', 'transportDataPointsCountHourly'],
|
|
|
333
|
+ startTs: Date.now() - value,
|
|
|
334
|
+ endTs: Date.now(),
|
|
|
335
|
+ interval: value > 3600000 ? 7200000 : 300000,
|
|
|
336
|
+ limit,
|
|
|
337
|
+ agg: 'COUNT',
|
|
|
338
|
+ },
|
|
|
339
|
+ },
|
|
|
340
|
+ ],
|
|
|
341
|
+ });
|
|
|
342
|
+ send(sendValue);
|
|
|
343
|
+
|
|
|
344
|
+ console.log(value);
|
293
|
}
|
345
|
}
|
294
|
</script>
|
346
|
</script>
|
295
|
|
347
|
|