Showing
15 changed files
with
411 additions
and
156 deletions
@@ -6,12 +6,18 @@ VITE_PUBLIC_PATH = / | @@ -6,12 +6,18 @@ VITE_PUBLIC_PATH = / | ||
6 | 6 | ||
7 | # Cross-domain proxy, you can configure multiple | 7 | # Cross-domain proxy, you can configure multiple |
8 | # Please note that no line breaks | 8 | # Please note that no line breaks |
9 | -# VITE_PROXY = [["/api","http://192.168.10.118:8080/api"],["/upload","http://192.168.10.116:3300/upload"]] | 9 | + |
10 | +# 本地 | ||
11 | +# VITE_PROXY = [["/api","http://192.168.10.123:8080/api"],["/upload","http://192.168.10.124:3300/upload"]] | ||
12 | + | ||
13 | +# 线上 | ||
10 | VITE_PROXY = [["/api","http://101.133.234.90:8080/api"],["/upload","http://192.168.10.116:3300/upload"]] | 14 | VITE_PROXY = [["/api","http://101.133.234.90:8080/api"],["/upload","http://192.168.10.116:3300/upload"]] |
11 | -# VITE_PROXY=[["/api","https://vvbin.cn/test"]] | 15 | + |
16 | +# 实时数据的ws地址 | ||
17 | +VITE_WEB_SOCKET = ws://101.133.234.90:8080/api/ws/plugins/telemetry?token= | ||
12 | 18 | ||
13 | # Delete console | 19 | # Delete console |
14 | -VITE_DROP_CONSOLE = false | 20 | +VITE_DROP_CONSOLE = true |
15 | 21 | ||
16 | # Basic interface address SPA | 22 | # Basic interface address SPA |
17 | VITE_GLOB_API_URL=/api | 23 | VITE_GLOB_API_URL=/api |
@@ -17,7 +17,7 @@ enum Api { | @@ -17,7 +17,7 @@ enum Api { | ||
17 | export const getMenuList = () => { | 17 | export const getMenuList = () => { |
18 | const userStore = useUserStore(); | 18 | const userStore = useUserStore(); |
19 | let url = Api.GetMenuList; | 19 | let url = Api.GetMenuList; |
20 | - if (userStore.getRoleList.find((v) => v == RoleEnum.ROLE_SYS_ADMIN)) { | 20 | + if (userStore.getRoleList.find((v) => v == RoleEnum.SYS_ADMIN)) { |
21 | url = Api.SysAdminMenuList; | 21 | url = Api.SysAdminMenuList; |
22 | } | 22 | } |
23 | return defHttp.get<getMenuListResultModel>({ url }); | 23 | return defHttp.get<getMenuListResultModel>({ url }); |
1 | export enum RoleEnum { | 1 | export enum RoleEnum { |
2 | - ROLE_SYS_ADMIN = 'SYS_ADMIN', | ||
3 | - ROLE_TENANT_ADMIN = 'TENANT_ADMIN', | ||
4 | - ROLE_PLATFORM_ADMIN = 'PLATFORM_ADMIN', | ||
5 | - ROLE_NORMAL_USER = 'CUSTOMER_USER', | 2 | + SYS_ADMIN = 'SYS_ADMIN', |
3 | + PLATFORM_ADMIN = 'PLATFORM_ADMIN', | ||
4 | + TENANT_ADMIN = 'TENANT_ADMIN', | ||
5 | + CUSTOMER_USER = 'CUSTOMER_USER', | ||
6 | +} | ||
7 | + | ||
8 | +export function isAdmin(role: string) { | ||
9 | + if (role === RoleEnum.SYS_ADMIN || role === RoleEnum.PLATFORM_ADMIN) { | ||
10 | + return true; | ||
11 | + } else if (role === RoleEnum.TENANT_ADMIN || role === RoleEnum.CUSTOMER_USER) { | ||
12 | + return false; | ||
13 | + } | ||
6 | } | 14 | } |
@@ -38,9 +38,7 @@ | @@ -38,9 +38,7 @@ | ||
38 | <div class="mr-4" | 38 | <div class="mr-4" |
39 | ><img | 39 | ><img |
40 | :src=" | 40 | :src=" |
41 | - role === 'TENANT_ADMIN' | ||
42 | - ? '/src/assets/images/alarm-count.png' | ||
43 | - : '/src/assets/images/zh.png' | 41 | + !isAdmin(role) ? '/src/assets/images/alarm-count.png' : '/src/assets/images/zh.png' |
44 | " | 42 | " |
45 | style="width: 5rem; height: 5rem" | 43 | style="width: 5rem; height: 5rem" |
46 | /></div> | 44 | /></div> |
@@ -51,7 +49,7 @@ | @@ -51,7 +49,7 @@ | ||
51 | }}</div> | 49 | }}</div> |
52 | <img src="/src/assets/images/tip.png" style="width: 1.4rem; height: 1.4rem" /> | 50 | <img src="/src/assets/images/tip.png" style="width: 1.4rem; height: 1.4rem" /> |
53 | </div> | 51 | </div> |
54 | - <div> {{ role === 'TENANT_ADMIN' ? '11月告警数(条)' : '租户总量(个)' }}</div> | 52 | + <div> {{ !isAdmin(role) ? '11月告警数(条)' : '租户总量(个)' }}</div> |
55 | </div> | 53 | </div> |
56 | </div> | 54 | </div> |
57 | <div class="ml-2 pt-4" style="border-top: 2px solid #f0f2f5"> | 55 | <div class="ml-2 pt-4" style="border-top: 2px solid #f0f2f5"> |
@@ -62,11 +60,7 @@ | @@ -62,11 +60,7 @@ | ||
62 | <div class="flex" style="height: 100px"> | 60 | <div class="flex" style="height: 100px"> |
63 | <div class="mr-4" | 61 | <div class="mr-4" |
64 | ><img | 62 | ><img |
65 | - :src=" | ||
66 | - role === 'TENANT_ADMIN' | ||
67 | - ? '/src/assets/images/msg-count.png' | ||
68 | - : '/src/assets/images/kf.png' | ||
69 | - " | 63 | + :src="!isAdmin(role) ? '/src/assets/images/msg-count.png' : '/src/assets/images/kf.png'" |
70 | style="width: 5rem; height: 5rem" | 64 | style="width: 5rem; height: 5rem" |
71 | /></div> | 65 | /></div> |
72 | <div class="flex-auto"> | 66 | <div class="flex-auto"> |
@@ -76,7 +70,7 @@ | @@ -76,7 +70,7 @@ | ||
76 | }}</div> | 70 | }}</div> |
77 | <img src="/src/assets/images/tip.png" style="width: 1.4rem; height: 1.4rem" /> | 71 | <img src="/src/assets/images/tip.png" style="width: 1.4rem; height: 1.4rem" /> |
78 | </div> | 72 | </div> |
79 | - <div> {{ role === 'TENANT_ADMIN' ? '11月消息量(条)' : '客户总量(个)' }} </div> | 73 | + <div> {{ !isAdmin(role) ? '11月消息量(条)' : '客户总量(个)' }} </div> |
80 | </div> | 74 | </div> |
81 | </div> | 75 | </div> |
82 | <div class="ml-2 pt-4" style="border-top: 2px solid #f0f2f5"> | 76 | <div class="ml-2 pt-4" style="border-top: 2px solid #f0f2f5"> |
@@ -86,9 +80,16 @@ | @@ -86,9 +80,16 @@ | ||
86 | </div> | 80 | </div> |
87 | </template> | 81 | </template> |
88 | <script lang="ts" setup> | 82 | <script lang="ts" setup> |
89 | - import { defineProps, ref, onMounted } from 'vue'; | 83 | + import { defineProps, defineExpose, ref, onMounted } from 'vue'; |
90 | import { Card } from 'ant-design-vue'; | 84 | import { Card } from 'ant-design-vue'; |
91 | import { getHomeData } from '/@/api/dashboard'; | 85 | import { getHomeData } from '/@/api/dashboard'; |
86 | + import { isAdmin } from '/@/enums/roleEnum'; | ||
87 | + defineProps<{ | ||
88 | + role: string; | ||
89 | + }>(); | ||
90 | + defineExpose({ | ||
91 | + isAdmin, | ||
92 | + }); | ||
92 | interface CardList { | 93 | interface CardList { |
93 | deviceInfo: { | 94 | deviceInfo: { |
94 | sumCount: number; | 95 | sumCount: number; |
@@ -104,9 +105,5 @@ | @@ -104,9 +105,5 @@ | ||
104 | onMounted(async () => { | 105 | onMounted(async () => { |
105 | const res = await getHomeData(); | 106 | const res = await getHomeData(); |
106 | growCardList.value = res; | 107 | growCardList.value = res; |
107 | - console.log(growCardList.value); | ||
108 | }); | 108 | }); |
109 | - defineProps<{ | ||
110 | - role: string; | ||
111 | - }>(); | ||
112 | </script> | 109 | </script> |
1 | <template> | 1 | <template> |
2 | <div> | 2 | <div> |
3 | - <Card title="帮助文档" v-if="role === 'TENANT_ADMIN'"> | 3 | + <Card title="帮助文档" v-if="!isAdmin(role)"> |
4 | <div> | 4 | <div> |
5 | <template v-for="item in helpDoc" :key="item.title"> | 5 | <template v-for="item in helpDoc" :key="item.title"> |
6 | <AnchorLink v-bind="item" /> | 6 | <AnchorLink v-bind="item" /> |
7 | </template> | 7 | </template> |
8 | </div> | 8 | </div> |
9 | <Card | 9 | <Card |
10 | - v-if="role === 'TENANT_ADMIN'" | 10 | + v-if="!isAdmin(role)" |
11 | :tab-list="tabListTitle" | 11 | :tab-list="tabListTitle" |
12 | v-bind="$attrs" | 12 | v-bind="$attrs" |
13 | :active-tab-key="activeKey" | 13 | :active-tab-key="activeKey" |
@@ -58,7 +58,7 @@ | @@ -58,7 +58,7 @@ | ||
58 | </Card> | 58 | </Card> |
59 | </Card> | 59 | </Card> |
60 | 60 | ||
61 | - <Card v-if="role !== 'TENANT_ADMIN'"> | 61 | + <Card v-if="isAdmin(role)"> |
62 | <Descriptions title="租户消息量TOP10" :column="1"> | 62 | <Descriptions title="租户消息量TOP10" :column="1"> |
63 | <template v-for="(item, index) in 10" :key="index"> | 63 | <template v-for="(item, index) in 10" :key="index"> |
64 | <DescriptionsItem> | 64 | <DescriptionsItem> |
@@ -100,7 +100,7 @@ | @@ -100,7 +100,7 @@ | ||
100 | </template> | 100 | </template> |
101 | </Descriptions> | 101 | </Descriptions> |
102 | </Card> | 102 | </Card> |
103 | - <BasicTable @register="registerTable" v-if="role !== 'TENANT_ADMIN'" /> | 103 | + <BasicTable @register="registerTable" v-if="isAdmin(role)" /> |
104 | </div> | 104 | </div> |
105 | </template> | 105 | </template> |
106 | 106 | ||
@@ -124,6 +124,7 @@ | @@ -124,6 +124,7 @@ | ||
124 | import { useGo } from '/@/hooks/web/usePage'; | 124 | import { useGo } from '/@/hooks/web/usePage'; |
125 | import { BasicTable, useTable } from '/@/components/Table'; | 125 | import { BasicTable, useTable } from '/@/components/Table'; |
126 | import { columns } from './props'; | 126 | import { columns } from './props'; |
127 | + import { isAdmin } from '/@/enums/roleEnum'; | ||
127 | export default defineComponent({ | 128 | export default defineComponent({ |
128 | components: { | 129 | components: { |
129 | Card, | 130 | Card, |
@@ -139,7 +140,10 @@ | @@ -139,7 +140,10 @@ | ||
139 | DescriptionsItem, | 140 | DescriptionsItem, |
140 | }, | 141 | }, |
141 | props: { | 142 | props: { |
142 | - role: String, | 143 | + role: { |
144 | + type: String, | ||
145 | + required: true, | ||
146 | + }, | ||
143 | }, | 147 | }, |
144 | setup(props) { | 148 | setup(props) { |
145 | // 通知数据 | 149 | // 通知数据 |
@@ -196,7 +200,7 @@ | @@ -196,7 +200,7 @@ | ||
196 | return userStore.enterPriseInfo?.qrCode; | 200 | return userStore.enterPriseInfo?.qrCode; |
197 | }); | 201 | }); |
198 | onMounted(async () => { | 202 | onMounted(async () => { |
199 | - if (props.role !== 'TENANT_ADMIN') return; | 203 | + if (isAdmin(props.role)) return; |
200 | const res = await getEnterPriseDetail(); | 204 | const res = await getEnterPriseDetail(); |
201 | const notice = await notifyMyGetrPageApi({ page: 1, pageSize: 5 }); | 205 | const notice = await notifyMyGetrPageApi({ page: 1, pageSize: 5 }); |
202 | userStore.setEnterPriseInfo(res); | 206 | userStore.setEnterPriseInfo(res); |
@@ -215,6 +219,7 @@ | @@ -215,6 +219,7 @@ | ||
215 | dataSource, | 219 | dataSource, |
216 | go, | 220 | go, |
217 | registerTable, | 221 | registerTable, |
222 | + isAdmin, | ||
218 | }; | 223 | }; |
219 | }, | 224 | }, |
220 | }); | 225 | }); |
@@ -5,7 +5,7 @@ | @@ -5,7 +5,7 @@ | ||
5 | :active-tab-key="activeKey" | 5 | :active-tab-key="activeKey" |
6 | @tabChange="onTabChange" | 6 | @tabChange="onTabChange" |
7 | > | 7 | > |
8 | - <template #tabBarExtraContent v-if="role === 'TENANT_ADMIN'"> | 8 | + <template #tabBarExtraContent v-if="!isAdmin(role)"> |
9 | <div class="extra-date"> | 9 | <div class="extra-date"> |
10 | <template v-for="(item, index) in dateList" :key="item"> | 10 | <template v-for="(item, index) in dateList" :key="item"> |
11 | <span @click="changeDate(index)" :class="{ active: index === activeIndex }">{{ | 11 | <span @click="changeDate(index)" :class="{ active: index === activeIndex }">{{ |
@@ -15,53 +15,275 @@ | @@ -15,53 +15,275 @@ | ||
15 | <DatePicker @change="onDateChange" /> | 15 | <DatePicker @change="onDateChange" /> |
16 | </div> | 16 | </div> |
17 | </template> | 17 | </template> |
18 | - <div v-if="activeKey === 'tab1'"> | ||
19 | - <p class="center">{{ role === 'TENANT_ADMIN' ? '告警数' : '租户趋势' }}</p> | ||
20 | - <VisitAnalysis v-if="role === 'TENANT_ADMIN'" /> | 18 | + <div v-if="activeKey === '1'"> |
19 | + <p class="center">{{ !isAdmin(role) ? '告警数' : '租户趋势' }}</p> | ||
20 | + <VisitAnalysis v-if="!isAdmin(role)" :alarmList="state.alarmList" /> | ||
21 | <VisitAnalysisBar v-else /> | 21 | <VisitAnalysisBar v-else /> |
22 | </div> | 22 | </div> |
23 | - <div v-else> | ||
24 | - <p class="center">消息数</p> | ||
25 | - <VisitAnalysisBar /> | 23 | + <div v-if="activeKey === '2'"> |
24 | + <p class="center">消息量</p> | ||
25 | + <VisitAnalysisBar :dataPointList="state.dataPointList" :messageList="state.messageList" /> | ||
26 | </div> | 26 | </div> |
27 | </Card> | 27 | </Card> |
28 | + <Card v-bind="$attrs" :tab-list="tab1ListTitle" v-if="isAdmin(role)"> | ||
29 | + <p class="center">客户趋势</p> | ||
30 | + <VisitAnalysis | ||
31 | + /></Card> | ||
28 | </template> | 32 | </template> |
29 | <script lang="ts" setup> | 33 | <script lang="ts" setup> |
30 | - import { ref } from 'vue'; | 34 | + import { ref, defineExpose, reactive } from 'vue'; |
31 | import { Card, DatePicker } from 'ant-design-vue'; | 35 | import { Card, DatePicker } from 'ant-design-vue'; |
32 | import VisitAnalysis from './VisitAnalysis.vue'; | 36 | import VisitAnalysis from './VisitAnalysis.vue'; |
33 | import VisitAnalysisBar from './VisitAnalysisBar.vue'; | 37 | import VisitAnalysisBar from './VisitAnalysisBar.vue'; |
34 | import { defineProps } from 'vue'; | 38 | import { defineProps } from 'vue'; |
39 | + import { isAdmin } from '/@/enums/roleEnum'; | ||
40 | + import { useWebSocket } from '@vueuse/core'; | ||
41 | + import { getAuthCache } from '/@/utils/auth'; | ||
42 | + import { JWT_TOKEN_KEY } from '/@/enums/cacheEnum'; | ||
35 | 43 | ||
44 | + defineExpose({ | ||
45 | + isAdmin, | ||
46 | + }); | ||
36 | const props = defineProps<{ | 47 | const props = defineProps<{ |
37 | role: string; | 48 | role: string; |
38 | }>(); | 49 | }>(); |
39 | - const activeKey = ref('tab1'); | 50 | + const activeKey = ref('1'); |
40 | 51 | ||
41 | // 动态根据登录角色来判断 | 52 | // 动态根据登录角色来判断 |
42 | - const tabListTitle = | ||
43 | - props.role === 'TENANT_ADMIN' | ||
44 | - ? [ | 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 = [ | ||
72 | + { | ||
73 | + key: '1', | ||
74 | + tab: '客户', | ||
75 | + }, | ||
76 | + ]; | ||
77 | + | ||
78 | + const dateList = ref(['1小时', '1天', '7天', '30天']); | ||
79 | + // web Socket | ||
80 | + 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); | ||
129 | + const state = reactive({ | ||
130 | + server: `${import.meta.env.VITE_WEB_SOCKET}${token}`, | ||
131 | + alarmList: new Array<[number, string]>(), | ||
132 | + alarmItem: new Array<[number, string]>(), | ||
133 | + dataPointList: new Array<[number, string]>(), | ||
134 | + messageList: new Array<[number, string]>(), | ||
135 | + dataPoint: new Array<[number, string]>(), | ||
136 | + MsgCount: new Array<[number, string]>(), | ||
137 | + }); | ||
138 | + const { send, close } = useWebSocket(state.server, { | ||
139 | + onConnected() { | ||
140 | + send(sendValue); | ||
141 | + console.log('建立连接了'); | ||
142 | + }, | ||
143 | + onMessage(_, e) { | ||
144 | + const { data, update } = JSON.parse(e.data); | ||
145 | + if (activeKey.value === '1') { | ||
146 | + if (data) { | ||
147 | + const { createdAlarmsCountHourly } = data.data[0].latest.TIME_SERIES; | ||
148 | + state.alarmItem = [createdAlarmsCountHourly.ts, createdAlarmsCountHourly.value]; | ||
149 | + state.alarmList.push([createdAlarmsCountHourly.ts, createdAlarmsCountHourly.value]); | ||
150 | + } | ||
151 | + if (update) { | ||
152 | + const { createdAlarmsCountHourly } = update[0].timeseries; | ||
153 | + const newArray: any = []; | ||
154 | + for (const item of createdAlarmsCountHourly) { | ||
155 | + newArray.push([item.ts, item.value]); | ||
156 | + } | ||
157 | + state.alarmList = [state.alarmItem, ...newArray]; | ||
158 | + } | ||
159 | + } else { | ||
160 | + if (data) { | ||
161 | + const { transportDataPointsCountHourly, transportMsgCountHourly } = | ||
162 | + data.data[0].latest.TIME_SERIES; | ||
163 | + state.dataPoint = [ | ||
164 | + transportDataPointsCountHourly.ts, | ||
165 | + transportDataPointsCountHourly.value, | ||
166 | + ]; | ||
167 | + | ||
168 | + state.MsgCount = [ | ||
169 | + transportDataPointsCountHourly.ts, | ||
170 | + transportDataPointsCountHourly.value, | ||
171 | + ]; | ||
172 | + state.dataPointList.push([ | ||
173 | + transportDataPointsCountHourly.ts, | ||
174 | + transportDataPointsCountHourly.value, | ||
175 | + ]); | ||
176 | + state.messageList.push([transportMsgCountHourly.ts, transportMsgCountHourly.value]); | ||
177 | + } | ||
178 | + if (update) { | ||
179 | + const { transportDataPointsCountHourly, transportMsgCountHourly } = update[0].timeseries; | ||
180 | + const newArray: any = []; | ||
181 | + const newArray1: any = []; | ||
182 | + for (const item of transportDataPointsCountHourly) { | ||
183 | + newArray.push([item.ts, item.value]); | ||
184 | + } | ||
185 | + for (const item of transportMsgCountHourly) { | ||
186 | + newArray1.push([item.ts, item.value]); | ||
187 | + } | ||
188 | + state.dataPointList = [state.dataPoint, ...newArray]; | ||
189 | + state.messageList = [state.MsgCount, ...newArray1]; | ||
190 | + } | ||
191 | + } | ||
192 | + }, | ||
193 | + onDisconnected() { | ||
194 | + console.log('断开连接了'); | ||
195 | + close(); | ||
196 | + }, | ||
197 | + }); | ||
198 | + function onTabChange(key: string) { | ||
199 | + activeKey.value = key; | ||
200 | + if (key === '1') { | ||
201 | + const sendAlarmValue = JSON.stringify({ | ||
202 | + entityDataCmds: [ | ||
45 | { | 203 | { |
46 | - key: 'tab1', | ||
47 | - tab: '告警数统计', | 204 | + cmdId: activeKey.value, |
205 | + historyCmd: { | ||
206 | + keys: ['createdAlarmsCountHourly'], | ||
207 | + startTs: 1638778336692, | ||
208 | + endTs: 1641370336692, | ||
209 | + interval: 43200000, | ||
210 | + limit: 60, | ||
211 | + agg: 'SUM', | ||
212 | + }, | ||
48 | }, | 213 | }, |
214 | + ], | ||
215 | + }); | ||
216 | + send(sendAlarmValue); | ||
217 | + } else { | ||
218 | + const sendMessageValue = JSON.stringify({ | ||
219 | + entityDataCmds: [ | ||
49 | { | 220 | { |
50 | - key: 'tab2', | ||
51 | - tab: '消息量统计', | 221 | + query: { |
222 | + entityFilter: { | ||
223 | + type: 'singleEntity', | ||
224 | + singleEntity: { | ||
225 | + id: '33782740-5d97-11ec-8ac9-f38ed935ea2a', | ||
226 | + entityType: 'API_USAGE_STATE', | ||
227 | + }, | ||
228 | + }, | ||
229 | + pageLink: { | ||
230 | + pageSize: 1024, | ||
231 | + page: 0, | ||
232 | + sortOrder: { | ||
233 | + key: { | ||
234 | + type: 'ENTITY_FIELD', | ||
235 | + key: 'createdTime', | ||
236 | + }, | ||
237 | + direction: 'DESC', | ||
238 | + }, | ||
239 | + }, | ||
240 | + entityFields: [ | ||
241 | + { | ||
242 | + type: 'ENTITY_FIELD', | ||
243 | + key: 'name', | ||
244 | + }, | ||
245 | + { | ||
246 | + type: 'ENTITY_FIELD', | ||
247 | + key: 'label', | ||
248 | + }, | ||
249 | + { | ||
250 | + type: 'ENTITY_FIELD', | ||
251 | + key: 'additionalInfo', | ||
252 | + }, | ||
253 | + ], | ||
254 | + latestValues: [ | ||
255 | + { | ||
256 | + type: 'TIME_SERIES', | ||
257 | + key: 'transportMsgCountHourly', | ||
258 | + }, | ||
259 | + { | ||
260 | + type: 'TIME_SERIES', | ||
261 | + key: 'transportDataPointsCountHourly', | ||
262 | + }, | ||
263 | + ], | ||
264 | + }, | ||
265 | + cmdId: activeKey.value, | ||
52 | }, | 266 | }, |
53 | - ] | ||
54 | - : [ | 267 | + ], |
268 | + }); | ||
269 | + const sendMessageValue2 = JSON.stringify({ | ||
270 | + entityDataCmds: [ | ||
55 | { | 271 | { |
56 | - key: 'tab1', | ||
57 | - tab: '租户', | 272 | + cmdId: activeKey.value, |
273 | + historyCmd: { | ||
274 | + keys: ['transportMsgCountHourly', 'transportDataPointsCountHourly'], | ||
275 | + startTs: 1641283221226, | ||
276 | + endTs: 1641369621226, | ||
277 | + interval: 7200000, | ||
278 | + limit: 12, | ||
279 | + agg: 'AVG', | ||
280 | + }, | ||
58 | }, | 281 | }, |
59 | - ]; | ||
60 | - | ||
61 | - const dateList = ref(['1小时', '1天', '7天', '30天']); | ||
62 | - const activeIndex = ref(0); | ||
63 | - function onTabChange(key) { | ||
64 | - activeKey.value = key; | 282 | + ], |
283 | + }); | ||
284 | + send(sendMessageValue); | ||
285 | + send(sendMessageValue2); | ||
286 | + } | ||
65 | } | 287 | } |
66 | function onDateChange(date, dateString) { | 288 | function onDateChange(date, dateString) { |
67 | console.log(date, dateString); | 289 | console.log(date, dateString); |
@@ -2,17 +2,25 @@ | @@ -2,17 +2,25 @@ | ||
2 | <div ref="chartRef" :style="{ height, width }"></div> | 2 | <div ref="chartRef" :style="{ height, width }"></div> |
3 | </template> | 3 | </template> |
4 | <script lang="ts" setup> | 4 | <script lang="ts" setup> |
5 | - import { onMounted, ref, Ref } from 'vue'; | 5 | + import { onMounted, ref, Ref, withDefaults, defineProps, watch } from 'vue'; |
6 | import { useECharts } from '/@/hooks/web/useECharts'; | 6 | import { useECharts } from '/@/hooks/web/useECharts'; |
7 | - import { basicProps } from './props'; | ||
8 | 7 | ||
9 | - defineProps({ | ||
10 | - ...basicProps, | 8 | + interface Props { |
9 | + width?: string; | ||
10 | + height?: string; | ||
11 | + alarmList: [number, string][]; | ||
12 | + } | ||
13 | + const props = withDefaults(defineProps<Props>(), { | ||
14 | + width: '100%', | ||
15 | + height: '280px', | ||
16 | + alarmList: () => [], | ||
11 | }); | 17 | }); |
18 | + | ||
12 | const chartRef = ref<HTMLDivElement | null>(null); | 19 | const chartRef = ref<HTMLDivElement | null>(null); |
13 | const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>); | 20 | const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>); |
14 | 21 | ||
15 | onMounted(() => { | 22 | onMounted(() => { |
23 | + console.log(props.alarmList); | ||
16 | setOptions({ | 24 | setOptions({ |
17 | tooltip: { | 25 | tooltip: { |
18 | trigger: 'axis', | 26 | trigger: 'axis', |
@@ -24,28 +32,8 @@ | @@ -24,28 +32,8 @@ | ||
24 | }, | 32 | }, |
25 | }, | 33 | }, |
26 | xAxis: { | 34 | xAxis: { |
27 | - type: 'category', | 35 | + type: 'time', |
28 | boundaryGap: false, | 36 | boundaryGap: false, |
29 | - data: [ | ||
30 | - '6:00', | ||
31 | - '7:00', | ||
32 | - '8:00', | ||
33 | - '9:00', | ||
34 | - '10:00', | ||
35 | - '11:00', | ||
36 | - '12:00', | ||
37 | - '13:00', | ||
38 | - '14:00', | ||
39 | - '15:00', | ||
40 | - '16:00', | ||
41 | - '17:00', | ||
42 | - '18:00', | ||
43 | - '19:00', | ||
44 | - '20:00', | ||
45 | - '21:00', | ||
46 | - '22:00', | ||
47 | - '23:00', | ||
48 | - ], | ||
49 | splitLine: { | 37 | splitLine: { |
50 | show: true, | 38 | show: true, |
51 | lineStyle: { | 39 | lineStyle: { |
@@ -58,30 +46,12 @@ | @@ -58,30 +46,12 @@ | ||
58 | show: false, | 46 | show: false, |
59 | }, | 47 | }, |
60 | }, | 48 | }, |
61 | - yAxis: [ | ||
62 | - { | ||
63 | - type: 'value', | ||
64 | - max: 80000, | ||
65 | - splitNumber: 4, | ||
66 | - axisTick: { | ||
67 | - show: false, | ||
68 | - }, | ||
69 | - splitArea: { | ||
70 | - show: true, | ||
71 | - areaStyle: { | ||
72 | - color: ['rgba(255,255,255,0.2)', 'rgba(226,226,226,0.2)'], | ||
73 | - }, | ||
74 | - }, | ||
75 | - }, | ||
76 | - ], | 49 | + yAxis: {}, |
77 | grid: { left: '1%', right: '1%', top: '2 %', bottom: 0, containLabel: true }, | 50 | grid: { left: '1%', right: '1%', top: '2 %', bottom: 0, containLabel: true }, |
78 | series: [ | 51 | series: [ |
79 | { | 52 | { |
80 | smooth: true, | 53 | smooth: true, |
81 | - data: [ | ||
82 | - 111, 222, 4000, 18000, 33333, 55555, 66666, 33333, 14000, 36000, 66666, 44444, 22222, | ||
83 | - 11111, 4000, 2000, 500, 333, 222, 111, | ||
84 | - ], | 54 | + data: props.alarmList, |
85 | type: 'line', | 55 | type: 'line', |
86 | areaStyle: {}, | 56 | areaStyle: {}, |
87 | itemStyle: { | 57 | itemStyle: { |
@@ -91,4 +61,49 @@ | @@ -91,4 +61,49 @@ | ||
91 | ], | 61 | ], |
92 | }); | 62 | }); |
93 | }); | 63 | }); |
64 | + watch( | ||
65 | + () => props.alarmList, | ||
66 | + (newValue) => { | ||
67 | + console.log(newValue); | ||
68 | + setOptions({ | ||
69 | + tooltip: { | ||
70 | + trigger: 'axis', | ||
71 | + axisPointer: { | ||
72 | + lineStyle: { | ||
73 | + width: 1, | ||
74 | + color: '#019680', | ||
75 | + }, | ||
76 | + }, | ||
77 | + }, | ||
78 | + xAxis: { | ||
79 | + type: 'time', | ||
80 | + boundaryGap: false, | ||
81 | + splitLine: { | ||
82 | + show: true, | ||
83 | + lineStyle: { | ||
84 | + width: 1, | ||
85 | + type: 'solid', | ||
86 | + color: 'rgba(226,226,226,0.5)', | ||
87 | + }, | ||
88 | + }, | ||
89 | + axisTick: { | ||
90 | + show: false, | ||
91 | + }, | ||
92 | + }, | ||
93 | + yAxis: {}, | ||
94 | + grid: { left: '1%', right: '1%', top: '2 %', bottom: 0, containLabel: true }, | ||
95 | + series: [ | ||
96 | + { | ||
97 | + smooth: true, | ||
98 | + data: newValue, | ||
99 | + type: 'line', | ||
100 | + areaStyle: {}, | ||
101 | + itemStyle: { | ||
102 | + color: '#5ab1ef', | ||
103 | + }, | ||
104 | + }, | ||
105 | + ], | ||
106 | + }); | ||
107 | + } | ||
108 | + ); | ||
94 | </script> | 109 | </script> |
@@ -2,57 +2,54 @@ | @@ -2,57 +2,54 @@ | ||
2 | <div ref="chartRef" :style="{ height, width }"></div> | 2 | <div ref="chartRef" :style="{ height, width }"></div> |
3 | </template> | 3 | </template> |
4 | <script lang="ts" setup> | 4 | <script lang="ts" setup> |
5 | - import { onMounted, ref, Ref } from 'vue'; | 5 | + import { ref, Ref, watch, withDefaults, defineProps } from 'vue'; |
6 | import { useECharts } from '/@/hooks/web/useECharts'; | 6 | import { useECharts } from '/@/hooks/web/useECharts'; |
7 | - import { basicProps } from './props'; | ||
8 | - | ||
9 | - defineProps({ | ||
10 | - ...basicProps, | 7 | + type DataItem = [number, string]; |
8 | + interface Props { | ||
9 | + width?: string; | ||
10 | + height?: string; | ||
11 | + dataPointList: DataItem[]; | ||
12 | + messageList: DataItem[]; | ||
13 | + } | ||
14 | + const props = withDefaults(defineProps<Props>(), { | ||
15 | + width: '100%', | ||
16 | + height: '280px', | ||
17 | + dataPointList: () => [], | ||
18 | + messageList: () => [], | ||
11 | }); | 19 | }); |
12 | - | ||
13 | const chartRef = ref<HTMLDivElement | null>(null); | 20 | const chartRef = ref<HTMLDivElement | null>(null); |
14 | const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>); | 21 | const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>); |
15 | - onMounted(() => { | ||
16 | - setOptions({ | ||
17 | - tooltip: { | ||
18 | - trigger: 'axis', | ||
19 | - axisPointer: { | ||
20 | - lineStyle: { | ||
21 | - width: 1, | ||
22 | - color: '#019680', | ||
23 | - }, | 22 | + watch( |
23 | + () => [props.dataPointList, props.messageList], | ||
24 | + ([newValue, newValue1]) => { | ||
25 | + setOptions({ | ||
26 | + tooltip: {}, | ||
27 | + xAxis: { | ||
28 | + type: 'time', | ||
24 | }, | 29 | }, |
25 | - }, | ||
26 | - grid: { left: '1%', right: '1%', top: '2 %', bottom: 0, containLabel: true }, | ||
27 | - xAxis: { | ||
28 | - type: 'category', | ||
29 | - data: [ | ||
30 | - '1月', | ||
31 | - '2月', | ||
32 | - '3月', | ||
33 | - '4月', | ||
34 | - '5月', | ||
35 | - '6月', | ||
36 | - '7月', | ||
37 | - '8月', | ||
38 | - '9月', | ||
39 | - '10月', | ||
40 | - '11月', | ||
41 | - '12月', | ||
42 | - ], | ||
43 | - }, | ||
44 | - yAxis: { | ||
45 | - type: 'value', | ||
46 | - max: 8000, | ||
47 | - splitNumber: 4, | ||
48 | - }, | ||
49 | - series: [ | ||
50 | - { | ||
51 | - data: [3000, 2000, 3333, 5000, 3200, 4200, 3200, 2100, 3000, 5100, 6000, 3200, 4800], | ||
52 | - type: 'bar', | ||
53 | - barMaxWidth: 80, | 30 | + legend: { |
31 | + data: ['传输数据点', '传输消息量'], | ||
32 | + left: '10%', | ||
54 | }, | 33 | }, |
55 | - ], | ||
56 | - }); | ||
57 | - }); | 34 | + yAxis: {}, |
35 | + grid: { | ||
36 | + bottom: 100, | ||
37 | + }, | ||
38 | + series: [ | ||
39 | + { | ||
40 | + name: '传输数据点', | ||
41 | + type: 'bar', | ||
42 | + stack: 'one', | ||
43 | + data: newValue, | ||
44 | + }, | ||
45 | + { | ||
46 | + name: '传输消息量', | ||
47 | + type: 'bar', | ||
48 | + stack: 'one', | ||
49 | + data: newValue1, | ||
50 | + }, | ||
51 | + ], | ||
52 | + }); | ||
53 | + } | ||
54 | + ); | ||
58 | </script> | 55 | </script> |
@@ -3,9 +3,9 @@ | @@ -3,9 +3,9 @@ | ||
3 | <div class="md:w-7/10 w-full !mr-4 enter-y"> | 3 | <div class="md:w-7/10 w-full !mr-4 enter-y"> |
4 | <GrowCard :loading="loading" class="enter-y" :role="role" /> | 4 | <GrowCard :loading="loading" class="enter-y" :role="role" /> |
5 | <SiteAnalysis class="!my-4 enter-y" :loading="loading" :role="role" /> | 5 | <SiteAnalysis class="!my-4 enter-y" :loading="loading" :role="role" /> |
6 | - <div class="md:flex enter-y" v-if="role === 'TENANT_ADMIN'"> | 6 | + <div class="md:flex enter-y" v-if="!isAdmin(role)"> |
7 | <Card title="核心流程指南" style="width: 100%"> | 7 | <Card title="核心流程指南" style="width: 100%"> |
8 | - <img alt="核心流程指南" src="../../../assets/images/flow.png" /> | 8 | + <img alt="核心流程指南" src="/src/assets/images/flow.png" /> |
9 | </Card> | 9 | </Card> |
10 | </div> | 10 | </div> |
11 | </div> | 11 | </div> |
@@ -15,13 +15,18 @@ | @@ -15,13 +15,18 @@ | ||
15 | </div> | 15 | </div> |
16 | </template> | 16 | </template> |
17 | <script lang="ts" setup> | 17 | <script lang="ts" setup> |
18 | - import { ref } from 'vue'; | 18 | + import { ref, defineExpose } from 'vue'; |
19 | import GrowCard from './components/GrowCard.vue'; | 19 | import GrowCard from './components/GrowCard.vue'; |
20 | import SiteAnalysis from './components/SiteAnalysis.vue'; | 20 | import SiteAnalysis from './components/SiteAnalysis.vue'; |
21 | import { Card } from 'ant-design-vue'; | 21 | import { Card } from 'ant-design-vue'; |
22 | import HelpDoc from './components/HelpDoc.vue'; | 22 | import HelpDoc from './components/HelpDoc.vue'; |
23 | import { USER_INFO_KEY } from '/@/enums/cacheEnum'; | 23 | import { USER_INFO_KEY } from '/@/enums/cacheEnum'; |
24 | import { getAuthCache } from '/@/utils/auth'; | 24 | import { getAuthCache } from '/@/utils/auth'; |
25 | + import { isAdmin } from '/@/enums/roleEnum'; | ||
26 | + defineExpose({ | ||
27 | + isAdmin, | ||
28 | + }); | ||
29 | + | ||
25 | const userInfo: any = getAuthCache(USER_INFO_KEY); | 30 | const userInfo: any = getAuthCache(USER_INFO_KEY); |
26 | const role = userInfo.roles[0]; | 31 | const role = userInfo.roles[0]; |
27 | console.log(role); | 32 | console.log(role); |
@@ -24,7 +24,7 @@ | @@ -24,7 +24,7 @@ | ||
24 | setup(props) { | 24 | setup(props) { |
25 | const token: string = getAuthCache(JWT_TOKEN_KEY); | 25 | const token: string = getAuthCache(JWT_TOKEN_KEY); |
26 | const state = reactive({ | 26 | const state = reactive({ |
27 | - server: `ws://101.133.234.90:8080/api/ws/plugins/telemetry?token=${token}`, | 27 | + server: `${import.meta.env.VITE_WEB_SOCKET}${token}`, |
28 | sendValue: JSON.stringify({ | 28 | sendValue: JSON.stringify({ |
29 | attrSubCmds: [], | 29 | attrSubCmds: [], |
30 | tsSubCmds: [ | 30 | tsSubCmds: [ |
@@ -16,7 +16,7 @@ | @@ -16,7 +16,7 @@ | ||
16 | label: '删除', | 16 | label: '删除', |
17 | icon: 'ant-design:delete-outlined', | 17 | icon: 'ant-design:delete-outlined', |
18 | color: 'error', | 18 | color: 'error', |
19 | - ifShow: record.roleType != RoleEnum.ROLE_SYS_ADMIN, | 19 | + ifShow: record.roleType != RoleEnum.SYS_ADMIN, |
20 | popConfirm: { | 20 | popConfirm: { |
21 | title: '是否确认删除', | 21 | title: '是否确认删除', |
22 | confirm: handleDelete.bind(null, record), | 22 | confirm: handleDelete.bind(null, record), |
@@ -171,7 +171,7 @@ | @@ -171,7 +171,7 @@ | ||
171 | showIndexColumn: false, | 171 | showIndexColumn: false, |
172 | searchInfo: { | 172 | searchInfo: { |
173 | tenantId, | 173 | tenantId, |
174 | - roleType: RoleEnum.ROLE_TENANT_ADMIN, | 174 | + roleType: RoleEnum.TENANT_ADMIN, |
175 | }, | 175 | }, |
176 | actionColumn: { | 176 | actionColumn: { |
177 | width: 100, | 177 | width: 100, |
@@ -75,7 +75,7 @@ export const tenantFormSchema: FormSchema[] = [ | @@ -75,7 +75,7 @@ export const tenantFormSchema: FormSchema[] = [ | ||
75 | mode: 'multiple', | 75 | mode: 'multiple', |
76 | api: getAllRoleList, | 76 | api: getAllRoleList, |
77 | params: { | 77 | params: { |
78 | - roleType: RoleEnum.ROLE_TENANT_ADMIN, | 78 | + roleType: RoleEnum.TENANT_ADMIN, |
79 | }, | 79 | }, |
80 | labelField: 'name', | 80 | labelField: 'name', |
81 | valueField: 'id', | 81 | valueField: 'id', |
@@ -156,7 +156,7 @@ | @@ -156,7 +156,7 @@ | ||
156 | name: values.name, | 156 | name: values.name, |
157 | remark: values.remark, | 157 | remark: values.remark, |
158 | status: values.status, | 158 | status: values.status, |
159 | - roleType: RoleEnum.ROLE_TENANT_ADMIN, | 159 | + roleType: RoleEnum.TENANT_ADMIN, |
160 | menu: allCheckedKeys.value as string[], | 160 | menu: allCheckedKeys.value as string[], |
161 | }; | 161 | }; |
162 | console.log(req, '请求参数'); | 162 | console.log(req, '请求参数'); |
@@ -73,7 +73,7 @@ export const searchFormSchema: FormSchema[] = [ | @@ -73,7 +73,7 @@ export const searchFormSchema: FormSchema[] = [ | ||
73 | label: '', | 73 | label: '', |
74 | component: 'Input', | 74 | component: 'Input', |
75 | colProps: { span: 8 }, | 75 | colProps: { span: 8 }, |
76 | - defaultValue: RoleEnum.ROLE_TENANT_ADMIN, | 76 | + defaultValue: RoleEnum.TENANT_ADMIN, |
77 | ifShow: false, | 77 | ifShow: false, |
78 | }, | 78 | }, |
79 | { | 79 | { |